{"$:/DefaultTiddlers":"wellbeingservice_public","$:/GoogleAnalyticsAccount":"afc-base-theme","$:/GoogleAnalyticsMeasurementID":"afc-base-theme","$:/SiteSubtitle":"wellbeingservice_public","$:/SiteTitle":"wellbeingservice_public","$:/_AFC/AboveStory/Logo":"afc-base-theme","$:/_AFC/EditDraftInfoSegment":"afc-base-theme","$:/_AFC/Fonts/UseFonts":"afc-base-theme","$:/_AFC/Macros/Image":"afc-base-theme","$:/_AFC/Macros/YouTube":"afc-base-theme","$:/_AFC/Palette":"wellbeingservice_public","$:/_AFC/Startup/ConfigurePreview":"afc-base-theme","$:/_AFC/Styles/Bubbles":"afc-base-theme","$:/_AFC/Styles/DocLinks":"afc-base-theme","$:/_AFC/Styles/FadedSidebar":"afc-base-theme","$:/_AFC/Styles/HideEditButton":"afc-base-theme","$:/_AFC/Styles/Overrides":"afc-base-theme","$:/_AFC/Styles/TopMenu":"afc-base-theme","$:/_AFC/SurveyBanner":"afc-base-theme","$:/_AFC/SurveyBanner/Styles":"afc-base-theme","$:/_AFC/TagDropdown/NewHere":"afc-base-theme","$:/_AFC/TagNavigation/Styles":"afc-base-theme","$:/_AFC/TagNavigationMacro":"afc-base-theme","$:/_AFC/TiddlerInfo/Text":"afc-base-theme","$:/_AFC/consent-banner/buttons/login":"afc-base-theme","$:/_AFC/grey-wordmark.svg":"afc-base-theme","$:/_AMBITWheel/English":"wellbeingservice_public","$:/_AMBITWheel/Macros":"wellbeingservice_public","$:/_AMBITWheel/Styles":"wellbeingservice_public","$:/_Macros/ImageLink":"afc-base-theme","$:/_Macros/LinkDoc":"afc-base-theme","$:/_Macros/LinkPDF":"afc-base-theme","$:/_Macros/Video":"afc-base-theme","$:/_Menu/Home":"wellbeingservice_public","$:/_Menu/Local Practice":"wellbeingservice_public","$:/_Menu/TOC":"wellbeingservice_public","$:/_Menu/Using the Manual":"wellbeingservice_public","$:/_Menu/Wellbeing Service Index":"wellbeingservice_public","$:/_Menu/Wellbeing Training":"wellbeingservice_public","$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/import":"wellbeingservice_public","$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/permaview":"wellbeingservice_public","$:/config/RelinkOnRename":"wellbeingservice_public","$:/config/ViewToolbarButtons/Visibility/$:/plugins/federatial/print/button":"afc-base-theme","$:/config/plugins/menubar/MenuItems/Visibility/$:/plugins/tiddlywiki/menubar/items/contents":"afc-base-theme","$:/config/plugins/menubar/MenuItems/Visibility/$:/plugins/tiddlywiki/menubar/items/server":"afc-base-theme","$:/config/plugins/tiddlywiki/consent-banner/greeting-message":"afc-base-theme","$:/core/ui/MoreSideBar/Drafts":"afc-base-theme","$:/core/ui/SideBar/Tools":"wellbeingservice_public","$:/core/ui/ViewTemplate/subtitle":"afc-base-theme","$:/favicon.ico":"afc-base-theme","$:/language/SideBar/Open/Caption":"wellbeingservice_public","$:/language/SideBar/Recent/Caption":"wellbeingservice_public","$:/palette":"afc-base-theme","$:/plugins/federatial/print/button":"afc-base-theme","$:/plugins/federatial/print/styles":"afc-base-theme","$:/plugins/federatial/print/template":"afc-base-theme","$:/plugins/federatial/print/template/inner":"afc-base-theme","$:/plugins/federatial/print/window":"afc-base-theme","$:/plugins/federatial/xememex/status-button":"afc-base-theme","$:/plugins/tiddlywiki/comments":"wellbeingservice_public","$:/plugins/tiddlywiki/comments/sidebar":"wellbeingservice_public","$:/plugins/tiddlywiki/consent-banner":"afc-base-theme","$:/plugins/tiddlywiki/googleanalytics":"afc-base-theme","$:/plugins/tiddlywiki/menubar":"afc-base-theme","$:/tags/MenuBar":"wellbeingservice_public","$:/tags/TopMenu":"wellbeingservice_public","$:/tags/ViewTemplate":"afc-base-theme","$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth":"wellbeingservice_public","$:/themes/tiddlywiki/vanilla/options/sidebarlayout":"wellbeingservice_public","$:/themes/tiddlywiki/vanilla/settings/backgroundimage":"wellbeingservice_public","3316699902_c3d93e61ce.jpg":"wellbeingservice_public","AF-logo-RGB-Green.png":"wellbeingservice_public","AIM Cards":"wellbeingservice_public","AIM cards - taking a mentalizing stance":"wellbeingservice_public","AIM cards pic1.jpg":"wellbeingservice_public","AMBIT Playing Cards":"wellbeingservice_public","AMBIT Training":"wellbeingservice_public","AMBIT Wiki":"wellbeingservice_public","AMBIT wheel 2014_SMALL.png":"wellbeingservice_public","AMBIT: an overview":"wellbeingservice_public","About us":"wellbeingservice_public","Active Planning":"wellbeingservice_public","Active planning stance and collaborative working":"wellbeingservice_public","Addressing Dis-integration":"wellbeingservice_public","Adolescent Behaviour":"wellbeingservice_public","Alternative Intervention Manuals":"wellbeingservice_public","Anna Freud National Centre for Children and Families":"wellbeingservice_public","Assessments":"wellbeingservice_public","Attachment Theory":"wellbeingservice_public","Autism":"wellbeingservice_public","Autism Screening":"wellbeingservice_public","BOAT Training":"wellbeingservice_public","Behaviour Problems":"wellbeingservice_public","Boundaries: helping CYP to understand and manage boundaries":"wellbeingservice_public","Broadcasting Intentions":"wellbeingservice_public","CapturePEN.PNG":"wellbeingservice_public","Capturecon.PNG":"wellbeingservice_public","Case Closures":"wellbeingservice_public","Cathy Creswell's Book for Child Anxiety":"wellbeingservice_public","Cathy Creswell's Book- Translated Versions":"wellbeingservice_public","Clinical Framework/ Principals":"wellbeingservice_public","Collecting SRS Feedback Remotely":"wellbeingservice_public","Comment by 'eleanorjoscelyne' on 'Returning to face to face work'":"wellbeingservice_public","Comment by 'eleanorjoscelyne' on 'Returning to face to face work' 1":"wellbeingservice_public","Community of Practice":"wellbeingservice_public","Community of practice pic.jpg":"wellbeingservice_public","Completing the Caseload Spreadsheet":"wellbeingservice_public","Consultation Discussion":"wellbeingservice_public","Consultations":"wellbeingservice_public","Contact us":"wellbeingservice_public","Contract outcomes":"wellbeingservice_public","Coping Skills Group for Children and Young People with Mild Learning Disabilities":"wellbeingservice_public","Core Features of AMBIT":"wellbeingservice_public","Core Skills":"wellbeingservice_public","Creating resources for young people":"wellbeingservice_public","Creative Commons Licence":"wellbeingservice_public","Data Queries (Team afternoon - Sept 2020 - Part 1)":"wellbeingservice_public","Developing Learning Organisations":"wellbeingservice_public","Dgrid.png":"wellbeingservice_public","Dilemmas to cover in the next weeks":"wellbeingservice_public","Dilemmas when working with parents":"wellbeingservice_public","Dis-integration Grid":"wellbeingservice_public","Draft of 'AMBIT Training' by mariannemcgowan":"wellbeingservice_public","Draft of 'New Tiddler 2' by chantalleiser":"wellbeingservice_public","Draft of 'New Tiddler 3' by chantalleiser":"wellbeingservice_public","EMHP Wiki":"wellbeingservice_public","Education at home":"wellbeingservice_public","Eligibility Criteria":"wellbeingservice_public","Emotion Regulation":"wellbeingservice_public","Emotion regulation":"wellbeingservice_public","Endings":"wellbeingservice_public","Engagement in remote working":"wellbeingservice_public","Epistemic Trust":"wellbeingservice_public","Examples of goals":"wellbeingservice_public","Exploring and understanding families' cultures":"wellbeingservice_public","Formatting Pages in AFNCCF Manuals":"wellbeingservice_public","Formulation":"wellbeingservice_public","Green Paper: mental health in schools":"wellbeingservice_public","Grid Pic.jpg":"wellbeingservice_public","Group Offer to UM":"wellbeingservice_public","Helping schools to manage behaviour problems (primary)":"wellbeingservice_public","Home":"wellbeingservice_public","HomeContents":"wellbeingservice_public","How do we learn from experience and local expertise?":"wellbeingservice_public","How to Describe Wellbeing":"wellbeingservice_public","How to Use POD":"wellbeingservice_public","How to decide what to offer to families during coronavirus outbreak":"wellbeingservice_public","How to edit your teams manual":"wellbeingservice_public","How to stay better connected with Brent":"wellbeingservice_public","How to use outcome measures in a collaborative way":"wellbeingservice_public","How to work with young people who might feel ambivalent about their network being included in the work":"wellbeingservice_public","Ideas for working with anger":"wellbeingservice_public","Ideas to set up face to face sessions":"wellbeingservice_public","If a training was going to be helpful, what would it help you with? group 1":"wellbeingservice_public","If a training was going to be helpful, what would it help you with? group 2":"wellbeingservice_public","If a training was going to be helpful, what would it help you with? group 3":"wellbeingservice_public","If a training was going to be helpful, what would it help you with? group 4":"wellbeingservice_public","Implementation Ideas for Objective 1":"wellbeingservice_public","Implementation Ideas for Objective 2":"wellbeingservice_public","Implementation Ideas for Objective 3":"wellbeingservice_public","Implementation Ideas for Objective 4":"wellbeingservice_public","Induction for outreach therapists":"wellbeingservice_public","Induction ideas for wellbeing practitioners":"wellbeingservice_public","Initial meetings with Parents":"wellbeingservice_public","Initial meetings with schools":"wellbeingservice_public","Intervention Manuals":"wellbeingservice_public","Introductions exercise":"wellbeingservice_public","KeyWorker":"wellbeingservice_public","Keyworker well-connected to wider team":"wellbeingservice_public","Learning at Work":"wellbeingservice_public","Local Practice":"wellbeingservice_public","Looked after children":"wellbeingservice_public","Managing Anger":"wellbeingservice_public","Managing Risk":"wellbeingservice_public","Managing endings":"wellbeingservice_public","Managing more than one person in a session":"wellbeingservice_public","Managing transitions back to school during the pandemic COVID":"wellbeingservice_public","Manualization":"wellbeingservice_public","ManualizedWorkContents":"wellbeingservice_public","Manualizing list":"wellbeingservice_public","Mapping":"wellbeingservice_public","Mapping networks with parents":"wellbeingservice_public","Marking the Task":"wellbeingservice_public","Mentalization":"wellbeingservice_public","Mentalizing and team learning group 1":"wellbeingservice_public","Mentalizing and team learning group 2":"wellbeingservice_public","Mentalizing and team learning group 3":"wellbeingservice_public","Mentalizing and team learning group 4":"wellbeingservice_public","Mentalizing the Moment (in Thinking Together)":"wellbeingservice_public","Mentalizing the impact of coronavirus on families":"wellbeingservice_public","Module 3 actions":"wellbeingservice_public","Motivational Interviewing":"wellbeingservice_public","NAV.PNG":"wellbeingservice_public","Our To Do List":"wellbeingservice_public","Outcome Measures":"wellbeingservice_public","Planning our work":"wellbeingservice_public","Qualification and recognition of training and experience":"wellbeingservice_public","Reaching shared agreement between parents and young people":"wellbeingservice_public","Recording systems":"wellbeingservice_public","Referral form":"wellbeingservice_public","Reflections on learning at work":"wellbeingservice_public","Reflections on module 3":"wellbeingservice_public","Reflections on module 4":"wellbeingservice_public","Reflections on module 5":"wellbeingservice_public","Reflections on the first training":"wellbeingservice_public","Reflections on training workshop 2":"wellbeingservice_public","Reflections on using the AIM cards":"wellbeingservice_public","Reflections on wellbeing videos":"wellbeingservice_public","Relationship to Help":"wellbeingservice_public","Report Writing Guidelines":"wellbeingservice_public","Reporting Re-vamped":"wellbeingservice_public","Reporting deadlines.PNG":"wellbeingservice_public","Resources for work":"wellbeingservice_public","Resources to support families during coronavirus":"wellbeingservice_public","Resources to support staff during coronavirus":"wellbeingservice_public","Respect Local Practice and Expertise":"wellbeingservice_public","Respect for Evidence":"wellbeingservice_public","Return to Purpose":"wellbeingservice_public","Returning to face to face work (October)":"wellbeingservice_public","Scaffolding Existing Relationships":"wellbeingservice_public","Scaling questions":"wellbeingservice_public","School Refusal and Separation Anxiety":"wellbeingservice_public","Schools Outreach Service Wiki":"wellbeingservice_public","Sculpting a Network":"wellbeingservice_public","Self-Esteem":"wellbeingservice_public","Self-Help Materials":"wellbeingservice_public","Self-care: On My Mind":"wellbeingservice_public","Self-harm":"wellbeingservice_public","Separation Anxiety":"wellbeingservice_public","Sequences":"wellbeingservice_public","Service Development Afternoons":"wellbeingservice_public","Service development space":"wellbeingservice_public","Sharing our existing experience and skills":"wellbeingservice_public","Signs and Safety":"wellbeingservice_public","SiteIcon":"wellbeingservice_public","Stance-Domains.jfif":"wellbeingservice_public","Stating the Case":"wellbeingservice_public","Strategies we use in our work during lockdown":"wellbeingservice_public","Successes":"wellbeingservice_public","Supervisory Structures":"wellbeingservice_public","Supporting Parents Wellbeing":"wellbeingservice_public","Supporting families to create routine/structure":"wellbeingservice_public","Synergy Pss":"wellbeingservice_public","Taking Responsibility for Integration":"wellbeingservice_public","Talking with CYP about the COVID Pandemic and related worries":"wellbeingservice_public","Team Afternoon - Sept 2020 (Part 2)":"wellbeingservice_public","The AMBIT Pro-Gram":"wellbeingservice_public","The AMBIT Pro-Gram: an example":"wellbeingservice_public","The Importance of Feedback":"wellbeingservice_public","The Therapist's Mentalizing Stance":"wellbeingservice_public","Thinking Together":"wellbeingservice_public","Thinking together":"wellbeingservice_public","Thrive framework":"wellbeingservice_public","Thrive model":"wellbeingservice_public","Training 02.06.2021":"wellbeingservice_public","Training Exercises":"wellbeingservice_public","Training Resources":"wellbeingservice_public","Training Themes":"wellbeingservice_public","Training ideas":"wellbeingservice_public","Training workshop 1 - well-being practitioners":"wellbeingservice_public","Training workshop 2 - wellbeing practitioners":"wellbeingservice_public","TrainingCore":"wellbeingservice_public","Transition to secondary school":"wellbeingservice_public","Transitions (Back to School)":"wellbeingservice_public","Troubleshooting":"wellbeingservice_public","Understanding our training needs":"wellbeingservice_public","User Guide":"wellbeingservice_public","WEST Consultation model":"wellbeingservice_public","WEST Outcome Measures Discussions":"wellbeingservice_public","WEST report writing":"wellbeingservice_public","Waiting list":"wellbeingservice_public","Well Connected Team: Ideas for supporting each other without 'jumping in the pond together'":"wellbeingservice_public","Wellbeing Service":"wellbeingservice_public","Wellbeing Service Index":"wellbeingservice_public","Wellbeing Training":"wellbeingservice_public","Wellbeing Work":"wellbeingservice_public","Wellbeing patchwork":"wellbeingservice_public","WellbeingTrainingContents":"wellbeingservice_public","What do we do if we know a family that is referred?":"wellbeingservice_public","What do we think the difference is between well-being and mental health?":"wellbeingservice_public","What do workers in this team need to do their job well? group 1":"wellbeingservice_public","What do workers in this team need to do their job well? group 2":"wellbeingservice_public","What do workers in this team need to do their job well? group 3":"wellbeingservice_public","What do workers in this team need to do their job well? group 4":"wellbeingservice_public","What evidence do we draw on in our work?":"wellbeingservice_public","What feelings does the work bring up for workers,  both positive and negative? group 1":"wellbeingservice_public","What feelings does the work bring up for workers,  both positive and negative? group 2":"wellbeingservice_public","What feelings does the work bring up for workers,  both positive and negative? group 3":"wellbeingservice_public","What feelings does the work bring up for workers,  both positive and negative? group 4":"wellbeingservice_public","What happens when risk escalates":"wellbeingservice_public","What have we learned during training?":"wellbeingservice_public","What is a wellbeing review?":"wellbeingservice_public","What makes the work hard? group 1":"wellbeingservice_public","What makes the work hard? group 2":"wellbeingservice_public","What makes the work hard? group 3":"wellbeingservice_public","What makes the work hard? group 4":"wellbeingservice_public","What we think wellbeing is":"wellbeingservice_public","Wheel with client highlighted.jpg":"wellbeingservice_public","Who has your rope pic.jpg":"wellbeingservice_public","Wiki Manual":"wellbeingservice_public","Working Remotely (COVID-19)":"wellbeingservice_public","Working in Multiple Domains":"wellbeingservice_public","Working in Schools":"wellbeingservice_public","Working in schools (November)":"wellbeingservice_public","Working remotely with children and young people with anxiety and low mood":"wellbeingservice_public","Working with Behaviour Problems":"wellbeingservice_public","Working with Looked After Children":"wellbeingservice_public","Working with Peer Difficulties":"wellbeingservice_public","Working with Your Client":"wellbeingservice_public","Working with Your Networks":"wellbeingservice_public","Working with Your Team":"wellbeingservice_public","Working with carers of LAC children and trauma":"wellbeingservice_public","Working with co-morbidity":"wellbeingservice_public","Working with low mood":"wellbeingservice_public","Working with parents":"wellbeingservice_public","Working with parents to support CYP's emotion regulation":"wellbeingservice_public","Working with schools":"wellbeingservice_public","Working with sleep difficulties":"wellbeingservice_public","Working with/through parents (remotely)":"wellbeingservice_public","_GoogleDocsIcons_docs":"afc-base-theme","_GoogleDocsIcons_sheets":"afc-base-theme","_GoogleDocsIcons_slides":"afc-base-theme","alexis-brown-omeaHbEFlN4-unsplash.jpg":"wellbeingservice_public","anastasia-petrova-xu2WYJek5AI-unsplash (1).jpg":"wellbeingservice_public","ap..png":"wellbeingservice_public","books pic 1.jpg":"wellbeingservice_public","broadcasting Pic.jpg":"wellbeingservice_public","ian-dooley-3NCA3tbaE5I-unsplash.jpg":"wellbeingservice_public","luciano-de-sa-ObwMZBdEWdI-unsplash (1).jpg":"wellbeingservice_public","melissa-askew-tSlvoSZK77c-unsplash.jpg":"wellbeingservice_public","patrick-tomasso-Oaqk7qqNh_c-unsplash.jpg":"wellbeingservice_public"}
{"$:/DefaultTiddlers":"\"2a0ad6248bdf0f494c4080a662325430\"","$:/GoogleAnalyticsAccount":"\"1d6a12df4239d409d489167749c0bed1\"","$:/GoogleAnalyticsMeasurementID":"\"18911c203bbfeecb9a7a5da94216ac89\"","$:/SiteSubtitle":"\"d04745d1587a701f986ee028441e5e92\"","$:/SiteTitle":"\"b3580cc5e72299034226e9fb06b80b24\"","$:/_AFC/AboveStory/Logo":"\"f90abc11b7d842cf11d2e8dd07d781e5\"","$:/_AFC/EditDraftInfoSegment":"\"14b97bb8d45794bfb36bf9192951e8f5\"","$:/_AFC/Fonts/UseFonts":"\"7a194c57092242bf0f99c79bd6e28fe2\"","$:/_AFC/Macros/Image":"\"c187fbc8c037e27fd02504e25c0aa644\"","$:/_AFC/Macros/YouTube":"\"571226f519b51c4b102ca27cec59bbcf\"","$:/_AFC/Palette":"\"ca7a1c4cb8fa5427f4888c32ab3fb515\"","$:/_AFC/Startup/ConfigurePreview":"\"d186a5c9b65e35420bbf7741b3c5f117\"","$:/_AFC/Styles/Bubbles":"\"78f9eee66bbb77bb10131346cb66b379\"","$:/_AFC/Styles/DocLinks":"\"406c2d60bf469bba7f5ce36c04f5ce08\"","$:/_AFC/Styles/FadedSidebar":"\"f429edacd34f19f1559a3779bc8d8dab\"","$:/_AFC/Styles/HideEditButton":"\"051c89709a3e30ce00bcd654225c25f4\"","$:/_AFC/Styles/Overrides":"\"34c7de5409fa262ece619897eb8cf27d\"","$:/_AFC/Styles/TopMenu":"\"b0cd98b814e1a1a2bea0e34aa3e2e60c\"","$:/_AFC/SurveyBanner":"\"b3015c7cf7503a0e11b08600c77311c8\"","$:/_AFC/SurveyBanner/Styles":"\"a2ccfcbd8fd68cad395e3149bf599069\"","$:/_AFC/TagDropdown/NewHere":"\"45deec1e2ad63899621dfb64b7cbe229\"","$:/_AFC/TagNavigation/Styles":"\"6db135a88329f41ed8427ff8c2ce51cb\"","$:/_AFC/TagNavigationMacro":"\"d3f8203a1a45a0fde2ef8e3faab820bf\"","$:/_AFC/TiddlerInfo/Text":"\"535865a9e975de227599cdd32f4ccc9e\"","$:/_AFC/consent-banner/buttons/login":"\"53924a18efd5ea26807b35fb2f545f68\"","$:/_AFC/grey-wordmark.svg":"\"d2b3a7add5aea8657db3bbeb3b498ae1\"","$:/_AMBITWheel/English":"\"e1a34868e071e2779f56db6affafd799\"","$:/_AMBITWheel/Macros":"\"479cd324f0c2ddeabd42e7572d60f985\"","$:/_AMBITWheel/Styles":"\"193fb46d453d0aa9b6ae9f235c6c748b\"","$:/_Macros/ImageLink":"\"3bbbf684a6393e57386fd7a0bcf1b94e\"","$:/_Macros/LinkDoc":"\"bea2d309a4d3c118bad5d5b78472977d\"","$:/_Macros/LinkPDF":"\"1833c49010a51b795109546425d87189\"","$:/_Macros/Video":"\"76773c71485bfc36f916e293e1eb17b8\"","$:/_Menu/Home":"\"e6963c134c5cc742e72820281d9b40dd\"","$:/_Menu/Local Practice":"\"79b84ef4e1740e54d196f8603ea45a29\"","$:/_Menu/TOC":"\"3266c1373345094f44b156c2704e3b56\"","$:/_Menu/Using the Manual":"\"f67c16a108837ad82ba0cb0d97a92e98\"","$:/_Menu/Wellbeing Service Index":"\"07aa5093f8c0365004266d80f575b603\"","$:/_Menu/Wellbeing Training":"\"1722d9af2afa0f3cd63bf95c8c8f1939\"","$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/import":"\"551d1696ead0480ebc8b817711c2e7e6\"","$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/permaview":"\"b1ef4650699db0f8ce693d335ff86289\"","$:/config/RelinkOnRename":"\"b2a5de65b130c06c2d8f6554f86d5874\"","$:/config/ViewToolbarButtons/Visibility/$:/plugins/federatial/print/button":"\"0e15c4427b0db8bc7ab25e467aa8c0bd\"","$:/config/plugins/menubar/MenuItems/Visibility/$:/plugins/tiddlywiki/menubar/items/contents":"\"d86d3acf25e62ebab56871fef1e7faae\"","$:/config/plugins/menubar/MenuItems/Visibility/$:/plugins/tiddlywiki/menubar/items/server":"\"9030fe5f447225c77631be1bd328ce71\"","$:/config/plugins/tiddlywiki/consent-banner/greeting-message":"\"135d7ecf1b4eb392c0f8a6563befb5db\"","$:/core/ui/MoreSideBar/Drafts":"\"bc8030c66ff72ad4a0d9f0000f16600d\"","$:/core/ui/SideBar/Tools":"\"e50fd49a7146be814081c69fcbc0fe8c\"","$:/core/ui/ViewTemplate/subtitle":"\"b0c8d4a1cfa25413f198cc963d3f4ef8\"","$:/favicon.ico":"\"9233b4d8e50d7c217c16a80d623deedb\"","$:/language/SideBar/Open/Caption":"\"266b26c370b38b56584b6b416f7b7b34\"","$:/language/SideBar/Recent/Caption":"\"8a582b993005f1a022c7b5047b6e243b\"","$:/palette":"\"0cd9d6ab24ec5f6cd0e4734287f77af1\"","$:/plugins/federatial/print/button":"\"e25177d0c3d818bbe28b1a7f36bc0b4c\"","$:/plugins/federatial/print/styles":"\"2ea66bf6be0fb2a73f32ce9825fd325a\"","$:/plugins/federatial/print/template":"\"581a8671a3e18319afcd6ff8c916f21e\"","$:/plugins/federatial/print/template/inner":"\"bd9a103267a6863fbaa0fb1fbe2e66ed\"","$:/plugins/federatial/print/window":"\"968a343265c864d64a865e478bbf912a\"","$:/plugins/federatial/xememex/status-button":"\"2277ef8c8a197aef0bbd393f2a6dbfbb\"","$:/plugins/tiddlywiki/comments":"\"d36e130cb6772174e1dc1a5a82e2aa4b\"","$:/plugins/tiddlywiki/comments/sidebar":"\"73855af0a7cd11572f759a73329f57c3\"","$:/plugins/tiddlywiki/consent-banner":"\"9fabdf6138d07ba9e123427fb3c50329\"","$:/plugins/tiddlywiki/googleanalytics":"\"3fb55c0cc1b173e87ed6c6d092acdec8\"","$:/plugins/tiddlywiki/menubar":"\"414c88bf626bb22343e801593cc9bb0f\"","$:/tags/MenuBar":"\"1bbce5e19b23dc2eed1793f4149d805b\"","$:/tags/TopMenu":"\"c8aad9bf14357b203b048815c88cfd1e\"","$:/tags/ViewTemplate":"\"d665195bf405c0eff27ac5c2807b7287\"","$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth":"\"80badb339532565570a623709cc5c524\"","$:/themes/tiddlywiki/vanilla/options/sidebarlayout":"\"dc18c3bc48d96445f488d79c0cbd4859\"","$:/themes/tiddlywiki/vanilla/settings/backgroundimage":"\"fabe146d8abc062c83bcd5622ba56876\"","3316699902_c3d93e61ce.jpg":"\"10c873e0b8939fa37662e06a1eab35ce\"","AF-logo-RGB-Green.png":"\"4e39406992604441d53e2862767bc892\"","AIM Cards":"\"8f8b5d210f83aea2664ddf9e67f817d0\"","AIM cards - taking a mentalizing stance":"\"e9fd04237cf63a08ba0e5d26d09bacec\"","AIM cards pic1.jpg":"\"44a3e1d9f2a80238c1af5fa7ea93428c\"","AMBIT Playing Cards":"\"eadebf1811f0a90d854477e6c5df9263\"","AMBIT Training":"\"dfbeb997ecc33e552149c28575344c80\"","AMBIT Wiki":"\"f9bf680def9d83e46e490158b1dd3a49\"","AMBIT wheel 2014_SMALL.png":"\"abc898f639457e9a6d91c18a8d409fea\"","AMBIT: an overview":"\"ca5ce48ee520ef6ba1d5dd1633a05601\"","About us":"\"fbec09bbd87675d314e8c16a1c55799c\"","Active Planning":"\"1f17e18d034c456571d95d996837da6b\"","Active planning stance and collaborative working":"\"2e848b9cea7463ca6ed2e4127b85345e\"","Addressing Dis-integration":"\"cc5fc5dffab305a3a2b6d7b0dd5c5f86\"","Adolescent Behaviour":"\"0cacd7eb8f8fac2358823e82f23f0a7c\"","Alternative Intervention Manuals":"\"d665bf1e77b9c59bc1111e5b562150c5\"","Anna Freud National Centre for Children and Families":"\"4a7d91f05954db41bf63dbc51dec9f73\"","Assessments":"\"0aaae8ffc3919ade77dde0588c3bc4f4\"","Attachment Theory":"\"d0364638cd5d588c4c6518701c25243a\"","Autism":"\"8e71d1fe2f71366250dfa14ab0b42061\"","Autism Screening":"\"6621178b2322444275fcaee6188ee263\"","BOAT Training":"\"7ff137edfc3cf5896ead3fb8f644fa3b\"","Behaviour Problems":"\"639b54d05c70274378753d34b0b78bcd\"","Boundaries: helping CYP to understand and manage boundaries":"\"773b1f5cc0c4e7646d7b4cb9349916b2\"","Broadcasting Intentions":"\"17762c4efe5620bb6f028a6307cf5b30\"","CapturePEN.PNG":"\"c90e44256be2f089031bff3c6928f017\"","Capturecon.PNG":"\"b62b29f1c7022319f72e19617586dcf3\"","Case Closures":"\"4b8a33c22524165a0cef63ff9c6db80d\"","Cathy Creswell's Book for Child Anxiety":"\"5788f607a301290f152d08934f15c42f\"","Cathy Creswell's Book- Translated Versions":"\"7a25451da86a2c144cf977a7b4766ec6\"","Clinical Framework/ Principals":"\"242e2d12077696776d52363604a923bb\"","Collecting SRS Feedback Remotely":"\"a91282837f663fe4cad3813d7b536776\"","Comment by 'eleanorjoscelyne' on 'Returning to face to face work'":"\"5b07fa11a3ec86aa56c2b87352c00452\"","Comment by 'eleanorjoscelyne' on 'Returning to face to face work' 1":"\"3157e90f0459ccce7802dc83b0b37e9e\"","Community of Practice":"\"2a94a0ed126388dbc46991efbf0c76da\"","Community of practice pic.jpg":"\"d587c9199e04b21a03027cc95ab8da6d\"","Completing the Caseload Spreadsheet":"\"3a949f56fa761adb870188bc2ef3278a\"","Consultation Discussion":"\"ed1915ecbc351035d8922dd044e5c1f7\"","Consultations":"\"0060a247870949cf2f880fb2dc89e327\"","Contact us":"\"4eea1a6df56fa057dbb791b6a7323c88\"","Contract outcomes":"\"6826659639472350132391155fd6d30b\"","Coping Skills Group for Children and Young People with Mild Learning Disabilities":"\"0ca47275f4d2db38f8359ee073f190e3\"","Core Features of AMBIT":"\"ab9e1cbfdac3e8c5a26a4b539df3ed80\"","Core Skills":"\"b21e13fdf90df8a74a9a310f79579320\"","Creating resources for young people":"\"fecf33c6bc3d2c5e3a1f8e6788eadf3d\"","Creative Commons Licence":"\"ce81e805475b621de8cfe165820ba513\"","Data Queries (Team afternoon - Sept 2020 - Part 1)":"\"7e5c6fa7b8f70716901a79347027784b\"","Developing Learning Organisations":"\"2916589242c7387919a74fb2a9f55ce2\"","Dgrid.png":"\"76d3a1714e6440166e3165730e2cbe96\"","Dilemmas to cover in the next weeks":"\"fc449fef5e576aba7ffab763f09098f3\"","Dilemmas when working with parents":"\"c50ef4890e6f63d59e3d260b6be79548\"","Dis-integration Grid":"\"87c8e4ed88bd6b5ec9606f522837abec\"","Draft of 'AMBIT Training' by mariannemcgowan":"\"179f72e33da80a87b736caf2f136fc16\"","Draft of 'New Tiddler 2' by chantalleiser":"\"65adbccfbbd940b04cc8f63a0cb0ab47\"","Draft of 'New Tiddler 3' by chantalleiser":"\"f30623a561e469ba7b18581b35a19105\"","EMHP Wiki":"\"e2c50c358e10f5a044810d6defb636fd\"","Education at home":"\"edc5eb8569d79a36f58247a0f9c0ca9a\"","Eligibility Criteria":"\"50e4385add974e6605e156384548ad12\"","Emotion Regulation":"\"0ca036279d0585dfcd8936ac552ab579\"","Emotion regulation":"\"2723e9bed57ae77310feff7303f6c932\"","Endings":"\"ca73b1e26121e7744fbe6bfe42f2ea3c\"","Engagement in remote working":"\"59d801464d5a9375328515ba1dafd049\"","Epistemic Trust":"\"2dea39b3fd4f147f3113471ea3a6f060\"","Examples of goals":"\"b581a3e9e72693d521ba07b7b0151fea\"","Exploring and understanding families' cultures":"\"4087b5b18c28582f014d5467fa611ebc\"","Formatting Pages in AFNCCF Manuals":"\"4a2ac1aef03d9ed5cdbec5e2436652a8\"","Formulation":"\"036b5dad43637b5bcccb1068d712bb7e\"","Green Paper: mental health in schools":"\"fb8468fd6b426fc77f4489b55429164e\"","Grid Pic.jpg":"\"56b919c50c7211aba7a37f7365d37673\"","Group Offer to UM":"\"5b9492cfe01117a6a7ef546fbcbbdd3d\"","Helping schools to manage behaviour problems (primary)":"\"e55d2b87264f680659dd6cfbafd16e54\"","Home":"\"c1b242a247c01a5327d6bd93f55dc51a\"","HomeContents":"\"f869a47249adeceb66830fe30f444a5b\"","How do we learn from experience and local expertise?":"\"5e4d7f23cf1dbf2a6c5cb0d566b693c5\"","How to Describe Wellbeing":"\"4540f49be5cba47fb1f54b5d309363d6\"","How to Use POD":"\"310c9ffdaea92b29ed2f0037a4f98067\"","How to decide what to offer to families during coronavirus outbreak":"\"40e3bceed117aba013c0605e3e5ffdeb\"","How to edit your teams manual":"\"94c5c96ecbb53f0981a5e9873b32ccd1\"","How to stay better connected with Brent":"\"5cc0d5b674b5f27de131be8535169a95\"","How to use outcome measures in a collaborative way":"\"7bc4f4a5194a40dabf2fba5e7129acd1\"","How to work with young people who might feel ambivalent about their network being included in the work":"\"29efcd26f95962b0fa7469ed64cf9c13\"","Ideas for working with anger":"\"e0f6726d71b5da81460b525ab3c392f1\"","Ideas to set up face to face sessions":"\"28bd038d2e4aeef75949bdf887279445\"","If a training was going to be helpful, what would it help you with? group 1":"\"b92c70fc5a666a570152912a58d8428f\"","If a training was going to be helpful, what would it help you with? group 2":"\"8e2c9dfb7a0ef96c24df4ba374555cfd\"","If a training was going to be helpful, what would it help you with? group 3":"\"ca3128870f8c758a0aa6f39543a5fa91\"","If a training was going to be helpful, what would it help you with? group 4":"\"69aa0a861e33f9d9733140a1103e6726\"","Implementation Ideas for Objective 1":"\"0d04c5f03e17b698237d543d56896859\"","Implementation Ideas for Objective 2":"\"f16a7281958863bd1f430e7aee9e8bd7\"","Implementation Ideas for Objective 3":"\"b8967d57e4af6462fdc53c7d2a52a55a\"","Implementation Ideas for Objective 4":"\"66a47fd73a50d49ac5cbbe2ac23f7d89\"","Induction for outreach therapists":"\"6de796026263fa2ab7009374169123b1\"","Induction ideas for wellbeing practitioners":"\"f764aac8173615ea4d8211a48509f42e\"","Initial meetings with Parents":"\"aea4e43ef731a8791e9f0a07c96ff2e2\"","Initial meetings with schools":"\"93303c2fa4cb804bc3f4e6d9e8c0c07a\"","Intervention Manuals":"\"ba9331e0d112e0a2f35d2839fbf1a52f\"","Introductions exercise":"\"d02d504cb406db2aa732021b7a9a4a4d\"","KeyWorker":"\"b5894ac257de4703c4f33fc9ffaddf11\"","Keyworker well-connected to wider team":"\"ee8e21be912acea942c2d6f340f6f2f0\"","Learning at Work":"\"5a1e37a0845499364d6f48ecceefb25c\"","Local Practice":"\"39917de52c9fbbd2f5b13ec4d88204a4\"","Looked after children":"\"74db8dba7cb3eec485011a95c5e20a5d\"","Managing Anger":"\"5a67f7d519272d712158e9f4db337832\"","Managing Risk":"\"8e9c2e7ac8dc62b05faab0fec3cd54f8\"","Managing endings":"\"e3e7109a40c202bf5449d22bcccd3cf5\"","Managing more than one person in a session":"\"02b703a9912de6043e2a2f0d7dc6fd99\"","Managing transitions back to school during the pandemic COVID":"\"72fdad7bff7bde202aa53292f88bdbfd\"","Manualization":"\"7c8f66b495f8cf19a1f95176166fa27e\"","ManualizedWorkContents":"\"6d4f076e2cbb069fd1ab8688d6b45b64\"","Manualizing list":"\"aa92552a14b76042070135134b86a76c\"","Mapping":"\"efdbabe784038811cafa2ede6bf3ac77\"","Mapping networks with parents":"\"973c5943ca58f19843aa62f8bdebf144\"","Marking the Task":"\"b374a9a7ab0767df443d316f212c12e4\"","Mentalization":"\"cd0f1cc5b32a22b1ad80e9fefe0dd907\"","Mentalizing and team learning group 1":"\"f768f7f270bb4e1d834474e04735c26e\"","Mentalizing and team learning group 2":"\"5b3f0c2c7d7fc2f66ba0a6457aa566cf\"","Mentalizing and team learning group 3":"\"cd43e485e63d02ec063ad1d47f0fc6c2\"","Mentalizing and team learning group 4":"\"d98aac9d66b918c2d470ee9bfac82873\"","Mentalizing the Moment (in Thinking Together)":"\"fd8f088e98f50c616d809bcd37987145\"","Mentalizing the impact of coronavirus on families":"\"c64e72c0c309ddc774a0f93eca95f8be\"","Module 3 actions":"\"f1bdb2c7cec39373bc852d9c9edc0b9f\"","Motivational Interviewing":"\"1c28b90e7990fadda4792d7d7592a5a9\"","NAV.PNG":"\"5c3bdd08657087645eeda8384767dafd\"","Our To Do List":"\"259a19223eb12a6848b33ef8aa07e893\"","Outcome Measures":"\"eaff18d2c9598c2fba52b3997a3cc63a\"","Planning our work":"\"57ec025453bdd1d7a571510d2583a808\"","Qualification and recognition of training and experience":"\"9a018f8fe2fa38d15e69e1aaccfebd56\"","Reaching shared agreement between parents and young people":"\"eaa19054eb14d69dac77f6531c9505dc\"","Recording systems":"\"2ca7d57aada7b37aca8c57cd3da7842c\"","Referral form":"\"65c4d99dc999b48abbf40aece3f59d82\"","Reflections on learning at work":"\"f3fac0437b27e02da905456b26fe5999\"","Reflections on module 3":"\"9464d19508a0243d5d315dda7fa805db\"","Reflections on module 4":"\"0f011ae8848d52d35e0a32485865fcf0\"","Reflections on module 5":"\"28d33cc8ed47363c0fc0f829add715be\"","Reflections on the first training":"\"a2d17a9d6fe5b8226c3f33dda745c82a\"","Reflections on training workshop 2":"\"15927a781f147798b49b5d0f5447f8a2\"","Reflections on using the AIM cards":"\"466369c899f67188eafa4d087547acee\"","Reflections on wellbeing videos":"\"c31d8654eab62cce9ffbe42c5b239837\"","Relationship to Help":"\"28b68d768eeb3c1af70f7ca9c0f7300e\"","Report Writing Guidelines":"\"6338804d294ec33d68ed8e20e0a3e223\"","Reporting Re-vamped":"\"afe6b91e6b92c392f90e494a2d0d28cc\"","Reporting deadlines.PNG":"\"884772ea30bb390ee21a4ec409e8a141\"","Resources for work":"\"34df1ea020bbfb081fa467490396042c\"","Resources to support families during coronavirus":"\"e6a3dd62c2a2accf6a75532e7e621354\"","Resources to support staff during coronavirus":"\"919b6ca96fbf05638f26dea0be17e9d9\"","Respect Local Practice and Expertise":"\"d2aec8321300b8c1987cb018c09c36e1\"","Respect for Evidence":"\"7b1a214e7b56aa23c93f302c4eed1f4f\"","Return to Purpose":"\"04626094cec873ed9e0eee831cf1e047\"","Returning to face to face work (October)":"\"c963811878826fcf899ad84e67dbfa8f\"","Scaffolding Existing Relationships":"\"3162ba5f76cfa914c8e4ca74a73c0cce\"","Scaling questions":"\"ee4715c4c8534a03b2a6387b65b29f63\"","School Refusal and Separation Anxiety":"\"436ab1abbdf27a0219345a872ba50eaf\"","Schools Outreach Service Wiki":"\"b6c6d3d07de37771fb20766ee7ea02a0\"","Sculpting a Network":"\"bca5423f5b7529038acf80e944f26940\"","Self-Esteem":"\"3caf7971eb4fa5e7293352b9a7ffc6e4\"","Self-Help Materials":"\"dde0c0ca3957153915e71a575db6e084\"","Self-care: On My Mind":"\"f7d096caa7573cce69c6dbc706251d64\"","Self-harm":"\"298003b831edb7d66580ccd0c730200a\"","Separation Anxiety":"\"c4df023b35ae650661260c6dee7a9f7c\"","Sequences":"\"607696724dab8ad32bb50d7a2b384c43\"","Service Development Afternoons":"\"f6e449870556e2f6424f4a4bc4319c47\"","Service development space":"\"8144a634266dbe5baffb931f6dd69b25\"","Sharing our existing experience and skills":"\"94b245b6713aadce860940f58d1a13f7\"","Signs and Safety":"\"d6d4b6791d455341c7bb7b1c67360848\"","SiteIcon":"\"115047065f730f9b8fb2f7ddd9b37d1d\"","Stance-Domains.jfif":"\"b6751695aa60cea1ee3905e8e5b93d87\"","Stating the Case":"\"01adcbc4135a52795730baffe30f9904\"","Strategies we use in our work during lockdown":"\"929415189fabdbbd8de10f9353a195f1\"","Successes":"\"f5ab9a828c8dce680709f11490bfc658\"","Supervisory Structures":"\"cc1ef8b607951e9d6e25e52eccee2584\"","Supporting Parents Wellbeing":"\"1cdbeb8458715f2cd55cea00e3ea146f\"","Supporting families to create routine/structure":"\"fb39d1735460b9bb068544ee778542bc\"","Synergy Pss":"\"badf46911f875c17405081b3a83415d1\"","Taking Responsibility for Integration":"\"bc91819c2eda564cc4f53f1f28e36500\"","Talking with CYP about the COVID Pandemic and related worries":"\"d019a4ee6d6fe7e96891fe8780a8d2c7\"","Team Afternoon - Sept 2020 (Part 2)":"\"cda2180a24112240bb610ce831ccc1d6\"","The AMBIT Pro-Gram":"\"c8e58d667321c2350ac77640386178c3\"","The AMBIT Pro-Gram: an example":"\"a4fe9330168c957d443b0a7c4dbd29b1\"","The Importance of Feedback":"\"84342eaffc0665714fd05cd2123ca941\"","The Therapist's Mentalizing Stance":"\"b7d5b77326628cfd6ed3037f5c63b674\"","Thinking Together":"\"f8312f5fada9ac63a3ae98ad5e59273e\"","Thinking together":"\"0b69f833926ceca221206ecf4f7c92d3\"","Thrive framework":"\"492c4b5996e7c81a8f1f79770d0e5337\"","Thrive model":"\"43b29f44c00ded23c84065b38ee1d1a5\"","Training 02.06.2021":"\"3989ed12a242ccca65013d4e34ae6a70\"","Training Exercises":"\"82117ff76b7bf45f9a094923e3a332fa\"","Training Resources":"\"9acc7f31756b6d1f2efaeb73067a72e6\"","Training Themes":"\"179fa04a0f7a15d35bdd821619592180\"","Training ideas":"\"b5ff8816f615469bf6870e3e177a6a3e\"","Training workshop 1 - well-being practitioners":"\"1fc011857d17e943ea57c4d5f43062b2\"","Training workshop 2 - wellbeing practitioners":"\"ee5e34db918fa9663dc822e6bea5a034\"","TrainingCore":"\"e243677af625875a1e50ed91c8e3aab7\"","Transition to secondary school":"\"fad5c378738ab0595c81e340922e3685\"","Transitions (Back to School)":"\"2b4202b6bfe26926f5f9dc72a3c50599\"","Troubleshooting":"\"f428bfced509f492db8d47a18ec3c9a9\"","Understanding our training needs":"\"0b1ae0cc4a5953a8c23d08e41a7fcee2\"","User Guide":"\"cb130e0512b5bc2d5b20990546c62b5d\"","WEST Consultation model":"\"da1499f7b0b03671c7d42c163672c795\"","WEST Outcome Measures Discussions":"\"34f07d9890a17cea2c8ec4bd172464a2\"","WEST report writing":"\"502c9c8a48b12d12a1aa2c424e518fe0\"","Waiting list":"\"561c8fbd4400fdfa007787b6a7cc0950\"","Well Connected Team: Ideas for supporting each other without 'jumping in the pond together'":"\"03055a917087226c5e109d989a1fe627\"","Wellbeing Service":"\"8ad71caaa507093733e1b309e2abfa7a\"","Wellbeing Service Index":"\"0cb198c352def67e03adc611514b749a\"","Wellbeing Training":"\"e5332f2f3c686e66b54e1ce6a8133183\"","Wellbeing Work":"\"f74f446ae56faaa9b3a24291245aedd9\"","Wellbeing patchwork":"\"9865ddb8c9decb133a20761e5cbb5c7a\"","WellbeingTrainingContents":"\"e943f760075ce73ee442569c391f46ea\"","What do we do if we know a family that is referred?":"\"e557667bc3651ecdd725a7a6b7175209\"","What do we think the difference is between well-being and mental health?":"\"f8930edd44f10160f37dc3626a3d8115\"","What do workers in this team need to do their job well? group 1":"\"0ba0ce939a82e576720e94050a2a25e7\"","What do workers in this team need to do their job well? group 2":"\"95a69fd82f289d3870a0219202c00854\"","What do workers in this team need to do their job well? group 3":"\"fcd46967ff146166453b85efb9f07250\"","What do workers in this team need to do their job well? group 4":"\"fed3ad5f6be9131f216f015c85ad9b8a\"","What evidence do we draw on in our work?":"\"fbcd06b018e945eec3b09820731f6f2c\"","What feelings does the work bring up for workers,  both positive and negative? group 1":"\"66c7c4215ea75ad3b117eab8b2b7dee2\"","What feelings does the work bring up for workers,  both positive and negative? group 2":"\"2e4d516d3ba4b7f4b9bcacab68ed2543\"","What feelings does the work bring up for workers,  both positive and negative? group 3":"\"f661135e5bca7f3cae14f60961a1d0ed\"","What feelings does the work bring up for workers,  both positive and negative? group 4":"\"7a4bd7a78179025066706e52dfeebb8d\"","What happens when risk escalates":"\"6fbf6c8c944b21b10f51335eec4b2aa2\"","What have we learned during training?":"\"4ee00a74f54d8b2bd75318eda25744c9\"","What is a wellbeing review?":"\"162716cbf04999dacb636ca873794cf5\"","What makes the work hard? group 1":"\"705dba287cdee4af26440535419b6ef0\"","What makes the work hard? group 2":"\"5ced8e23320614cef7ec6cb4d48ae08c\"","What makes the work hard? group 3":"\"5acf11a04ebba80b0e76dad9aa70743d\"","What makes the work hard? group 4":"\"60f8914a2ac4d0bda403d26b2326ac71\"","What we think wellbeing is":"\"4290ff31854a8a41ec44537243d87a35\"","Wheel with client highlighted.jpg":"\"af069d6e97788c6b27ad78aaf628551f\"","Who has your rope pic.jpg":"\"ee3fa601ba515f2f73755b26ba6d6297\"","Wiki Manual":"\"f6dc8ca0bd888932ba3e1b48a06aaa12\"","Working Remotely (COVID-19)":"\"2095d3785cd7222d0df50fd2759ec89f\"","Working in Multiple Domains":"\"d6b86d1b9cbb38aba2fa75b1e6e660ec\"","Working in Schools":"\"1b3e8341ffeb4307f743ce1c6041b131\"","Working in schools (November)":"\"e5d3f0a8c7dd40640fb5c805e1c148bb\"","Working remotely with children and young people with anxiety and low mood":"\"e958e3029d4270882976c11d9a58bb38\"","Working with Behaviour Problems":"\"f3adcb8316941b213bb26c557f4e0dab\"","Working with Looked After Children":"\"2ae8125bef3632f0d0109ec554c50598\"","Working with Peer Difficulties":"\"e30297386ce01e77cbfb485339405dc2\"","Working with Your Client":"\"8b3195fba6ef54be512c2394ab4ce6f0\"","Working with Your Networks":"\"4dfd9b2cd8cb18f20baecbd7affe1eb8\"","Working with Your Team":"\"0af89e91f92bdacf1fb113977cf88f73\"","Working with carers of LAC children and trauma":"\"ac9ef20f83e82860aa0982d5acdeb106\"","Working with co-morbidity":"\"9289459b49976ab01fe67ce870bf02ab\"","Working with low mood":"\"334ca634bab71ecabb2358b4d82228df\"","Working with parents":"\"11b56bcccd67ebb43cbb9043b0c75441\"","Working with parents to support CYP's emotion regulation":"\"69d4666f031751a0d2cca06a262e3367\"","Working with schools":"\"66977e5d889fd37ce52512cbbabf964e\"","Working with sleep difficulties":"\"2b809837ff6f4123e61ab68fcc01985c\"","Working with/through parents (remotely)":"\"1a900163e83eae71be7ae96418b083d3\"","_GoogleDocsIcons_docs":"\"9d4fed4e0e53ef07414e690889b5f0df\"","_GoogleDocsIcons_sheets":"\"644ac0405d219c505fcce761df1a4d87\"","_GoogleDocsIcons_slides":"\"88ad487247d895b8d80e7212b448945f\"","alexis-brown-omeaHbEFlN4-unsplash.jpg":"\"0473f9de9c2bce5412d80ae0b52fb471\"","anastasia-petrova-xu2WYJek5AI-unsplash (1).jpg":"\"a2b6ff644fc4da159ac7ed7894f2184e\"","ap..png":"\"cfb395ca6e247254ab6bf238b7cec1e7\"","books pic 1.jpg":"\"25495fc4bc3c1134c9d4988920134859\"","broadcasting Pic.jpg":"\"b193f80ee8ec0ae9642d9c2ff56d3f8e\"","ian-dooley-3NCA3tbaE5I-unsplash.jpg":"\"5ca3a15bd2c42783316fb24403450ebd\"","luciano-de-sa-ObwMZBdEWdI-unsplash (1).jpg":"\"47697bcf07783c2974ddda912dcb6430\"","melissa-askew-tSlvoSZK77c-unsplash.jpg":"\"67e9de52594b7c926ae57b2ef03fea39\"","patrick-tomasso-Oaqk7qqNh_c-unsplash.jpg":"\"5cb6b2b550dd4fa6328ea9612f17c2db\""}
https://8y1wh49hn1.execute-api.eu-west-2.amazonaws.com/prod/
4s50tg1b4toisc43c4q42gsceq
eu-west-2:2756d3cb-8b8b-47a9-8248-595a9d254d91
wellbeingservice_public
eu-west-2
eu-west-2_3lsaUbCyk
[[Home]]
UA-9237856-2
G-J19L1608BP
Wellbeing and Emotional Support Team
[img width=150 [SiteIcon]]<br/>WEST 



<div class="tc-afc-above-story-logo">
[img width=160 [$:/_AFC/grey-wordmark.svg]]
</div>
<$reveal type="nomatch" state=<<folded-state>> text="hide" tag="div" retain="yes" animate="yes">
<div class="tc-xememex-tiddler-info tc-subtitle">
Bag: <$view tiddler="$:/state/federatial/xememex/tiddlers/bag" index=<<currentTiddler>>>(none)</$view>
</div>
</$reveal>
\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline


@font-face {
  font-display: swap;
  font-family: FormaDJRBanner;
  font-style: normal;
  font-weight: 300;
  src: url(/fonts/$:/_fonts/FormaDJRBanner-Light.woff) format("woff");
}

@font-face {
  font-display: swap;
  font-family: FormaDJRBanner;
  font-style: italic;
  font-weight: 300;
  src: url(/fonts/$:/_fonts/FormaDJRBanner-LightItalic.woff) format("woff");
}

@font-face {
  font-display: swap;
  font-family: FormaDJRBanner;
  font-style: normal;
  font-weight: 400;
  src: url(/fonts/$:/_fonts/FormaDJRBanner-Regular.woff) format("woff");
}

@font-face {
  font-display: swap;
  font-family: FormaDJRBanner;
  font-style: italic;
  font-weight: 400;
  src: url(/fonts/$:/_fonts/FormaDJRBanner-Italic.woff) format("woff");
}

@font-face {
  font-display: swap;
  font-family: FormaDJRBanner;
  font-style: normal;
  font-weight: 500;
  src: url(/fonts/$:/_fonts/FormaDJRBanner-Medium.woff) format("woff");
}

@font-face {
  font-display: swap;
  font-family: FormaDJRBanner;
  font-style: italic;
  font-weight: 500;
  src: url(/fonts/$:/_fonts/FormaDJRBanner-MediumItalic.woff) format("woff");
}

@font-face {
  font-display: swap;
  font-family: FormaDJRBanner;
  font-style: italic;
  font-weight: 700;
  src: url(/fonts/$:/_fonts/FormaDJRBanner-BoldItalic.woff) format("woff");
}

@font-face {
  font-display: swap;
  font-family: Mulish;
  font-style: normal;
  font-weight: 400;
  src: url(/fonts/$:/_fonts/Mulish-Regular.woff) format("woff");
}

@font-face {
  font-display: swap;
  font-family: Mulish;
  font-style: italic;
  font-weight: 400;
  src: url(/fonts/$:/_fonts/Mulish-Italic.woff) format("woff");
}

@font-face {
  font-display: swap;
  font-family: Mulish;
  font-style: normal;
  font-weight: 700;
  src: url(/fonts/$:/_fonts/Mulish-Bold.woff) format("woff");
}

@font-face {
  font-display: swap;
  font-family: Mulish;
  font-style: italic;
  font-weight: 700;
  src: url(/fonts/$:/_fonts/Mulish-BoldItalic.woff) format("woff");
}

@font-face {
  font-display: swap;
  font-family: Mulish;
  font-style: normal;
  font-weight: 900;
  src: url(/fonts/$:/_fonts/Mulish-Black.woff) format("woff");
}

@font-face {
  font-display: swap;
  font-family: Mulish;
  font-style: italic;
  font-weight: 900;
  src: url(/fonts/$:/_fonts/Mulish-BlackItalic.woff) format("woff");
}

html body.tc-body {
font-family: "Mulish";
}

.tc-top-menu,
.tc-site-title,
.tc-site-subtitle,
h1, h2, h3, h4, h5, h6 {
font-family: "FormaDJRBanner";
letter-spacing: 0.09em;
font-weight: 600;
text-align: left;
}

h1 button, h2 button, h3 button, h4 button, h5 button, h6 button {
letter-spacing: 0.09em;
}

.tc-site-title {
font-weight: bold;
}

body .tc-titlebar h2 {
font-weight: 700;
}
\define image(title,width,height)
<$image source=<<__title__>> width=<<__width__>> height=<<__height__>>/>
\end
\define embed-video(code)
<$reveal state="$:/state/consent-banner/accepted" type="match" text="yes" tag="div">
<iframe width="560" height="315" src="https://www.youtube.com/embed/$code$" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
</$reveal>
<$reveal state="$:/state/consent-banner/accepted" type="nomatch" text="yes" tag="div">
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/$code$" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
</$reveal>
\end

<<embed-video KtCUr83XgyE>>
afc-white: #ffffff
afc-black: #222222
afc-green: #147BD1
afc-pale-green: #6cbeaf
afc-blue: #155dac
afc-purple: #925195
afc-orange: #eb7837
afc-brown: #786e65
afc-light-grey: #e2e2e2
afc-very-light-grey: #f2f2f2
afc-mid: rgba(232, 232, 232, 0.84)
top-menu-background: <<colour afc-green>>
top-menu-foreground: <<colour afc-white>>
page-footer-background: <<colour afc-green>>
page-footer-foreground: <<colour afc-white>>
alert-background: <<color afc-white>>
alert-border: #147BD1
alert-highlight: #881122
alert-muted-foreground: #147BD1
background: #fff
blockquote-bar: <<colour muted-foreground>>
button-background: 
button-foreground: 
button-border: 
code-background: #f7f7f9
code-border: #e1e1e8
code-foreground: #dd1144
dirty-indicator: #ff0000
download-background: #34c734
download-foreground: <<colour background>>
dragger-background: <<colour foreground>>
dragger-foreground: <<colour background>>
dropdown-background: <<colour background>>
dropdown-border: <<colour muted-foreground>>
dropdown-tab-background-selected: #fff
dropdown-tab-background: #ececec
dropzone-background: rgba(0,200,0,0.7)
external-link-background-hover: inherit
external-link-background-visited: inherit
external-link-background: inherit
external-link-foreground-hover: inherit
external-link-foreground-visited: #0000aa
external-link-foreground: #0000ee
foreground: <<color afc-black>>
message-background: #ecf2ff
message-border: #cfd6e6
message-foreground: #547599
modal-backdrop: <<colour foreground>>
modal-background: <<colour background>>
modal-border: #999999
modal-footer-background: #f5f5f5
modal-footer-border: #dddddd
modal-header-border: #eeeeee
muted-foreground: #bbb
notification-background: #ffffdd
notification-border: #999999
page-background: <<color afc-light-grey>>
pre-background: #f5f5f5
pre-border: #cccccc
primary: <<colour afc-purple>>
sidebar-button-foreground: <<colour foreground>>
sidebar-controls-foreground-hover: #000000
sidebar-controls-foreground: #aaaaaa
sidebar-foreground-shadow: rgba(255,255,255, 0.8)
sidebar-foreground: #acacac
sidebar-muted-foreground-hover: #444444
sidebar-muted-foreground: #c0c0c0
sidebar-tab-background-selected: #f4f4f4
sidebar-tab-background: #e0e0e0
sidebar-tab-border-selected: <<colour tab-border-selected>>
sidebar-tab-border: <<colour tab-border>>
sidebar-tab-divider: #e4e4e4
sidebar-tab-foreground-selected: 
sidebar-tab-foreground: <<colour tab-foreground>>
sidebar-tiddler-link-foreground-hover: #444444
sidebar-tiddler-link-foreground: #999999
site-title-foreground: <<colour tiddler-title-foreground>>
static-alert-foreground: #aaaaaa
tab-background-selected: #ffffff
tab-background: #d8d8d8
tab-border-selected: #d8d8d8
tab-border: #cccccc
tab-divider: #d8d8d8
tab-foreground-selected: <<colour tab-foreground>>
tab-foreground: #666666
table-border: #dddddd
table-footer-background: #a8a8a8
table-header-background: #f0f0f0
tag-background: #147BD1
tag-foreground: #ffffff
tiddler-background: <<colour background>>
tiddler-border: <<colour background>>
tiddler-controls-foreground-hover: #888888
tiddler-controls-foreground-selected: #444444
tiddler-controls-foreground: #cccccc
tiddler-editor-background: #f8f8f8
tiddler-editor-border-image: #ffffff
tiddler-editor-border: #cccccc
tiddler-editor-fields-even: #e0e8e0
tiddler-editor-fields-odd: #f0f4f0
tiddler-info-background: #f8f8f8
tiddler-info-border: #dddddd
tiddler-info-tab-background: #f8f8f8
tiddler-link-background: <<colour background>>
tiddler-link-foreground: <<colour primary>>
tiddler-subtitle-foreground: #c0c0c0
tiddler-title-foreground: #182955
toolbar-new-button: 
toolbar-options-button: 
toolbar-save-button: 
toolbar-info-button: 
toolbar-edit-button: 
toolbar-close-button: 
toolbar-delete-button: 
toolbar-cancel-button: 
toolbar-done-button: 
untagged-background: #999999
very-muted-foreground: #888888
<$action-setfield $tiddler="$:/state/showeditpreview" $value="yes"/>
<$action-setfield $tiddler="$:/state/editpreviewtype" $value="$:/core/ui/EditTemplate/body/preview/output"/>
/* ------------------------------------------
PURE CSS SPEECH BUBBLES
by Nicolas Gallagher
- http://nicolasgallagher.com/pure-css-speech-bubbles/

http://nicolasgallagher.com
http://twitter.com/necolas

Created: 02 March 2010
Version: 1.2 (03 March 2011)

Dual licensed under MIT and GNU GPLv2 Nicolas Gallagher
------------------------------------------ */

/* NOTE: Some declarations use longhand notation so that it can be clearly
explained what specific properties or values do and what their relationship
is to other properties or values in creating the effect */

/* ============================================================================================================================
== BUBBLE WITH AN ISOCELES TRIANGLE
** ============================================================================================================================ */

/* THE SPEECH BUBBLE
------------------------------------------------------------------------------------------------------------------------------- */

.bubbles-triangle-isosceles {
  position:relative;
  padding:15px;
  margin:1em 0 3em;
  color:#000;
  background:#f3961c; /* default background for browsers without gradient support */
  /* css3 */
  background:-webkit-gradient(linear, 0 0, 0 100%, from(#f9d835), to(#f3961c));
  background:-moz-linear-gradient(#f9d835, #f3961c);
  background:-o-linear-gradient(#f9d835, #f3961c);
  background:linear-gradient(#f9d835, #f3961c);
  -webkit-border-radius:10px;
  -moz-border-radius:10px;
  border-radius:10px;
}

/* Variant : for top positioned triangle
------------------------------------------ */

.bubbles-triangle-isosceles.bubbles-top {
  background:-webkit-gradient(linear, 0 0, 0 100%, from(#f3961c), to(#f9d835));
  background:-moz-linear-gradient(#f3961c, #f9d835);
  background:-o-linear-gradient(#f3961c, #f9d835);
  background:linear-gradient(#f3961c, #f9d835);
}

/* Variant : for left/right positioned triangle
------------------------------------------ */

.bubbles-triangle-isosceles.bubbles-left {
  margin-left:50px;
  background:#f3961c;
}

/* Variant : for right positioned triangle
------------------------------------------ */

.bubbles-triangle-isosceles.bubbles-right {
  margin-right:50px;
  background:#f3961c;
}

/* THE TRIANGLE
------------------------------------------------------------------------------------------------------------------------------- */

/* creates triangle */
.bubbles-triangle-isosceles:after {
  content:"";
  position:absolute;
  bottom:-15px; /* value = - border-top-width - border-bottom-width */
  left:50px; /* controls horizontal position */
  border-width:15px 15px 0; /* vary these values to change the angle of the vertex */
  border-style:solid;
  border-color:#f3961c transparent;
  /* reduce the damage in FF3.0 */
  display:block;
  width:0;
}

/* Variant : top
------------------------------------------ */

.bubbles-triangle-isosceles.bubbles-top:after {
  top:-15px; /* value = - border-top-width - border-bottom-width */
  right:50px; /* controls horizontal position */
  bottom:auto;
  left:auto;
  border-width:0 15px 15px; /* vary these values to change the angle of the vertex */
  border-color:#f3961c transparent;
}

/* Variant : left
------------------------------------------ */

.bubbles-triangle-isosceles.bubbles-left:after {
  top:16px; /* controls vertical position */
  left:-50px; /* value = - border-left-width - border-right-width */
  bottom:auto;
  border-width:10px 50px 10px 0;
  border-color:transparent #f3961c;
}

/* Variant : right
------------------------------------------ */

.bubbles-triangle-isosceles.bubbles-right:after {
  top:16px; /* controls vertical position */
  right:-50px; /* value = - border-left-width - border-right-width */
  bottom:auto;
  left:auto;
  border-width:10px 0 10px 50px;
  border-color:transparent #f3961c;
}


/* ============================================================================================================================
== BUBBLE WITH A RIGHT-ANGLED TRIANGLE
** ============================================================================================================================ */

/* THE SPEECH BUBBLE
------------------------------------------------------------------------------------------------------------------------------- */

.bubbles-triangle-right {
  position:relative;
  padding:15px;
  margin:1em 0 3em;
  color:#fff;
  background:#075698; /* default background for browsers without gradient support */
  /* css3 */
  background:-webkit-gradient(linear, 0 0, 0 100%, from(#2e88c4), to(#075698));
  background:-moz-linear-gradient(#2e88c4, #075698);
  background:-o-linear-gradient(#2e88c4, #075698);
  background:linear-gradient(#2e88c4, #075698);
  -webkit-border-radius:10px;
  -moz-border-radius:10px;
  border-radius:10px;
}

/* Variant : for top positioned triangle
------------------------------------------ */

.bubbles-triangle-right.bubbles-top {
  background:-webkit-gradient(linear, 0 0, 0 100%, from(#075698), to(#2e88c4));
  background:-moz-linear-gradient(#075698, #2e88c4);
  background:-o-linear-gradient(#075698, #2e88c4);
  background:linear-gradient(#075698, #2e88c4);
}

/* Variant : for left positioned triangle
------------------------------------------ */

.bubbles-triangle-right.bubbles-left {
  margin-left:40px;
  background:#075698;
}

/* Variant : for right positioned triangle
------------------------------------------ */

.bubbles-triangle-right.bubbles-right {
  margin-right:40px;
  background:#075698;
}

/* THE TRIANGLE
------------------------------------------------------------------------------------------------------------------------------- */

.bubbles-triangle-right:after {
  content:"";
  position:absolute;
  bottom:-20px; /* value = - border-top-width - border-bottom-width */
  left:50px; /* controls horizontal position */
  border-width:20px 0 0 20px; /* vary these values to change the angle of the vertex */
  border-style:solid;
  border-color:#075698 transparent;
  /* reduce the damage in FF3.0 */
  display:block;
  width:0;
}

/* Variant : top
------------------------------------------ */

.bubbles-triangle-right.bubbles-top:after {
  top:-20px; /* value = - border-top-width - border-bottom-width */
  right:50px; /* controls horizontal position */
  bottom:auto;
  left:auto;
  border-width:20px 20px 0 0; /* vary these values to change the angle of the vertex */
  border-color:transparent #075698;
}

/* Variant : left
------------------------------------------ */

.bubbles-triangle-right.bubbles-left:after {
  top:16px;
  left:-40px; /* value = - border-left-width - border-right-width */
  bottom:auto;
  border-width:15px 40px 0 0; /* vary these values to change the angle of the vertex */
  border-color:transparent #075698;
}

/* Variant : right
------------------------------------------ */

.bubbles-triangle-right.bubbles-right:after {
  top:16px;
  right:-40px; /* value = - border-left-width - border-right-width */
  bottom:auto;
  left:auto;
  border-width:15px 0 0 40px; /* vary these values to change the angle of the vertex */
  border-color:transparent #075698 ;
}


/* ============================================================================================================================
== BUBBLE WITH AN OBTUSE TRIANGLE
** ============================================================================================================================ */

/* THE SPEECH BUBBLE
------------------------------------------------------------------------------------------------------------------------------- */

.bubbles-triangle-obtuse {
  position:relative;
  padding:15px;
  margin:1em 0 3em;
  color:#fff;
  background:#c81e2b;
  /* css3 */
  background:-webkit-gradient(linear, 0 0, 0 100%, from(#f04349), to(#c81e2b));
  background:-moz-linear-gradient(#f04349, #c81e2b);
  background:-o-linear-gradient(#f04349, #c81e2b);
  background:linear-gradient(#f04349, #c81e2b);
  -webkit-border-radius:10px;
  -moz-border-radius:10px;
  border-radius:10px;
}

/* Variant : for top positioned triangle
------------------------------------------ */

.bubbles-triangle-obtuse.bubbles-top {
  background:-webkit-gradient(linear, 0 0, 0 100%, from(#c81e2b), to(#f04349));
  background:-moz-linear-gradient(#c81e2b, #f04349);
  background:-o-linear-gradient(#c81e2b, #f04349);
  background:linear-gradient(#c81e2b, #f04349);
}

/* Variant : for left positioned triangle
------------------------------------------ */

.bubbles-triangle-obtuse.bubbles-left {
  margin-left:50px;
  background:#c81e2b;
}

/* Variant : for right positioned triangle
------------------------------------------ */

.bubbles-triangle-obtuse.bubbles-right {
  margin-right:50px;
  background:#c81e2b;
}

/* THE TRIANGLE
------------------------------------------------------------------------------------------------------------------------------- */

/* creates the wider right-angled triangle */
.bubbles-triangle-obtuse:before {
  content:"";
  position:absolute;
  bottom:-20px; /* value = - border-top-width - border-bottom-width */
  left:60px; /* controls horizontal position */
  border:0;
  border-right-width:30px; /* vary this value to change the angle of the vertex */
  border-bottom-width:20px; /* vary this value to change the height of the triangle. must be equal to the corresponding value in :after */
  border-style:solid;
  border-color:transparent #c81e2b;
  /* reduce the damage in FF3.0 */
  display:block;
  width:0;
}

/* creates the narrower right-angled triangle */
.bubbles-triangle-obtuse:after {
  content:"";
  position:absolute;
  bottom:-20px; /* value = - border-top-width - border-bottom-width */
  left:80px; /* value = (:before's left) + (:before's border-right/left-width)  - (:after's border-right/left-width) */
  border:0;
  border-right-width:10px; /* vary this value to change the angle of the vertex */
  border-bottom-width:20px; /* vary this value to change the height of the triangle. must be equal to the corresponding value in :before */
  border-style:solid;
  border-color:transparent #fff;
  /* reduce the damage in FF3.0 */
  display:block;
  width:0;
}

/* Variant : top
------------------------------------------ */

.bubbles-triangle-obtuse.bubbles-top:before {
  top:-20px; /* value = - border-top-width - border-bottom-width */
  bottom:auto;
  left:auto;
  right:60px; /* controls horizontal position */
  border:0;
  border-left-width:30px; /* vary this value to change the width of the triangle */
  border-top-width:20px; /* vary this value to change the height of the triangle. must be equal to the corresponding value in :after */
  border-color:transparent #c81e2b;
}

.bubbles-triangle-obtuse.bubbles-top:after {
  top:-20px; /* value = - border-top-width - border-bottom-width */
  bottom:auto;
  left:auto;
  right:80px; /* value = (:before's right) + (:before's border-right/left-width)  - (:after's border-right/left-width) */
  border-width:0;
  border-left-width:10px; /* vary this value to change the width of the triangle */
  border-top-width:20px; /* vary this value to change the height of the triangle. must be equal to the corresponding value in :before */
  border-color:transparent #fff;
}

/* Variant : left
------------------------------------------ */

.bubbles-triangle-obtuse.bubbles-left:before {
  top:15px; /* controls vertical position */
  bottom:auto;
  left:-50px; /* value = - border-left-width - border-right-width */
  border:0;
  border-bottom-width:30px; /* vary this value to change the height of the triangle */
  border-left-width:50px; /* vary this value to change the width of the triangle. must be equal to the corresponding value in :after */
  border-color:#c81e2b transparent;
}

.bubbles-triangle-obtuse.bubbles-left:after {
  top:35px; /* value = (:before's top) + (:before's border-top/bottom-width)  - (:after's border-top/bottom-width) */
  bottom:auto;
  left:-50px; /* value = - border-left-width - border-right-width */
  border:0;
  border-bottom-width:10px; /* vary this value to change the height of the triangle */
  border-left-width:50px; /* vary this value to change the width of the triangle. must be equal to the corresponding value in :before */
  border-color:#fff transparent;
}

/* Variant : right
------------------------------------------ */

.bubbles-triangle-obtuse.bubbles-right:before {
  top:15px; /* controls vertical position */
  bottom:auto;
  left:auto;
  right:-50px; /* value = - border-left-width - border-right-width */
  border:0;
  border-bottom-width:30px; /* vary this value to change the height of the triangle */
  border-right-width:50px; /* vary this value to change the width of the triangle. must be equal to the corresponding value in :after */
  border-color:#c81e2b transparent;
}

.bubbles-triangle-obtuse.bubbles-right:after {
  top:35px; /* value = (:before's top) + (:before's border-top/bottom-width)  - (:after's border-top/bottom-width) */
  bottom:auto;
  right:-50px; /* value = - border-left-width - border-right-width */
  left:auto;
  border:0;
  border-bottom-width:10px; /* vary this value to change the height of the triangle */
  border-right-width:50px; /* vary this value to change the width of the triangle. must be equal to the corresponding value in :before */
  border-color:#fff transparent;
}


/* ============================================================================================================================
== BUBBLE WITH A BORDER AND TRIANGLE
** ============================================================================================================================ */

/* THE SPEECH BUBBLE
------------------------------------------------------------------------------------------------------------------------------- */

.bubbles-triangle-border {
  position:relative;
  padding:15px;
  margin:1em 0 3em;
  border:5px solid #5a8f00;
  color:#333;
  background:#fff;
  /* css3 */
  -webkit-border-radius:10px;
  -moz-border-radius:10px;
  border-radius:10px;
}

/* Variant : for left positioned triangle
------------------------------------------ */

.bubbles-triangle-border.bubbles-left {
  margin-left:30px;
}

/* Variant : for right positioned triangle
------------------------------------------ */

.bubbles-triangle-border.bubbles-right {
  margin-right:30px;
}

/* THE TRIANGLE
------------------------------------------------------------------------------------------------------------------------------- */

.bubbles-triangle-border:before {
  content:"";
  position:absolute;
  bottom:-20px; /* value = - border-top-width - border-bottom-width */
  left:40px; /* controls horizontal position */
  border-width:20px 20px 0;
  border-style:solid;
  border-color:#5a8f00 transparent;
  /* reduce the damage in FF3.0 */
  display:block;
  width:0;
}

/* creates the smaller  triangle */
.bubbles-triangle-border:after {
  content:"";
  position:absolute;
  bottom:-13px; /* value = - border-top-width - border-bottom-width */
  left:47px; /* value = (:before left) + (:before border-left) - (:after border-left) */
  border-width:13px 13px 0;
  border-style:solid;
  border-color:#fff transparent;
  /* reduce the damage in FF3.0 */
  display:block;
  width:0;
}

/* Variant : top
------------------------------------------ */

/* creates the larger triangle */
.bubbles-triangle-border.bubbles-top:before {
  top:-20px; /* value = - border-top-width - border-bottom-width */
  bottom:auto;
  left:auto;
  right:40px; /* controls horizontal position */
  border-width:0 20px 20px;
}

/* creates the smaller  triangle */
.bubbles-triangle-border.bubbles-top:after {
  top:-13px; /* value = - border-top-width - border-bottom-width */
  bottom:auto;
  left:auto;
  right:47px; /* value = (:before right) + (:before border-right) - (:after border-right) */
  border-width:0 13px 13px;
}

/* Variant : left
------------------------------------------ */

/* creates the larger triangle */
.bubbles-triangle-border.bubbles-left:before {
  top:10px; /* controls vertical position */
  bottom:auto;
  left:-30px; /* value = - border-left-width - border-right-width */
  border-width:15px 30px 15px 0;
  border-color:transparent #5a8f00;
}

/* creates the smaller  triangle */
.bubbles-triangle-border.bubbles-left:after {
  top:16px; /* value = (:before top) + (:before border-top) - (:after border-top) */
  bottom:auto;
  left:-21px; /* value = - border-left-width - border-right-width */
  border-width:9px 21px 9px 0;
  border-color:transparent #fff;
}

/* Variant : right
------------------------------------------ */

/* creates the larger triangle */
.bubbles-triangle-border.bubbles-right:before {
  top:10px; /* controls vertical position */
  bottom:auto;
  left:auto;
  right:-30px; /* value = - border-left-width - border-right-width */
  border-width:15px 0 15px 30px;
  border-color:transparent #5a8f00;
}

/* creates the smaller  triangle */
.bubbles-triangle-border.bubbles-right:after {
  top:16px; /* value = (:before top) + (:before border-top) - (:after border-top) */
  bottom:auto;
  left:auto;
  right:-21px; /* value = - border-left-width - border-right-width */
  border-width:9px 0 9px 21px;
  border-color:transparent #fff;
}


/* ============================================================================================================================
== SPEECH BUBBLE ICON
** ============================================================================================================================ */

.bubbles-example-commentheading {
  position:relative;
  padding:0;
  color:#b513af;
}

/* creates the rectangle */
.bubbles-example-commentheading:before {
  content:"";
  position:absolute;
  top:9px;
  left:-25px;
  width:15px;
  height:10px;
  background:#b513af;
  /* css3 */
  -webkit-border-radius:3px;
  -moz-border-radius:3px;
  border-radius:3px;
}

/* creates the triangle */
.bubbles-example-commentheading:after {
  content:"";
  position:absolute;
  top:15px;
  left:-19px;
  border:4px solid transparent;
  border-left-color:#b513af;
  /* reduce the damage in FF3.0 */
  display:block;
  width:0;
}


/* ============================================================================================================================
== BLOCKQUOTE WITH RIGHT-ANGLED TRIANGLE
** ============================================================================================================================ */

.bubbles-example-right {
  position:relative;
  padding:15px 30px;
  margin:0;
  color:#fff;
  background:#5a8f00; /* default background for browsers without gradient support */
  /* css3 */
  background:-webkit-gradient(linear, 0 0, 0 100%, from(#b8db29), to(#5a8f00));
  background:-moz-linear-gradient(#b8db29, #5a8f00);
  background:-o-linear-gradient(#b8db29, #5a8f00);
  background:linear-gradient(#b8db29, #5a8f00);
  -webkit-border-radius:10px;
  -moz-border-radius:10px;
  border-radius:10px;
}

/* display of quote author (alternatively use a class on the element following the blockquote) */
.example-right + p {margin:15px 0 2em 85px; font-style:italic;}

/* creates the triangle */
.bubbles-example-right:after {
  content:"";
  position:absolute;
  bottom:-50px;
  left:50px;
  border-width:0 20px 50px 0px;
  border-style:solid;
  border-color:transparent #5a8f00;
  /* reduce the damage in FF3.0 */
  display:block;
  width:0;
}


/* ============================================================================================================================
== BLOCKQUOTE WITH OBTUSE TRIANGLE
** ============================================================================================================================ */

.bubbles-example-obtuse {
  position:relative;
  padding:15px 30px;
  margin:0;
  color:#000;
  background:#f3961c; /* default background for browsers without gradient support */
  /* css3 */
  background:-webkit-gradient(linear, 0 0, 0 100%, from(#f9d835), to(#f3961c));
  background:-moz-linear-gradient(#f9d835, #f3961c);
  background:-o-linear-gradient(#f9d835, #f3961c);
  background:linear-gradient(#f9d835, #f3961c);
  /* Using longhand to avoid inconsistencies between Safari 4 and Chrome 4 */
  -webkit-border-top-left-radius:25px 50px;
  -webkit-border-top-right-radius:25px 50px;
  -webkit-border-bottom-right-radius:25px 50px;
  -webkit-border-bottom-left-radius:25px 50px;
  -moz-border-radius:25px / 50px;
  border-radius:25px / 50px;
}

/* display of quote author (alternatively use a class on the element following the blockquote) */
.example-obtuse + p {margin:10px 150px 2em 0; text-align:right; font-style:italic;}

/* creates the larger triangle */
.bubbles-example-obtuse:before {
  content:"";
  position:absolute;
  bottom:-30px;
  right:80px;
  border-width:0 0 30px 50px;
  border-style:solid;
  border-color:transparent #f3961c;
  /* reduce the damage in FF3.0 */
  display:block;
  width:0;
}

/* creates the smaller triangle */
.bubbles-example-obtuse:after {
  content:"";
  position:absolute;
  bottom:-30px;
  right:110px;
  border-width:0 0 30px 20px;
  border-style:solid;
  border-color:transparent #fff;
  /* reduce the damage in FF3.0 */
  display:block;
  width:0;
}


/* ============================================================================================================================
== TWITTER
** ============================================================================================================================ */

.bubbles-example-twitter {
  position:relative;
  padding:15px;
  margin:100px 0 0.5em;
  color:#333;
  background:#eee;
  /* css3 */
  -webkit-border-radius:10px;
  -moz-border-radius:10px;
  border-radius:10px;
}

.bubbles-example-twitter p {font-size:28px; line-height:1.25em;}

/* this isn't necessary, just saves me having to edit the HTML of the demo */
.bubbles-example-twitter:before {
  content:url(twitter-logo.gif);
  position:absolute;
  top:-60px;
  left:0;
  width:155px;
  height:36px;
  /* reduce the damage in FF3.0 */
  display:block;
}

/* creates the triangle */
.bubbles-example-twitter:after {
  content:"";
  position:absolute;
  top:-30px;
  left:50px;
  border:15px solid transparent;
  border-bottom-color:#eee;
  /* reduce the damage in FF3.0 */
  display:block;
  width:0;
}

/* display of quote author (alternatively use a class on the element following the blockquote) */
.bubbles-example-twitter + p {padding-left:15px; font:14px Arial, sans-serif;}


/* ============================================================================================================================
== NUMBER
** ============================================================================================================================ */

.bubbles-example-number {
  position:relative;
  width:200px;
  height:200px;
  margin:50px 0 200px;
  text-align:center;
  font:140px/200px Arial, sans-serif;
  color:#fff;
  background:#C91F2C;
}

/* creates the larger triangle */
.bubbles-example-number:before {
  content:"";
  position:absolute;
  bottom:-140px;
  right:0;
  border-width:0 0 140px 140px;
  border-style:solid;
  border-color:transparent #C91F2C;
}

/* creates the larger triangle */
.bubbles-example-number:after {
  content:"";
  position:absolute;
  bottom:-140px;
  right:85px;
  border-width:0 0 140px 55px;
  border-style:solid;
  border-color:transparent #fff;
}


/* ============================================================================================================================
== PINCHED SPEECH BUBBLE (more CSS3)
** ============================================================================================================================ */

.bubbles-pinched {
  position:relative;
  padding:15px;
  margin:50px 0 3em;
  text-align:center;
  color:#fff;
  background:#333;
  /* css3 */
  -webkit-border-radius:10px;
  -moz-border-radius:10px;
  border-radius:10px;
}

/* creates a rectangle of the colour wanted for the pointy bit */
.bubbles-pinched:before {
  content:"";
  position:absolute;
  top:-20px;
  left:50%;
  width:100px;
  height:20px;
  margin:0 0 0 -50px;
  background:#333;
}

/* creates a rounded rectangle to cover part of the rectangle generated above */
.bubbles-pinched:after {
  content:"";
  position:absolute;
  top:-20px;
  left:0;
  width:50%;
  height:20px;
  background:#fff;
  /* css3 */
  -webkit-border-bottom-right-radius:15px;
  -moz-border-radius-bottomright:15px;
  border-bottom-right-radius:15px;
}

/* creates the other rounded rectangle */
.bubbles-pinched > :first-child:before {
  content:"";
  position:absolute;
  top:-20px;
  right:0;
  width:50%;
  height:20px;
  background:#fff;
  /* css3 */
  -webkit-border-bottom-left-radius:15px;
  -moz-border-radius-bottomleft:15px;
  border-bottom-left-radius:15px;
}


/* ============================================================================================================================
== OVAL SPEECH BUBBLE (more CSS3)
** ============================================================================================================================ */

.bubbles-oval-speech {
  position:relative;
  width:270px;
  padding:50px 40px;
  margin:1em auto 50px;
  text-align:center;
  color:#fff;
  background:#5a8f00;
  /* css3 */
  background:-webkit-gradient(linear, 0 0, 0 100%, from(#b8db29), to(#5a8f00));
  background:-moz-linear-gradient(#b8db29, #5a8f00);
  background:-o-linear-gradient(#b8db29, #5a8f00);
  background:linear-gradient(#b8db29, #5a8f00);
  /*
  NOTES:
  -webkit-border-radius:220px 120px; // produces oval in safari 4 and chrome 4
  -webkit-border-radius:220px / 120px; // produces oval in chrome 4 (again!) but not supported in safari 4
  Not correct application of the current spec, therefore, using longhand to avoid future problems with webkit corrects this
  */
  -webkit-border-top-left-radius:220px 120px;
  -webkit-border-top-right-radius:220px 120px;
  -webkit-border-bottom-right-radius:220px 120px;
  -webkit-border-bottom-left-radius:220px 120px;
  -moz-border-radius:220px / 120px;
  border-radius:220px / 120px;
}

.bubbles-oval-speech p {font-size:1.25em;}

/* creates part of the curve */
.bubbles-oval-speech:before {
  content:"";
  position:absolute;
  z-index:-1;
  bottom:-30px;
  right:50%;
  height:30px;
  border-right:60px solid #5a8f00;
  background:#5a8f00; /* need this for webkit - bug in handling of border-radius */
  /* css3 */
  -webkit-border-bottom-right-radius:80px 50px;
  -moz-border-radius-bottomright:80px 50px;
  border-bottom-right-radius:80px 50px;
  /* using translate to avoid undesired appearance in CSS2.1-capabable but CSS3-incapable browsers */
  -webkit-transform:translate(0, -2px);
  -moz-transform:translate(0, -2px);
  -ms-transform:translate(0, -2px);
  -o-transform:translate(0, -2px);
  transform:translate(0, -2px);
}

/* creates part of the curved pointy bit */
.bubbles-oval-speech:after {
  content:"";
  position:absolute;
  z-index:-1;
  bottom:-30px;
  right:50%;
  width:60px;
  height:30px;
  background:#fff;
  /* css3 */
  -webkit-border-bottom-right-radius:40px 50px;
  -moz-border-radius-bottomright:40px 50px;
  border-bottom-right-radius:40px 50px;
  /* using translate to avoid undesired appearance in CSS2.1-capabable but CSS3-incapable browsers */
  -webkit-transform:translate(-30px, -2px);
  -moz-transform:translate(-30px, -2px);
  -ms-transform:translate(-30px, -2px);
  -o-transform:translate(-30px, -2px);
  transform:translate(-30px, -2px);
}


/* ============================================================================================================================
== OVAL THOUGHT BUBBLE (more CSS3)
** ============================================================================================================================ */

.bubbles-oval-thought {
  position:relative;
  width:270px;
  padding:50px 40px;
  margin:1em auto 80px;
  text-align:center;
  color:#fff;
  background:#075698;
  /* css3 */
  background:-webkit-gradient(linear, 0 0, 0 100%, from(#2e88c4), to(#075698));
  background:-moz-linear-gradient(#2e88c4, #075698);
  background:-o-linear-gradient(#2e88c4, #075698);
  background:linear-gradient(#2e88c4, #075698);
  /*
  NOTES:
  -webkit-border-radius:220px 120px; // produces oval in safari 4 and chrome 4
  -webkit-border-radius:220px / 120px; // produces oval in chrome 4 (again!) but not supported in safari 4
  Not correct application of the current spec, therefore, using longhand to avoid future problems with webkit corrects this
  */
  -webkit-border-top-left-radius:220px 120px;
  -webkit-border-top-right-radius:220px 120px;
  -webkit-border-bottom-right-radius:220px 120px;
  -webkit-border-bottom-left-radius:220px 120px;
  -moz-border-radius:220px / 120px;
  border-radius:220px / 120px;
}

.bubbles-oval-thought p {font-size:1.25em;}

/* creates the larger circle */
.bubbles-oval-thought:before {
  content:"";
  position:absolute;
  bottom:-20px;
  left:50px;
  width:30px;
  height:30px;
  background:#075698;
  /* css3 */
  -webkit-border-radius:30px;
  -moz-border-radius:30px;
  border-radius:30px;
}

/* creates the smaller circle */
.bubbles-oval-thought:after {
  content:"";
  position:absolute;
  bottom:-30px;
  left:30px;
  width:15px;
  height:15px;
  background:#075698;
  /* css3 */
  -webkit-border-radius:15px;
  -moz-border-radius:15px;
  border-radius:15px;
}

/* ============================================================================================================================
== OVAL SPEECH BUBBLE WITH QUOTATION MARKS (more CSS3)
** ============================================================================================================================ */

.bubbles-oval-quotes {
  position:relative;
  width:400px;
  height:350px;
  margin:2em auto 10px;
  color:#000;
  background:#ffed26;
  /* css3 */
  /*
  NOTES:
  -webkit-border-radius:Apx Bpx; // produces oval in safari 4 and chrome 4
  -webkit-border-radius:Apx / Bpx; // produces oval in chrome 4 (again!) but not supported in safari 4
  Not correct application of the current spec, therefore, using longhand to avoid future problems with webkit corrects this
  */
  -webkit-border-top-left-radius:400px 350px;
  -webkit-border-top-right-radius:400px 350px;
  -webkit-border-bottom-right-radius:400px 350px;
  -webkit-border-bottom-left-radius:400px 350px;
  -moz-border-radius:400px / 350px;
  border-radius:400px / 350px;
}

/* creates opening quotation mark */
.bubbles-oval-quotes:before {
  content:"\201C";
  position:absolute;
  z-index:1;
  top:20px;
  left:20px;
  font:80px/1 Georgia, serif;
  color:#ffed26;
}

/* creates closing quotation mark */
.bubbles-oval-quotes:after {
  content:"\201D";
  position:absolute;
  z-index:1;
  bottom:0;
  right:20px;
  font:80px/0.25 Georgia, serif;
  color:#ffed26;
}

.bubbles-oval-quotes p {
  width:250px;
  height:250px;
  padding:50px 0 0;
  margin:0 auto;
  text-align:center;
  font-size:35px;
}

/* creates smaller curve */
.bubbles-oval-quotes p:before {
  content:"";
  position:absolute;
  z-index:-1;
  bottom:-30px;
  right:55%;
  width:180px; /* wider than necessary to make it look a bit better in IE8 */
  height:60px;
  background:#fff; /* need this for webkit - bug in handling of border-radius */
  /* css3 */
  -webkit-border-bottom-right-radius:40px 50px;
  -moz-border-radius-bottomright:40px 50px;
  border-bottom-right-radius:40px 50px;
  /* using translate to avoid undesired appearance in CSS2.1-capabable but CSS3-incapable browsers */
  -webkit-transform:translate(-30px, -2px);
  -moz-transform:translate(-30px, -2px);
  -ms-transform:translate(-30px, -2px);
  -o-transform:translate(-30px, -2px);
  transform:translate(-30px, -2px);
}

/* creates larger curve */
.bubbles-oval-quotes p:after {
  content:"";
  position:absolute;
  z-index:-2;
  bottom:-30px;
  right:25%;
  height:80px;
  border-right:200px solid #ffed26;
  background:#ffed26; /* need this for webkit - bug in handling of border-radius */
  /* css3 */
  -webkit-border-bottom-right-radius:200px 100px;
  -moz-border-radius-bottomright:200px 100px;
  border-bottom-right-radius:200px 100px;
  /* using translate to avoid undesired appearance in CSS2.1-capabable but CSS3-incapable browsers */
  -webkit-transform:translate(0, -2px);
  -moz-transform:translate(0, -2px);
  -ms-transform:translate(0, -2px);
  -o-transform:translate(0, -2px);
  transform:translate(0, -2px);
  /* reduce the damage in FF3.0 */
  display:block;
  width:0;
}

.bubbles-oval-quotes + p {
  position:relative; /* part of the IE8 width compromise */
  width:150px;
  margin:0 0 2em;
  font-size:18px;
  font-weight:bold;
}


/* ============================================================================================================================
== RECTANGLE-BORDER STYLE WITH CURVE
** ============================================================================================================================ */

.bubbles-rectangle-speech-border {
  position:relative;
  padding:50px 15px;
  margin:1em 0 3em;
  border:10px solid #5a8f00;
  text-align:center;
  color:#333;
  background:#fff;
  /* css3 */
  -webkit-border-radius:20px;
  -moz-border-radius:20px;
  border-radius:20px;
}

/* creates larger curve */
.bubbles-rectangle-speech-border:before {
  content:"";
  position:absolute;
  z-index:10;
  bottom:-40px;
  left:50px;
  width:50px;
  height:30px;
  border-style:solid;
  border-width:0 10px 10px 0;
  border-color:#5a8f00;
  background:transparent;
  /* css3 */
  -webkit-border-bottom-right-radius:80px 50px;
  -moz-border-radius-bottomright:80px 50px;
  border-bottom-right-radius:80px 50px;
  /* reduce the damage in FF3.0 */
  display:block;
}

/* creates smaller curve */
.bubbles-rectangle-speech-border:after {
  content:"";
  position:absolute;
  z-index:10;
  bottom:-40px;
  left:50px;
  width:20px;
  height:30px;
  border-style:solid;
  border-width:0 10px 10px 0;
  border-color:#5a8f00;
  background:transparent;
  /* css3 */
  -webkit-border-bottom-right-radius:40px 50px;
  -moz-border-radius-bottomright:40px 50px;
  border-bottom-right-radius:40px 50px;
  /* reduce the damage in FF3.0 */
  display:block;
}

/* creates a small circle to produce a rounded point where the two curves meet */
.bubbles-rectangle-speech-border > :first-child:before {
  content:"";
  position:absolute;
  bottom:-40px;
  left:45px;
  width:10px;
  height:10px;
  background:#5a8f00;
  /* css3 */
  -webkit-border-radius:10px;
  -moz-border-radius:10px;
  border-radius:10px;
}

/* creates a white rectangle to cover part of the oval border*/
.bubbles-rectangle-speech-border > :first-child:after {
  content:"";
  position:absolute;
  bottom:-10px;
  left:76px;
  width:24px;
  height:15px;
  background:#fff;
}

/* ============================================================================================================================
== OVER SPEECH BUBBLE, EMPTY, WITH BORDER (more CSS3)
** ============================================================================================================================ */

.bubbles-oval-speech-border {
  position:relative;
  padding:70px 30px;
  margin:1em auto 60px;
  border:10px solid #f3961c;
  text-align:center;
  color:#333;
  background:#fff;
  /* css3 */
  /*
  NOTES:
  -webkit-border-radius:240px 140px; // produces oval in safari 4 and chrome 4
  -webkit-border-radius:240px / 140px; // produces oval in chrome 4 (again!) but not supported in safari 4
  Not correct application of the current spec, therefore, using longhand to avoid future problems with webkit corrects this
  */
  -webkit-border-top-left-radius:240px 140px;
  -webkit-border-top-right-radius:240px 140px;
  -webkit-border-bottom-right-radius:240px 140px;
  -webkit-border-bottom-left-radius:240px 140px;
  -moz-border-radius:240px / 140px;
  border-radius:240px / 140px;
}

/* creates larger curve */
.bubbles-oval-speech-border:before {
  content:"";
  position:absolute;
  z-index:2;
  bottom:-40px;
  right:50%;
  width:50px;
  height:30px;
  border-style:solid;
  border-width:0 10px 10px 0;
  border-color:#f3961c;
  margin-right:-10px;
  background:transparent;
  /* css3 */
  -webkit-border-bottom-right-radius:80px 50px;
  -moz-border-radius-bottomright:80px 50px;
  border-bottom-right-radius:80px 50px;
  /* reduce the damage in FF3.0 */
  display:block;
}

/* creates smaller curve */
.bubbles-oval-speech-border:after {
  content:"";
  position:absolute;
  z-index:2;
  bottom:-40px;
  right:50%;
  width:20px;
  height:31px;
  border-style:solid;
  border-width:0 10px 10px 0;
  border-color:#f3961c;
  margin-right:20px;
  background:transparent;
  /* css3 */
  -webkit-border-bottom-right-radius:40px 50px;
  -moz-border-radius-bottomright:40px 50px;
  border-bottom-right-radius:40px 50px;
  /* reduce the damage in FF3.0 */
  display:block;
}

/* creates a small circle to produce a rounded point where the two curves meet */
.bubbles-oval-speech-border > :first-child:before {
  content:"";
  position:absolute;
  z-index:1;
  bottom:-40px;
  right:50%;
  width:10px;
  height:10px;
  margin-right:45px;
  background:#f3961c;
  /* css3 */
  -webkit-border-radius:10px;
  -moz-border-radius:10px;
  border-radius:10px;
}

/* creates a white rectangle to cover part of the oval border*/
.bubbles-oval-speech-border > :first-child:after {
  content:"";
  position:absolute;
  z-index:1;
  bottom:-10px;
  right:50%;
  width:30px;
  height:15px;
  background:#fff;
}

/* ============================================================================================================================
== OVER THOUGHT BUBBLE, EMPTY, WITH BORDER (more CSS3)
** ============================================================================================================================ */

.bubbles-oval-thought-border {
  position:relative;
  padding:70px 30px;
  margin:1em auto 80px;
  border:10px solid #c81e2b;
  text-align:center;
  color:#333;
  background:#fff;
  /* css3 */
  /*
  NOTES:
  -webkit-border-radius:240px 140px; // produces oval in safari 4 and chrome 4
  -webkit-border-radius:240px / 140px; // produces oval in chrome 4 (again!) but not supported in safari 4
  Not correct application of the current spec, therefore, using longhand to avoid future problems with webkit corrects this
  */
  -webkit-border-top-left-radius:240px 140px;
  -webkit-border-top-right-radius:240px 140px;
  -webkit-border-bottom-right-radius:240px 140px;
  -webkit-border-bottom-left-radius:240px 140px;
  -moz-border-radius:240px / 140px;
  border-radius:240px / 140px;
}

/* creates the larger circle */
.bubbles-oval-thought-border:before {
  content:"";
  position:absolute;
  z-index:10;
  bottom:-40px;
  right:100px;
  width:50px;
  height:50px;
  border:10px solid #c81e2b;
  background:#fff;
  /* css3 */
  -webkit-border-radius:50px;
  -moz-border-radius:50px;
  border-radius:50px;
  /* reduce the damage in FF3.0 */
  display:block;
}

/* creates the smaller circle */
.bubbles-oval-thought-border:after {
  content:"";
  position:absolute;
  z-index:10;
  bottom:-60px;
  right:50px;
  width:25px;
  height:25px;
  border:10px solid #c81e2b;
  background:#fff;
  /* css3 */
  -webkit-border-radius:25px;
  -moz-border-radius:25px;
  border-radius:25px;
  /* reduce the damage in FF3.0 */
  display:block;
}
\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline

.tc-ext-doc-link {
color: <<color primary>>;
fill: <<color primary>>;
font-size: 1.2em;
font-weight: bold;
font-family: Mulish;
text-decoration: none;
border-radius: 4px;
padding: 0.3em;
margin: 0.3em -0.3em 0.3em -0.3em;
border: 2px solid transparent;
}

.tc-ext-doc-link svg {
vertical-align: middle;
height: 0.75em;
}

.tc-ext-doc-link img {
vertical-align: middle;
height: 1.3em;
}

.tc-ext-doc-link:hover {
color: <<color background>>;
fill: <<color background>>;
background: <<color primary>>;
border: 2px solid rgba(0,0,0,0.5);
}
\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline

@media (min-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {

<<if-sidebar """

	.tc-sidebar-scrollable {
		background: linear-gradient(to right,rgba(255,255,255,0) 0%,rgba(255,255,255,0.85) 42px,rgba(255,255,255,0.85) 100%);
	}

""">>

}

@media (max-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {

<<if-sidebar """

	.tc-sidebar-scrollable {
		background: linear-gradient(to right,rgba(255,255,255,0.85) 0%,rgba(255,255,255,0.85) 100%);
	}

""">>

}
\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline

html body.tc-body .tc-tiddler-frame.tc-tagged-HideEditButton .tc-btn-\%24\%3A\%2Fcore\%2Fui\%2FButtons\%2Fedit,
html body.tc-body .tc-tiddler-frame.tc-tagged-HideEditButton .tc-btn-\%24\%3A\%2Fcore\%2Fui\%2FButtons\%2Finfo,
html body.tc-body .tc-tiddler-frame.tc-tagged-HideEditButton .tc-btn-\%24\%3A\%2Fcore\%2Fui\%2FButtons\%2Fmore-tiddler-actions,
html body.tc-body .tc-tiddler-frame.tc-tagged-HideEditButton .tc-tags-wrapper,
html body.tc-body .tc-tiddler-frame.tc-tagged-HideEditButton .tc-tagged-by {
	display: none;
}

button.tc-tiddlylink, a.tc-tiddlylink {
    font-weight: bold;
}

.tc-afc-above-story-logo {
background: <<colour afc-light-purple>>;
margin: -0.5em -0.5em 1.5em -0.5em;
padding: 0.5em 0.5em 0.5em 0.5em;
border-radius: 0.25rem;
}

h1, h2, h3, h4, h5, h6 {
margin: 0.75em -0.25em 0.25em -0.25em;
padding: 0.25em 0.25em 0.25em 0.25em;
border-radius: 0.25rem;
color: <<colour afc-dark-blue>>;
}

h1 {
background: <<colour afc-solid-turquoise>>;
}
h2 {
background: <<colour afc-solid-purple>>;
color: <<colour afc-white>>;
}
h3 {
background: <<colour afc-solid-yellow>>;
}
h4 {
background: <<colour afc-solid-green>>;
}
h5 {
background: <<colour afc-solid-pink>>;
}

.tc-titlebar h2,
h1.tc-site-title {
background: none;
color: <<colour afc-dark-blue>>;
}

div.tc-thumbnail-caption {
background: <<colour afc-dark-blue>>;
}

\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline

.tc-topbar-right {
	top: 0;
	right: 0;
}

.tc-topbar-left {
	display: inline-block;
	top: 0;
	left: 0;
	width: 100%;
}

nav.tc-top-menu p {
	margin: 0;
}

nav.tc-top-menu > ul {
	position: relative;
	list-style-type: none;
	margin: 0;
    padding: 0 0 0 42px;
	text-transform: uppercase;
	background: <<colour top-menu-background>>;
	<<box-shadow "1px 1px 5px rgba(0, 0, 0, 0.3)">>
}

nav.tc-top-menu > ul > li {
	display: inline-block;
	margin: 0;
	padding: 0;
}

nav.tc-top-menu > ul > li > a,
nav.tc-top-menu > ul > li > button {
	display: block;
	font-weight: 700;
	color: <<colour top-menu-foreground>>;
	fill: <<colour top-menu-foreground>>;
	text-decoration: none;
	padding: 0.5em;
	margin: 0;
	background: none;
	border: none;
    cursor: pointer;
    text-transform: inherit;
    border-radius: 0;
    text-decoration: none;
}

nav.tc-top-menu > ul > li > a.tc-selected,
nav.tc-top-menu > ul > li > button.tc-selected {
	background: <<colour top-menu-foreground>>;
	color: <<colour top-menu-background>>;
	fill: <<colour top-menu-background>>;
}

nav.tc-top-menu > ul > li svg {
	width: 1em;
	height: 1em;
	fill: <<colour top-menu-foreground>>;
}

nav.tc-top-menu > ul > li > a:hover,
nav.tc-top-menu > ul > li > button:hover {
	background: rgba(0,0,0,0.25);
    border-radius: 0;
    text-decoration: none;
}

nav.tc-top-menu .tc-drop-down {
	max-height: 70vh;
	overflow: auto;
}

nav.tc-top-menu .tc-drop-down a {
	text-decoration: none;
}

nav.tc-top-menu .tc-drop-down button {
	display: inline-block;
	width: auto;
}

nav.tc-top-menu .tc-drop-down ol {
	margin: 0;
}
<$list filter="[{$:/_AFC/SurveyBanner/URL}!is[blank]]" variable="ignore">
<a href={{$:/_AFC/SurveyBanner/URL}} target="_blank" class="tc-survey-banner">
<div class="tc-survey-banner-heading">
{{$:/core/images/plugin-generic-language}}
Help us improve
</div>
<div class="tc-survey-banner-body">
We are hoping to gather valuable feedback on your use and opinion of the Wiki Manuals. By sharing your thoughts and opinions, you will contribute directly to ongoing improvements. It will take no longer than 10 minutes of your time to complete.
</div>
</a>
</$list>
\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline macrocallblock

.tc-survey-banner {
background: <<colour afc-light-green>>;
color: <<colour afc-dark-blue>>;
fill: <<colour afc-dark-blue>>;
padding: 1em;
text-shadow: none;
border-radius: 8px;
line-height: 1.2;
text-decoration: none;
display: block;
margin-right: 1em;
}


.tc-survey-banner:hover {
background: <<colour afc-dark-blue>>;
color: <<colour afc-light-green>>;
fill: <<colour afc-light-green>>;
}

.tc-survey-banner-heading {
font-size: 2em;
font-weight:bold;
margin-bottom: 0.5em;
}

.tc-survey-banner-heading svg {
width: 1em;
height: 1em; 
vertical-align: text-bottom;
}
<hr/>
<$button class="tc-btn-invisible">
<$set name="tags" filter="[<currentTiddler>]">
<$action-sendmessage $message="tm-new-tiddler" tags=<<tags>>/>
Create new tiddler tagged '<$text text=<<currentTiddler>>/>'
</$set>
</$button>
\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline

.tc-tag-navigation-buttons {
	clear: both;
	display: flex;
	font-size: 1em;
	border: 1px solid #c1e1ea;
}

.tc-tag-navigation-button-previous,
.tc-tag-navigation-button-next {
	cursor: pointer;
	border: none;
	background: #c1e1ea;
	border-radius: 4px;
	padding: 5px; color: white;
}

.tc-tag-navigation-button-middle {
	flex: 1; font-size: 100%;

}

.tc-tag-navigation-body {
	padding: 0.5em;
	border-left: 1px solid #c1e1ea;
	border-right: 1px solid #c1e1ea;
}

.tc-tag-navigation-button-previous:hover {
  background-color:#94d2e3;
}

.tc-tag-navigation-button-next:hover {
  background-color:#94d2e3;
}
\define tag-navigation-buttons()
<div class="tc-tag-navigation-buttons">
<$list filter="[<__tag__>tagging[]allbefore<currentTiddler>limit[1]]" variable="ignore">
<$button class="tc-tag-navigation-button tc-tag-navigation-button-previous">
<$action-setfield $tiddler=<<state>> $value={{{ [<__tag__>tagging[]before<currentTiddler>] }}}/>
{{left}} previous

</$button>
</$list>
<$button class="tc-tag-navigation-button tc-tag-navigation-button-middle tc-btn-invisible">
<$action-navigate $to=<<__tag__>>/>
 (<$text text={{{ [<__tag__>tagging[]allbefore<currentTiddler>count[]add[1]] }}}/> of <$text text={{{ [<__tag__>tagging[]count[]] }}}/>)
</$button>

<$list filter="[<__tag__>tagging[]allafter<currentTiddler>limit[1]]" variable="ignore">
<$button class="tc-tag-navigation-button tc-tag-navigation-button-next">
<$action-setfield $tiddler=<<state>> $value={{{ [<__tag__>tagging[]after<currentTiddler>] }}}/>
next {{right}}
</$button>
</$list>
</div>
\end

\define tag-navigation(tag)
<div class="tc-tag-navigation">
<$set name="state" value=<<qualify "$:/state/tag-navigation">>>
<$set name="state" value={{{ [<state>addsuffix[/]addsuffix<__tag__>] }}}>
<$tiddler tiddler={{{ [<state>get[text]] ~[<__tag__>tagging[]first[]]  }}}>
<<tag-navigation-buttons>>
<div class="tc-tag-navigation-body">
<h1><$text text={{!!title}}/></h1>
<$transclude mode="block"/>
</div>
<<tag-navigation-buttons>>
</$tiddler>
</$set>
</$set>
</div>
\end
<textarea readonly="readonly" style="width:100%;height:10em;"><$text text={{!!text}}/></textarea>
<$button message="tm-login" class="tc-consent-button tc-btn-invisible">
Login
</$button>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 230 53" class="header__logo--desktop">
  <g class="logo-icon">
    <path fill="#FFDC16" d="M5.546 36.716 0 47.398 10.682 53l3.88-7.47c-3.716-2.032-6.885-5.052-9.016-8.814Zm4.562-8.843 2.322-.412c.71 4.12 3.251 7.47 6.639 9.337l6.01-11.589-6.803-13.099-8.168 15.763Z"></path>
    <path fill="#64C3D7" d="M34.23 26.5c-1.911-3.707-.49-8.293 3.197-10.215L28.986 0l-13.36 7.003 2.65 5.107 1.585-3.048 10.682 5.602-5.464 10.573L39.476 53l13.36-7.003-8.442-16.284c-3.688 1.95-8.25.494-10.163-3.213Z"></path>
    <path fill="#AFDCE6" d="m19.861 9.062-1.585 3.048 6.803 13.1 5.464-10.573L19.86 9.062Z"></path>
    <path fill="#645FA5" d="M44.394 29.713c3.688-1.922 5.136-6.508 3.196-10.216-1.912-3.707-6.475-5.162-10.163-3.212l6.967 13.428Z"></path>
    <path fill="#AAA0CD" d="M34.23 26.5c1.913 3.707 6.476 5.163 10.164 3.213l-6.967-13.429c-3.688 1.923-5.108 6.509-3.196 10.216Z"></path>
    <path fill="#ED73AA" d="m29.068 48.03-1.694-9.694c-2.978.412-5.846-.165-8.305-1.538l-4.508 8.733a22.757 22.757 0 0 0 14.507 2.499ZM2.814 29.164a23.297 23.297 0 0 0 2.732 7.551l4.562-8.842-7.294 1.29Z"></path>
    <path fill="#F0AFCB" d="m12.457 27.461-2.322.412-4.59 8.87a23.222 23.222 0 0 0 9.016 8.815l4.508-8.76c-3.36-1.895-5.901-5.218-6.611-9.337Z"></path>
  </g>
  <g class="logo-text">
   <path fill="#000" d="M81.957 38.336a.594.594 0 0 1-.546-.385l-2.022-6.123h-9.288l-1.967 6.123c-.082.193-.3.385-.546.385h-3.36c-.192 0-.328-.192-.274-.385l8.06-22.957c.081-.192.3-.385.546-.385h4.671c.246 0 .465.165.547.385L85.7 37.95c.055.165-.082.385-.273.385h-3.47Zm-3.66-9.941-3.58-10.82-3.496 10.82h7.076Zm9.152 9.941c-.192 0-.41-.192-.41-.412l.164-7.8-.137-8.841c0-.193.191-.413.41-.413h3.142c.19 0 .41.193.41.412l-.055 2.142c1.12-1.62 3.06-2.938 5.655-2.938 3.633 0 5.901 2.444 5.901 6.838v3.597l.136 7.003c0 .192-.191.412-.409.412h-3.36c-.192 0-.41-.192-.41-.412l.136-7.003v-3.487c0-2.472-1.338-3.762-3.196-3.762-2.05 0-3.934 1.73-4.29 5.354v1.895l.055 7.003c0 .192-.19.412-.41.412H87.45Zm18.194 0c-.191 0-.41-.192-.41-.412l.164-7.8-.136-8.841c0-.193.191-.413.409-.413h3.142c.191 0 .41.193.41.412l-.055 2.142c1.12-1.62 3.06-2.938 5.655-2.938 3.634 0 5.901 2.444 5.901 6.838v3.597l.137 7.003c0 .192-.191.412-.41.412h-3.333c-.191 0-.41-.192-.41-.412l.137-7.003v-3.487c0-2.472-1.339-3.762-3.196-3.762-2.049 0-3.934 1.73-4.289 5.354v1.895l.054 7.003c0 .192-.191.412-.41.412h-3.36Zm30.188 0c-.191 0-.41-.192-.41-.412l.055-1.977c-1.202 1.702-3.005 2.718-5.355 2.718-4.781 0-7.349-3.927-7.349-9.007 0-5.053 2.787-9.117 7.431-9.117 2.268 0 4.043.879 5.218 2.581l-.082-1.84c0-.192.191-.412.41-.412h3.333c.191 0 .41.193.41.412l-.164 8.266.164 8.376c0 .192-.192.412-.41.412h-3.251Zm-4.562-2.527c2.732 0 4.289-2.032 4.316-6.068.027-4.037-1.475-6.262-4.234-6.29-2.924-.027-4.372 2.225-4.372 5.96-.027 4.064 1.421 6.398 4.29 6.398Zm17.593 2.527c-.191 0-.41-.192-.41-.412l.273-11.451-.273-11.452c0-.192.192-.412.41-.412h14.452c.191 0 .41.193.41.412v2.444c0 .193-.192.412-.41.412h-10.545l-.192 7.305h10.245c.191 0 .41.192.41.412v2.444c0 .192-.191.412-.41.412h-10.245l.192 9.474c0 .192-.192.412-.41.412h-3.497Zm17.129 0c-.191 0-.41-.192-.41-.412l.164-8.403-.164-8.239c0-.192.192-.412.41-.412h3.306c.191 0 .41.193.382.412l-.109 2.719c1.284-2.17 3.579-3.24 6.065-3.24.273 0 .546.027.765.055.218.027.41.247.41.466v2.362a.398.398 0 0 1-.41.385c-.191-.028-.465-.028-.738-.028-3.223 0-5.764 1.867-5.983 5.767l.082 8.156c0 .192-.191.412-.41.412h-3.36Zm26.828-5.959c.191 0 .382.192.327.412-.491 3.295-3.332 5.959-7.922 5.959-5.601 0-8.633-3.762-8.633-9.062 0-5.52 3.196-9.172 8.496-9.172 5.328 0 8.387 3.597 8.524 9.474 0 .192-.191.412-.41.412h-12.539c.164 3.734 1.693 5.492 4.589 5.492 2.076 0 3.47-.989 3.961-3.076a.521.521 0 0 1 .492-.412h3.115v-.027Zm-7.677-9.035c-2.431 0-3.879 1.483-4.316 4.311h8.414c-.164-2.279-1.475-4.311-4.098-4.311Zm16.391 15.406c-3.633 0-5.901-2.444-5.901-6.838v-3.598l-.109-7.002c0-.192.191-.412.41-.412h3.306c.191 0 .409.192.409.412l-.109 7.003V31.8c0 2.472 1.339 3.762 3.169 3.762 2.049 0 3.934-1.73 4.289-5.355v-1.895l-.027-7.002c0-.192.191-.412.41-.412h3.333c.191 0 .409.192.409.412l-.163 7.799.136 8.842c0 .193-.191.412-.41.412h-3.141c-.192 0-.41-.192-.41-.412l.109-2.142c-1.147 1.62-3.114 2.939-5.71 2.939Zm24.724-.412c-.191 0-.409-.192-.409-.412l.082-1.977c-1.175 1.702-3.006 2.718-5.328 2.718-4.781 0-7.349-3.927-7.349-9.007 0-5.053 2.787-9.117 7.431-9.117 2.268 0 4.043.879 5.191 2.554l-.082-8.046c0-.192.191-.412.41-.412h3.36c.191 0 .41.192.41.412l-.164 10.874.164 12.028c0 .193-.191.412-.41.412h-3.306v-.027Zm-4.535-2.5c2.705 0 4.289-2.031 4.317-6.068.027-4.064-1.475-6.344-4.235-6.371-2.923-.055-4.371 2.28-4.371 6.014-.027 4.064 1.421 6.426 4.289 6.426Z"></path>
  </g>
</svg>
<$vars 
	text-outer-line-1-nne="Managing"
	text-outer-line-2-nne="risk"
	text-outer-line-1-ene="Working in"
	text-outer-line-2-ene="multiple domains"
	text-outer-line-1-wnw="Individual keyworker"
	text-outer-line-2-wnw="relationship"
	text-outer-line-1-nnw="Scaffolding"
	text-outer-line-2-nnw="existing relationships"
	text-outer-line-1-ssw="Respect for local"
	text-outer-line-2-ssw="practice and expertise"
	text-outer-line-1-wsw="Keyworker well-"
	text-outer-line-2-wsw="connected to the team"
	text-outer-line-1-ese="Keyworker responsible"
	text-outer-line-2-ese="for integration"
	text-outer-line-1-sse="Respect"
	text-outer-line-2-sse="for evidence"
	text-inner-line-1-n="Working with"
	text-inner-line-2-n="your CLIENT"
	text-inner-line-small-1-n="(Active Planning, etc)"
	text-inner-line-1-e="Working with"
	text-inner-line-2-e="your"
	text-inner-line-3-e="NETWORKS"
	text-inner-line-small-1-e="(Addressing"
	text-inner-line-small-2-e="disintegration, etc)"
	text-inner-line-1-s="LEARNING"
	text-inner-line-2-s="at work"
	text-inner-line-small-1-s="(Wiki-manualization, etc)"
	text-inner-line-1-w="Working"
	text-inner-line-2-w="with"
	text-inner-line-3-w="your TEAM"
	text-inner-line-small-1-w="(Supervisory"
	text-inner-line-small-2-w="structures, etc)"
	text-middle="Mentalizing"
	link-ring-outer-nne="Managing Risk"
	link-ring-outer-ene="Working in multiple domains"
	link-ring-outer-wnw="KeyWorker"
	link-ring-outer-nnw="Scaffolding existing relationships"
	link-ring-outer-ssw="Respect local practice and expertise"
	link-ring-outer-wsw="Keyworker well-connected to wider team"
	link-ring-outer-ese="Addressing Dis-integration"
	link-ring-outer-sse="Respect for Evidence"
	link-ring-inner-n="Working with your CLIENT"
	link-ring-inner-e="Working with your NETWORKS"
	link-ring-inner-s="LEARNING at work"
	link-ring-inner-w="Working with your TEAM"
	link-middle="Mentalization"
	>
<$transclude tiddler="$:/_AMBITWheel/Template" mode="inline"/>
</$vars>
\define ambit-wheel(size,language:"English")
<$vars
	wheel-size="$size$"
>
<$transclude tiddler="$:/_AMBITWheel/$language$" mode="inline"/>
</$vars>
\end

\define ambit-wheel-iconic(ring,language:"English")
<$vars
	svg-classes="no-text faded unfade-$ring$"
	wheel-size="50px"
>
<$transclude tiddler="$:/_AMBITWheel/$language$" mode="inline"/>
</$vars>
\end
\define colour-outer-ring-background() #6D6D6D
\define colour-outer-ring-background-faded() #E8E8E8
\define colour-inner-ring-background() #302F30
\define colour-inner-ring-background-faded() #D8D8D8
\define colour-north-text() #F29898
\define colour-east-text() #7BD332
\define colour-south-text() #BCD8F4
\define colour-west-text() #D4D600
\define colour-middle-background() #FFFFFF
\define colour-middle-text() #4D4D4D

\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline macrocallblock

/* Variants */

.ambit-wheel.faded .path-ring-outer {
	fill: <<colour-outer-ring-background-faded>>;
}

.ambit-wheel.faded .path-ring-inner {
	fill: <<colour-inner-ring-background-faded>>;
}

/* Remove default link styling */

.ambit-wheel a.tc-tiddlylink-missing {
	font-style: normal;
}

.ambit-wheel a.tc-tiddlylink:hover {
	text-decoration: none;
}

/* Ring colours */

.ambit-wheel .path-ring-outer {
	fill: <<colour-outer-ring-background>>;
}

.ambit-wheel .ring-outer-nne:hover .path-ring-outer,
.ambit-wheel .ring-outer-nnw:hover .path-ring-outer,
.ambit-wheel.unfade-outer-nne .path-ring-outer-nne,
.ambit-wheel.unfade-outer-nnw .path-ring-outer-nnw {
	fill: <<colour-north-text>>;
}

.ambit-wheel .ring-outer-ene:hover .path-ring-outer,
.ambit-wheel .ring-outer-ese:hover .path-ring-outer,
.ambit-wheel.unfade-outer-ene .path-ring-outer-ene,
.ambit-wheel.unfade-outer-ese .path-ring-outer-ese {
	fill: <<colour-east-text>>;
}

.ambit-wheel .ring-outer-sse:hover .path-ring-outer,
.ambit-wheel .ring-outer-ssw:hover .path-ring-outer,
.ambit-wheel.unfade-outer-ssw .path-ring-outer-ssw,
.ambit-wheel.unfade-outer-sse .path-ring-outer-sse {
	fill: <<colour-south-text>>;
}

.ambit-wheel .ring-outer-wsw:hover .path-ring-outer,
.ambit-wheel .ring-outer-wnw:hover .path-ring-outer,
.ambit-wheel.unfade-outer-wnw .path-ring-outer-wnw,
.ambit-wheel.unfade-outer-wsw .path-ring-outer-wsw {
	fill: <<colour-west-text>>;
}

.ambit-wheel .ring-outer:hover .text-outer {
	fill: <<colour-outer-ring-background>>;
}

.ambit-wheel .path-ring-inner {
	fill: <<colour-inner-ring-background>>;
}

.ambit-wheel .ring-inner-n:hover .path-ring-inner,
.ambit-wheel.unfade-inner-n .path-ring-inner-n {
	fill: <<colour-north-text>>;
}

.ambit-wheel .ring-inner-e:hover .path-ring-inner,
.ambit-wheel.unfade-inner-e .path-ring-inner-e {
	fill: <<colour-east-text>>;
}

.ambit-wheel .ring-inner-s:hover .path-ring-inner,
.ambit-wheel.unfade-inner-s .path-ring-inner-s {
	fill: <<colour-south-text>>;
}

.ambit-wheel .ring-inner-w:hover .path-ring-inner,
.ambit-wheel.unfade-inner-w .path-ring-inner-w {
	fill: <<colour-west-text>>;
}

.ambit-wheel .ring-inner:hover .text-inner {
	fill: <<colour-inner-ring-background>>;
}

.ambit-wheel .text-outer-nne,
.ambit-wheel .text-outer-nnw,
.ambit-wheel .text-inner-n {
	fill: <<colour-north-text>>;
}

.ambit-wheel .text-outer-ene,
.ambit-wheel .text-outer-ese,
.ambit-wheel .text-inner-e {
	fill: <<colour-east-text>>;
}

.ambit-wheel .text-outer-sse,
.ambit-wheel .text-outer-ssw,
.ambit-wheel .text-inner-s {
	fill: <<colour-south-text>>;
}

.ambit-wheel .text-outer-wnw,
.ambit-wheel .text-outer-wsw,
.ambit-wheel .text-inner-w {
	fill: <<colour-west-text>>;
}

/* Middle colours */

.ambit-wheel .middle .circle-middle {
	fill: <<colour-middle-background>>;
}

.ambit-wheel .middle .text-middle {
	fill: <<colour-middle-text>>;
}

.ambit-wheel .middle:hover .circle-middle {
	fill: <<colour-middle-text>>;
}

.ambit-wheel .middle:hover .text-middle {
	fill: <<colour-middle-background>>;
}

/* Text styles */

.ambit-wheel .text-outer,
.ambit-wheel .text-inner-large,
.ambit-wheel .text-inner-small,
.ambit-wheel .text-middle {
	text-anchor: middle;
	font-family: Helvetica-Bold, Helvetica;
	font-size: 14px;
	font-weight: bold;
}

.ambit-wheel .text-inner-small {
	font-size: 10px;
}

.ambit-wheel .text-middle {
	font-size: 17px;
}

/* Variants */

.ambit-wheel.no-text {
	pointer-events: none;
}

.ambit-wheel.no-text text {
	display: none;
}
\define image-link-body(image,caption,width,height,color,background-color,icon)
<div class="tc-thumbnail-wrapper" style="width:$width$px;height:$height$px;">
<div class="tc-thumbnail-image">[img[$image$]]</div><div class="tc-thumbnail-icon" style="fill:$color$;color:$color$;">
$icon$
</div><div class="tc-thumbnail-caption">
$caption$
</div>
</div>
\end

\define image-link(link,image,caption,width,height,color,background-color,icon)
<$link to="""$link$"""><$macrocall $name="image-link-body" icon=<<__icon__>> color=<<__color__>> background-color=<<__background-color__>> image=<<__image__>> caption=<<__caption__>> width=<<__width__>> height=<<__height__>>/></$link>
\end

\define image-link-ext(link,image,caption,width,height,color,background-color,icon)
<a href="""$link$""" target="_blank" rel="noopener noreferrer"><$macrocall $name="image-link-body" icon=<<__icon__>> color=<<__color__>> background-color=<<__background-color__>> image=<<__image__>> caption=<<__caption__>> width=<<__width__>> height=<<__height__>>/></a>
\end

\define link-doc(caption,url,type:"docs")
<a href="""$url$""" class="tc-ext-doc-link" style="" target="_blank" rel="noopener noreferrer" title="Open in Google Docs">
{{$:/core/images/chevron-right}}<$image source={{{ [tag[$:/_GoogleDocsIcon]caption<__type__>] }}}/> $caption$
</a>
\end
\define link-pdf(caption,url,colour:"#55c6a7")
<a href="""$url$""" class="tc-btn-big-green" style="background-color:$colour$;" target="_blank" rel="noopener noreferrer">
{{$:/core/images/file}} $caption$
</a>
\end
\define embed-video(code)
<iframe width="560" height="315" src="https://www.youtube.com/embed/$code$" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
\end
<div class="tc-table-of-contents">
<<toc-selective-expandable 'HomeContents'>>
</div>
<div class="tc-table-of-contents">
<<toc-selective-expandable 'LocalPracticeContents'>>
</div>

<div class="tc-table-of-contents">
<<toc-selective-expandable 'UsingTheManualContents'>>
</div>

<div class="tc-table-of-contents">
<<toc-selective-expandable 'WellbeingTrainingContents'>>
</div>
show
show
yes
hide
hide
show
! Our use of cookies

We use necessary cookies to make our site work. We’d also like to set optional analytics to help us improve it. We won’t set optional cookies unless you enable them. Using this tool will set a cookie on your device to remember your preferences.

Anna Freud  provides this wiki platform for external teams who are responsible for the content, including cookies, that are added to their individual manuals. Guidance for teams on how to embed correctly has been added to the user guide.

For more detailed information about the cookies we use, see our <a href="https://www.annafreud.org/your-privacy/" class="tc-tiddlylink-external" target="_blank" rel="noopener noreferrer">Cookies page</a>.

---

!! Necessary cookies

Necessary cookies enable core functionality such as security, network management, and accessibility. You may disable these by changing your browser settings, but this may affect how the website functions.

---

!! Analytics cookies

We’d like to set non-essential cookies, such as Google Analytics, to help us to improve our website by collecting and reporting information on how you use it. The cookies collect information in a way that does not directly identify anyone. For more information on how these cookies work, please see our <a href="https://www.annafreud.org/your-privacy/" class="tc-tiddlylink-external" target="_blank" rel="noopener noreferrer">Cookies page</a>. If you are 16 or under, please ask a parent or carer for consent before accepting.

---
<$list filter={{$:/core/Filters/Drafts!!filter}} >
<div class="tc-menu-list-item">
<$link><$view field="title"/></$link>  <$list filter="[all[current]frombag{$:/plugins/federatial/xememex/config/recipe}]" variable="listItem"><span style="display:inline-block;background:#ff4;border:1px solid #cc0;color:black;padding:0 2px;border-radius:4px;font-size:0.8em;line-height:1.3;">local</span></$list>
</div>
</$list>
\define lingo-base() $:/language/ControlPanel/
\define config-title()
$:/config/PageControlButtons/Visibility/$(listItem)$
\end

<<lingo Basics/Version/Prompt>> <<version>>

<$set name="tv-config-toolbar-icons" value="yes">

<$set name="tv-config-toolbar-text" value="yes">

<$set name="tv-config-toolbar-class" value="">

<$list filter="[all[shadows+tiddlers]tag[$:/tags/PageControls]!has[draft.of]]" variable="listItem">

<div style="position:relative;" class={{{ [<listItem>encodeuricomponent[]addprefix[tc-btn-]] }}}>

<$checkbox tiddler=<<config-title>> field="text" checked="show" unchecked="hide" default="show"/> <$transclude tiddler=<<listItem>>/> <i class="tc-muted"><$transclude tiddler=<<listItem>> field="description"/></i>

</div>

</$list>

</$set>

</$set>

</$set>
<$transclude tiddler="$:/core" subtiddler="$:/core/ui/ViewTemplate/subtitle"/>
iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAACApJREFUeAHdmQmIlkUYxzfNq0NTo8PIlDKPyi4qi0yhErWkEoROhSxTISOVosuorCwUtKKiEC3tUCTNbonW9UpJ7c4y274kxDQ30y631H7/z31lvmlm3mu1b33gt+/MM8/zzMz7zvltRUX5S3OaeAO8CRthOcyHU+CAllb07l7YBLsNqurS23ieBwecNKFHY2ALmB2P0osN/S+ku8MBI73pydcQddb1XGeVryd/LDRoaUrrJ8IucHU60m312CxBfzA0SOlEq1dC1MnQc1XA7tGG2Pt+NHp7oFP2y6gM2P5D2bnQYORqWloLdid9+QK2s2PsP6O8MZS9jKCFO8HXWVP/DXbXgOa4tkblzXI7PZzyshZ1xm60K6+pMRq0LZqibe8vcPlIp8NSCyhLOZ9W/Qm+xkd6LXZaHH2ic0Jk63qO8jn+n/oOVP4TuBps6qZgo20xJJoOX4DpZ6arKWsUCrC/yw6iwkVgNtKVvjNFw/rHxNMOUzZyKy1xdTjS6QA0MkNrQ+eHlzPE2ycuHYn6G0SddT3vyVjz9YG4qrMsFsO5gUbqZWhvzyrNcawB10uVrm/WwPXld3agcWrgV3BIzsqm4+97AZNyxs7trh8xfI3TvO+Zu4aKiqsCdXxYD/Ezh9A+7uu89FMzRy51bEPWd4vUgSl4SwwWltaTOndTwEMLVDOYDn+ATn2boQDaw7+EHZBEtAashc4OY9WhRfhbR9k+VbUkuo6kvhFQGSiTjy5Jn8BkuAzi1onQQtsf//0mPahpGqwAX+d1bd0QKHf5aYTMhD6gQ5Ut+jHF5SfdUNt4X+QHEfRTiBqxzEhHuui5PFAW2YSea/C/BcxL0h2BmHdR5pW852V98aWgvby7UUs7I20ndQ3OI11wfha+gevqAv1a93Q94qaPyydW1xqLl8D1pUIXHg1/Ndbll1VXSby7AzEnUFavoittAXwNXh0o+zxQ5ouXRK/trsoT+yH0XkmzDWrx0VwbDyE/bXE+0bBdCPp1V78LHAaHwzGgbawTNIe0ou3uIlgCOn2adwBts7lFv7NNgyRfY0HAbmRMS7QmnQ6jYB6o8UnqNG10hqgx/G4mnUua4D0LzEpC6XcDtpembIlGiBa69wMxXW1Zi320Fl1OOrM0xXM+uCqxdb9jpymiHcEui/LdKMsq2mVmQNIfU7/HVi9BUyuz6LweNT70fAc7HTklGro+2/ZFi3x/zsTdt+DZ9WrN0Y6VSeJ+xVFltXCjFT00BY60bLNmtSDrF+MdYHfazr+WpZLeOP0dE3wb5a45HZoyx+NTn3I7wbaA3Wk7PyxNpUdgvDEm6AbKz/AEDS2YXT0+WdQaBRri60DtsTtt5nWXSDz9no4Jpjd+EvjkeQrMys30xT6nDPo+Rj3fk95k5M06o7RGZqycg0VoldVR9pKYKA9QHlVqP2+J8U1T/JZVz1LyOoTZdZr5K0IVaEitiglwWyhAXdnNgRhTEvgnMennqeN1jz56CTofNPFVMCDGeY7P0dL3CsTRC84rhxKgAFGn7GdVoEy2w8EplWjtYFFeR9Kki0jbQBxNoVaQRybhHLXL9XyKch2AXGXSVYOO9iVyJjmfg/T3l1jHZ74LxBsc7+616EGJXqKvrVoI24DOJj4b6QdCibxAzuewnrIWJdbxmScD8d6Od3danIw2bqUfUuepL/w1+Pqkk+te0dV2K/iMR++1TJ7oG4inL9gxeaii5XH8LYCvjdIvBFOGkPHZa6c7KjLuFTDUnb11ZJjiqZU29LXS7AYa0rri+jojvY7E9iGrGbqfA37DKCvK4/z1BU+68teFKnmEFivdHNuVWLszugHqtOdrX6Qf63aveCLgOzfy+cJhtAFdJegikXa44lKULvzdBVEj7eeLe8y8f4dSot3H9rPzz3kj7PmVyLaP8jX4NZJvVIkUi+BjMBuurzUG/rN1oIsTjaCoQvupOno5AuguMh1se1d+AXZaw3yiNm8Dl690xY/7KokVUBswlPFKOBvSyFkYmy/TbsiPlOvcIGkJ4+AXsO1ceY1c+cSJVnyXv3T95ax/PfkMXPoPsL8Sko6IGTHxZ1F+N2yJsTPbshrbdpBEHsHI9DXTI6IAaoBZkCRdwEcLXT84BHyihm4HM6bWmMWwDLTTmGVx6XnY6zicVPSboi/m+IOMKANJT4Mkw8pwKyZr+bsKdALUwekHUKe1HTaF8+AkaAHHwAmQRSbidCdoWiWVXhgu9Bg/Y+tPRFEJu8sMTY/BkEW64uTrz0xXQI2KYZBmTvoqyKvXl54KR0JW6YCjrx2zQ0G1HT0Gaeeor7K0+k+o+4JQAxOWtcfOV/ec4kHAE2gres23DvAgbIZ9LWroCtACuQaqIa+E1jTdSxJLcyyHgg5LoSup722H9Nr7F8BHYNrpI9wDaVZ9zEvkQnJmTDM9rcQyRUaHFy1KmkMFMIMmSWtaaYhXgnaPvyDk9zPl40HDOa1ci4Mv9mRzG0wb2LTXMDsNuoFejvJC2562w19BX7MAOsFpu2wFOoX2gaSijmh6vAEaMYq1C0Ki6Xufx2Bcfb0AT/xYdWMsJsDYWEu3ge4pn4NeqI7VOvdrNOkqrBes3xH0HAAu0ZQuCxlEKzTMfUM1r77SE7s3+rKRo2nJK5C3sz5/+yVo6hxRNr03GtKT9DLwdSSP3nwJut2WtWhxfA/ydNjlW1UXU9trg5DOtPJhqAZXh9LqdhJnHrSBBien0uIxMBc2QJrO12CvEaUv3xaK8i9e8Ax/5Ku5fAAAAABJRU5ErkJggg==
Open Pages
Recent changes
$:/_AFC/Palette
\whitespace trim
\define print-button()
<$button tooltip="print" aria-label="print" class=<<tv-config-toolbar-class>>>
<$action-sendmessage $message="tm-open-window" template="$:/plugins/federatial/print/window" windowTitle={{$:/config/plugins/federatial/print/window-title}}/>
<$list filter="[<tv-config-toolbar-icons>prefix[yes]]">
{{$:/core/images/print-button}}
</$list>
<$list filter="[<tv-config-toolbar-text>prefix[yes]]">
<span class="tc-btn-text">
<$text text="print"/>
</span>
</$list>
</$button>
\end
<$list filter="[<currentTiddler>tagging[]role[heading]limit[1]]" variable="ignore" emptyMessage=<<print-button>>>
<$text text=""/>
</$list>
\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline

.tc-export-controls {
	background: #dfddf9;
	margin: -1em -1em 0 -1em;
	padding: 1em;
	border-bottom: 2px solid black;
}

.tc-export-controls textarea {
	width: 100%;
}

.tc-export-header {
	margin-top: 1em;
	padding: 1em;
	border: 1px solid black;
}

@media print {

	.tc-unprintable {
		display: none;
	}

}
<$transclude tiddler="$:/plugins/federatial/print/template/inner" mode="block"/>
! <$view field="title"/>

{{!!text}}

\whitespace trim

<$set name="themeTitle" value={{$:/view}}>

<$set name="tempCurrentTiddler" value=<<currentTiddler>>>

<$set name="currentTiddler" value={{$:/language}}>

<$set name="languageTitle" value={{!!name}}>

<$set name="currentTiddler" value=<<tempCurrentTiddler>>>

<$importvariables filter="[[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]">

<div class="tc-unprintable tc-export-controls">

<$button message="tm-print" tooltip="Print this page">
Print
</$button>

</div>

<$transclude tiddler="$:/plugins/federatial/print/template" mode="block"/>

</$importvariables>

</$set>

</$set>

</$set>

</$set>

</$set>
!! This tiddler is present to disable the default login status pill that Xememex provides
{
    "tiddlers": {
        "$:/config/Comments/EnableFilter": {
            "title": "$:/config/Comments/EnableFilter",
            "text": "[all[current]!is[system]]\n"
        },
        "$:/plugins/tiddlywiki/comments/above-story": {
            "title": "$:/plugins/tiddlywiki/comments/above-story",
            "tags": "$:/tags/AboveStory",
            "text": "<$reveal state=\"$:/config/Comments/EnableWikiComments\" type=\"match\" text=\"yes\" default=\"no\">\n<$tiddler tiddler=\"$:/SiteTitle\">\n<$transclude tiddler=\"$:/plugins/tiddlywiki/comments/comments-template\" mode=\"inline\"/>\n</$tiddler>\n</$reveal>\n"
        },
        "$:/plugins/tiddlywiki/comments/add-comment-button-actions": {
            "title": "$:/plugins/tiddlywiki/comments/add-comment-button-actions",
            "text": "<$set name=\"username\" value={{$:/status/UserName}} emptyValue=\"(anonymous)\">\n<$set name=\"target\" filter=\"[<currentTiddler>]\">\n<$action-createtiddler $basetitle={{{ [[Comment by ']addsuffix<username>addsuffix[' on ']addsuffix<currentTiddler>addsuffix[']] }}} role=\"comment\" list=<<target>> text=\"\" edit-mode=\"yes\"/>\n</$set>\n</$set>\n"
        },
        "$:/plugins/tiddlywiki/comments/add-comment-button": {
            "title": "$:/plugins/tiddlywiki/comments/add-comment-button",
            "text": "<$reveal state=\"$:/status/IsReadOnly\" type=\"match\" text=\"no\" default=\"no\" tag=\"div\" class=\"tc-comment-button\">\n<$button class=\"tc-btn-invisible\" actions={{$:/plugins/tiddlywiki/comments/add-comment-button-actions}}>\nadd comment {{$:/core/images/add-comment}}\n</$button>\n</$reveal>\n"
        },
        "$:/plugins/tiddlywiki/comments/comments-template": {
            "title": "$:/plugins/tiddlywiki/comments/comments-template",
            "text": "<div class=\"tc-comments\">\n<ol class=\"tc-comment-list\">\n<$list filter=\"[all[tiddlers+shadows]role[comment]contains<currentTiddler>sort[created]!has[draft.of]]\">\n<li>\n<div class=\"tc-comment-entry\">\n<div class=\"tc-comment-entry-heading\">\n<$link>{{!!creator}} at <$view field=\"modified\" format=\"date\" template=\"0hh:0mm:0ss DDD DDth MMM YYYY\"/></$link>\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/CommentToolbarButton]!has[draft.of]]\" variable=\"listItem\">\n<$transclude tiddler=<<listItem>> mode=\"inline\"/>\n</$list>\n</div>\n<div class=\"tc-comment-entry-body\">\n<$reveal type=\"match\" state=\"!!edit-mode\" text=\"yes\">\n<$edit-text tiddler=<<currentTiddler>> tag=\"textarea\" focus=\"true\"/>\n</$reveal>\n<$reveal type=\"nomatch\" state=\"!!edit-mode\" text=\"yes\">\n<$transclude tiddler=<<currentTiddler>> mode=\"block\"/>\n<$transclude tiddler=\"$:/plugins/tiddlywiki/comments/add-comment-button\" mode=\"inline\"/>\n</$reveal>\n</div>\n</div>\n<$transclude tiddler=\"$:/plugins/tiddlywiki/comments/comments-template\" mode=\"inline\"/>\n</li>\n</$list>\n</ol>\n</div>\n"
        },
        "$:/plugins/tiddlywiki/comments/config": {
            "title": "$:/plugins/tiddlywiki/comments/config",
            "text": "\\define select(description,filter)\n<$button>\n<$action-setfield $tiddler=\"$:/config/Comments/EnableFilter\" $value=<<__filter__>>/>\n$description$\n</$button>\n\\end\n\n! Wiki Comments\n\n<$checkbox tiddler=\"$:/config/Comments/EnableWikiComments\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"no\"> <$link to=\"$:/config/Comments/EnableWikiComments\">Allow wiki-level comments as well as tiddler comments</$link> </$checkbox>\n\n! Tiddler Comments\n\nThis filter expression determines which tiddlers will have commenting enabled:\n\n<$edit-text tiddler=\"$:/config/Comments/EnableFilter\" tag=\"input\"/>\n\nOr you can choose a preselected filter:\n\n* <<select \"All tiddlers except system tiddlers\" \"[all[current]!is[system]]\">>\n* <<select \"Only tiddlers tagged 'commentable'\" \"[all[current]tag[commentable]]\">>\n* <<select \"Disable all commenting\" \"\">>\n"
        },
        "$:/plugins/tiddlywiki/comments/filter-all-comments": {
            "title": "$:/plugins/tiddlywiki/comments/filter-all-comments",
            "tags": "$:/tags/Filter",
            "filter": "[role[comment]!sort[modified]]",
            "description": "All comments",
            "text": ""
        },
        "$:/plugins/tiddlywiki/comments/footer-view-template-segment": {
            "title": "$:/plugins/tiddlywiki/comments/footer-view-template-segment",
            "tags": "$:/tags/ViewTemplate",
            "list-after": "$:/core/ui/ViewTemplate/body",
            "text": "<$list filter={{$:/config/Comments/EnableFilter}} variable=\"ignore\">\n<div class=\"tc-comments-segment\">\n<$transclude tiddler=\"$:/plugins/tiddlywiki/comments/add-comment-button\" mode=\"inline\"/>\n<$transclude tiddler=\"$:/plugins/tiddlywiki/comments/comments-template\" mode=\"inline\"/>\n</div>\n</$list>"
        },
        "$:/plugins/tiddlywiki/comments/header-view-template-segment": {
            "title": "$:/plugins/tiddlywiki/comments/header-view-template-segment",
            "tags": "$:/tags/ViewTemplate",
            "list-before": "$:/core/ui/ViewTemplate/body",
            "text": "<$list filter=\"[all[current]role[comment]]\" variable=\"ignore\">\n<div class=\"tc-is-comment-header\">\nThis tiddler is a comment on:\n<ul>\n<$list filter=\"[list<currentTiddler>sort[title]]\">\n<li>\n<$link to=<<currentTiddler>>><$text text=<<currentTiddler>>/></$link>\n</li>\n</$list>\n</ul>\n</div>\n</$list>\n"
        },
        "$:/plugins/tiddlywiki/comments/readme": {
            "title": "$:/plugins/tiddlywiki/comments/readme",
            "text": "This plugin provides a simple means for adding threaded comments to tiddlers.\n\n* Click the \"add comment\" button to make a new comment, and then click the \"save\" button to save it\n* You can comment on a tiddler itself, or add a comment to an existing comment\n* The sidebar tab ''Comments'' lists a timeline of all comments\n* Comments are attributed to the username stored in the system tiddler [[$:/status/UserName]]\n* By default, comments are available on all non-system tiddlers. The ''config'' tab lets you customise which tiddlers can accept comments by specifying a filter extension\n* The buttons for adding and editing comments are only available if the system tiddler [[$:/status/IsReadOnly]] is not set to `yes`\n* Use the \"All comments\" option in the $:/AdvancedSearch ''Filter'' tab to see or export all comments\n\n!! Data Model\n\nThe data model employed by the comments plugin is very simple:\n\n* Comment tiddlers are identified by the `role` field being set to `comment`\n* The `list` field of comment tiddlers lists the tiddlers to which this comment applies\n** It is thus possible for a comment to be applied to multiple tiddlers at once\n** The links between comments can be preserved when renaming them by using the relink checkbox in the edit template\n* The `edit-mode` field of comment tiddlers is set to `yes` to display it in edit mode, or `no` to display it in view mode\n* The `saved-text` field is updated when switching to edit mode so that it can be restored if the user cancels\n\n"
        },
        "$:/plugins/tiddlywiki/comments/sidebar-segment": {
            "title": "$:/plugins/tiddlywiki/comments/sidebar-segment",
            "tags": "$:/tags/SideBarSegment",
            "list-after": "$:/core/ui/SideBarSegments/site-subtitle",
            "text": "<$reveal state=\"$:/config/Comments/EnableWikiComments\" type=\"match\" text=\"yes\" default=\"no\">\n<$tiddler tiddler=\"$:/SiteTitle\">\n<$transclude tiddler=\"$:/plugins/tiddlywiki/comments/add-comment-button\" mode=\"inline\"/>\n</$tiddler>\n</$reveal>\n"
        },
        "$:/plugins/tiddlywiki/comments/sidebar": {
            "title": "$:/plugins/tiddlywiki/comments/sidebar",
            "tags": "$:/tags/SideBar",
            "caption": "Comments",
            "text": "<div class=\"tc-timeline\">\n<$list filter=\"[all[tiddlers+shadows]role[comment]has[modified]!sort[modified]eachday[modified]]\">\n<div class=\"tc-menu-list-item\">\n<$view field=\"modified\" format=\"date\" template=\"DDth MMM YYYY\"/>\n<$list filter=\"[all[tiddlers+shadows]role[comment]sameday:modified{!!modified}!sort[modified]]\">\n<div class=\"tc-menu-list-subitem\">\n<$link>Comment by '<$view field=\"modifier\">(anonymous)</$view>'</$link> on\n<$list filter=\"[list<currentTiddler>sort[title]]\">\n<$link to=<<currentTiddler>>><$text text=<<currentTiddler>>/></$link>\n</$list>\n</div>\n</$list>\n</div>\n</$list>\n</div>\n"
        },
        "$:/plugins/tiddlywiki/comments/styles": {
            "title": "$:/plugins/tiddlywiki/comments/styles",
            "tags": "[[$:/tags/Stylesheet]]",
            "text": "\\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline\n\n.tc-is-comment-header {\n\tbackground: #c1e1e9;\n\tpadding: 0.25em;\n}\n\n.tc-comments-segment {\n\tborder-top: 2px solid #c1e1e9;\n}\n\n.tc-comment-button button {\n\twidth: 100%;\n\ttext-align: right;\n}\n\n.tc-sidebar-scrollable .tc-comment-button button {\n\twidth: auto;\n\ttext-align: right;\n}\n\n.tc-comment-button button svg {\n\tfill: #26cb56;\n\theight: 2em;\n\twidth: 2em;\n}\n\n.tc-comments {\n}\n\n.tc-comment-list {\n\tlist-style: none;\n     padding-left: 0;\n}\n\n.tc-comment-list .tc-comments {\n\tpadding-left: 1em;\n}\n\n.tc-comment-entry {\n\tborder: 1px solid #c1e1ea;\n\tmargin: 0.5em 0 0 0;\n\tbackground: #dbf6ff;\n}\n\n.tc-comment-entry-heading {\n\tfont-size: 0.7em;\n\tfont-weight: bold;\n\ttext-transform: uppercase;\n\tbackground: #c1e1ea;\n\tcolor: #5B6D80;\n\tpadding: 0 0.5em;\n}\n\n.tc-comment-entry-body {\n\tfont-size: 0.8em;\n\tpadding: 0 0.5em;\n}\n\n.tc-comment-entry-body textarea {\n\tfont-size: 1.1em;\n\twidth: 100%\n}\n"
        },
        "$:/tags/CommentToolbarButton": {
            "title": "$:/tags/CommentToolbarButton",
            "list": "[[$:/plugins/tiddlywiki/comments/toolbar-button-cancel]] [[$:/plugins/tiddlywiki/comments/toolbar-button-delete]] [[$:/plugins/tiddlywiki/comments/toolbar-button-save]] [[$:/plugins/tiddlywiki/comments/toolbar-button-edit]]"
        },
        "$:/plugins/tiddlywiki/comments/toolbar-button-cancel": {
            "title": "$:/plugins/tiddlywiki/comments/toolbar-button-cancel",
            "tags": "$:/tags/CommentToolbarButton",
            "text": "<$reveal state=\"$:/status/IsReadOnly\" type=\"match\" text=\"no\" default=\"no\" tag=\"span\">\n<$reveal type=\"match\" state=\"!!edit-mode\" text=\"yes\">\n<$button>\n<$action-setfield $tiddler=<<currentTiddler>> $field=\"edit-mode\" $value=\"no\"/>\n<$action-setfield $tiddler=<<currentTiddler>> $field=\"text\" $value={{!!saved-text}}/>\ncancel\n</$button>\n</$reveal>\n</$reveal>\n"
        },
        "$:/plugins/tiddlywiki/comments/toolbar-button-delete": {
            "title": "$:/plugins/tiddlywiki/comments/toolbar-button-delete",
            "tags": "$:/tags/CommentToolbarButton",
            "text": "<$reveal state=\"$:/status/IsReadOnly\" type=\"match\" text=\"no\" default=\"no\" tag=\"span\">\n<$reveal type=\"match\" state=\"!!edit-mode\" text=\"yes\">\n<$button>\n<$action-deletetiddler $tiddler=<<currentTiddler>>/>\ndelete\n</$button>\n</$reveal>\n</$reveal>\n"
        },
        "$:/plugins/tiddlywiki/comments/toolbar-button-edit": {
            "title": "$:/plugins/tiddlywiki/comments/toolbar-button-edit",
            "tags": "$:/tags/CommentToolbarButton",
            "text": "<$reveal state=\"$:/status/IsReadOnly\" type=\"match\" text=\"no\" default=\"no\" tag=\"span\">\n<$reveal type=\"nomatch\" state=\"!!edit-mode\" text=\"yes\">\n<$button>\n<$action-setfield $tiddler=<<currentTiddler>> $field=\"edit-mode\" $value=\"yes\"/>\n<$action-setfield $tiddler=<<currentTiddler>> $field=\"saved-text\" $value={{!!text}}/>\nedit\n</$button>\n</$reveal>\n</$reveal>\n"
        },
        "$:/plugins/tiddlywiki/comments/toolbar-button-save": {
            "title": "$:/plugins/tiddlywiki/comments/toolbar-button-save",
            "tags": "$:/tags/CommentToolbarButton",
            "text": "<$reveal state=\"$:/status/IsReadOnly\" type=\"match\" text=\"no\" default=\"no\" tag=\"span\">\n<$reveal type=\"match\" state=\"!!edit-mode\" text=\"yes\">\n<$button>\n<$action-setfield $tiddler=<<currentTiddler>> $field=\"edit-mode\" $value=\"no\"/>\nsave\n</$button>\n</$reveal>\n</$reveal>\n"
        }
    }
}
<div class="tc-timeline">
<$list filter="[all[tiddlers+shadows]role[comment]has[modified]!sort[modified]eachday[modified]]">
<div class="tc-menu-list-item">
<$view field="modified" format="date" template="DDth MMM YYYY"/>
<$list filter="[all[tiddlers+shadows]role[comment]sameday:modified{!!modified}!sort[modified]]">
<div class="tc-menu-list-subitem">
<$link>Comment by '<$view field="modifier">(anonymous)</$view>'</$link> on
<$list filter="[list<currentTiddler>sort[title]]">
<$link to=<<currentTiddler>>><$text text=<<currentTiddler>>/></$link>
</$list>
</div>
</$list>
</div>
</$list>
</div>
{"tiddlers":{"$:/plugins/tiddlywiki/consent-banner/banner":{"title":"$:/plugins/tiddlywiki/consent-banner/banner","tags":"$:/tags/PageTemplate","text":"\\whitespace trim\n\n<$reveal state=\"$:/state/consent-banner/accepted\" type=\"match\" text=\"\" tag=\"div\">\n\n<div class=\"tc-consent-backdrop\">\n\n</div>\n\n<div class=\"tc-consent-banner tc-consent-banner-left\">\n\n<$transclude tiddler=\"$:/config/plugins/tiddlywiki/consent-banner/greeting-message\" mode=\"block\"/>\n\n<div class=\"tc-consent-buttons\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/ConsentBanner/Button]]\">\n\n<$transclude tiddler=<<currentTiddler>> mode=\"inline\"/>\n\n</$list>\n\n</div>\n\n</div>\n\n</$reveal>\n"},"$:/plugins/tiddlywiki/consent-banner/blocked-embed-message-wrapper":{"title":"$:/plugins/tiddlywiki/consent-banner/blocked-embed-message-wrapper","text":"\\define styles()\nwidth:$(width)$;height:$(height)$;\n\\end\n\n<div class=\"tc-blocked-embedded-content\" style=<<styles>>>\n<div class=\"tc-blocked-embedded-content-inner\">\n<div class=\"tc-blocked-embedded-content-inner-inner\">\n<$transclude tiddler=\"$:/config/plugins/tiddlywiki/consent-banner/blocked-embed-message\" mode=\"inline\"/>\n</div>\n</div>\n</div>\n"},"$:/plugins/tiddlywiki/consent-banner/buttons/accept":{"title":"$:/plugins/tiddlywiki/consent-banner/buttons/accept","tags":"$:/tags/ConsentBanner/Button","text":"<$button message=\"tm-consent-accept\" class=\"tc-consent-button tc-consent-button-default tc-btn-invisible\" tooltip={{$:/config/plugins/tiddlywiki/consent-banner/buttons/accept/hint}}>\n{{$:/config/plugins/tiddlywiki/consent-banner/buttons/accept/caption}}\n</$button>\n"},"$:/plugins/tiddlywiki/consent-banner/buttons/decline":{"title":"$:/plugins/tiddlywiki/consent-banner/buttons/decline","tags":"$:/tags/ConsentBanner/Button","text":"<$button message=\"tm-consent-decline\" class=\"tc-consent-button tc-btn-invisible\" tooltip={{$:/config/plugins/tiddlywiki/consent-banner/buttons/decline/hint}}>\n{{$:/config/plugins/tiddlywiki/consent-banner/buttons/decline/caption}}\n</$button>\n"},"$:/config/DefaultColourMappings/consent-banner-backdrop-background":{"title":"$:/config/DefaultColourMappings/consent-banner-backdrop-background","text":"rgba(0,0,0,0.2)"},"$:/config/DefaultColourMappings/consent-banner-background":{"title":"$:/config/DefaultColourMappings/consent-banner-background","text":"#009677"},"$:/config/DefaultColourMappings/consent-banner-button-background":{"title":"$:/config/DefaultColourMappings/consent-banner-button-background","text":"transparent"},"$:/config/DefaultColourMappings/consent-banner-button-border":{"title":"$:/config/DefaultColourMappings/consent-banner-button-border","text":"#fff"},"$:/config/DefaultColourMappings/consent-banner-button-default-background":{"title":"$:/config/DefaultColourMappings/consent-banner-button-default-background","text":"#fff"},"$:/config/DefaultColourMappings/consent-banner-button-default-foreground":{"title":"$:/config/DefaultColourMappings/consent-banner-button-default-foreground","text":"#009677"},"$:/config/DefaultColourMappings/consent-banner-button-foreground":{"title":"$:/config/DefaultColourMappings/consent-banner-button-foreground","text":"#fff"},"$:/config/DefaultColourMappings/consent-banner-button-hover-background":{"title":"$:/config/DefaultColourMappings/consent-banner-button-hover-background","text":"#fff"},"$:/config/DefaultColourMappings/consent-banner-button-hover-border":{"title":"$:/config/DefaultColourMappings/consent-banner-button-hover-border","text":"#fff"},"$:/config/DefaultColourMappings/consent-banner-button-hover-foreground":{"title":"$:/config/DefaultColourMappings/consent-banner-button-hover-foreground","text":"#009577"},"$:/config/DefaultColourMappings/consent-banner-foreground":{"title":"$:/config/DefaultColourMappings/consent-banner-foreground","text":"#fff"},"$:/config/DefaultColourMappings/consent-banner-hr-background":{"title":"$:/config/DefaultColourMappings/consent-banner-hr-background","text":"rgba(255,255,255,.25)"},"$:/config/DefaultColourMappings/consent-banner-link-foreground":{"title":"$:/config/DefaultColourMappings/consent-banner-link-foreground","text":"#fff"},"$:/config/plugins/tiddlywiki/consent-banner/block-embedded-content":{"title":"$:/config/plugins/tiddlywiki/consent-banner/block-embedded-content","text":"yes"},"$:/config/plugins/tiddlywiki/consent-banner/blocked-embed-message":{"title":"$:/config/plugins/tiddlywiki/consent-banner/blocked-embed-message","text":"Blocked embedded content from<br/><a href=<<url>> class=\"tc-tiddlylink-external\" target=\"_blank\" rel=\"noopener noreferrer\"><$text text=<<url>>/></a>\n\n<hr/>\n\n{{$:/plugins/tiddlywiki/consent-banner/buttons/accept}} cookies to unblock"},"$:/config/plugins/tiddlywiki/consent-banner/blocked-raw-message":{"title":"$:/config/plugins/tiddlywiki/consent-banner/blocked-raw-message","text":"<div class=\"tc-blocked-embedded-content\" style=\"width:100%;\">\n\n<div class=\"tc-blocked-embedded-content-inner\">\n\n<div class=\"tc-blocked-embedded-content-inner-inner\">\n\nBlocked raw content\n\n<hr/>\n\n{{$:/plugins/tiddlywiki/consent-banner/buttons/accept}} cookies to unblock\n\n</div>\n\n</div>\n\n</div>\n"},"$:/config/plugins/tiddlywiki/consent-banner/buttons/accept/caption":{"title":"$:/config/plugins/tiddlywiki/consent-banner/buttons/accept/caption","text":"Accept"},"$:/config/plugins/tiddlywiki/consent-banner/buttons/accept/hint":{"title":"$:/config/plugins/tiddlywiki/consent-banner/buttons/accept/hint","text":"Accept cookies"},"$:/config/plugins/tiddlywiki/consent-banner/buttons/clear/caption":{"title":"$:/config/plugins/tiddlywiki/consent-banner/buttons/clear/caption","text":"Clear"},"$:/config/plugins/tiddlywiki/consent-banner/buttons/clear/hint":{"title":"$:/config/plugins/tiddlywiki/consent-banner/buttons/clear/hint","text":"Clear cookies"},"$:/config/plugins/tiddlywiki/consent-banner/buttons/decline/caption":{"title":"$:/config/plugins/tiddlywiki/consent-banner/buttons/decline/caption","text":"Decline"},"$:/config/plugins/tiddlywiki/consent-banner/buttons/decline/hint":{"title":"$:/config/plugins/tiddlywiki/consent-banner/buttons/decline/hint","text":"Decline cookies"},"$:/config/cookie-consent-required":{"title":"$:/config/cookie-consent-required","text":"yes"},"$:/config/plugins/tiddlywiki/consent-banner/greeting-message":{"title":"$:/config/plugins/tiddlywiki/consent-banner/greeting-message","text":"! Our use of cookies\n\nWe use necessary cookies to make our site work. We’d also like to set optional analytics to help us improve it. We won’t set optional cookies unless you enable them. Using this tool will set a cookie on your device to remember your preferences.\n\n---\n\n!! Necessary cookies\n\nNecessary cookies enable core functionality such as security, network management, and accessibility. You may disable these by changing your browser settings, but this may affect how the website functions.\n\n---\n\n!! Analytics cookies\n\nWe’d like to set non-essential cookies, such as Google Analytics, to help us to improve our website by collecting and reporting information on how you use it. The cookies collect information in a way that does not directly identify anyone.\n\n---\n"},"$:/plugins/tiddlywiki/consent-banner/tv-block-embedded-content":{"title":"$:/plugins/tiddlywiki/consent-banner/tv-block-embedded-content","tags":"$:/tags/Macro","text":"<$set name=\"tv-block-embedded-content\" value={{{ [{$:/config/cookie-consent-required}else[no]match[yes]then{$:/state/consent-banner/accepted}!match[yes]then[yes]] }}}/>\n"},"$:/plugins/tiddlywiki/consent-banner/config":{"title":"$:/plugins/tiddlywiki/consent-banner/config","text":"! [[Greeting Message|$:/config/plugins/tiddlywiki/consent-banner/greeting-message]]\n\n<div style=\"\">\n\n<div style=\"display:inline-block;vertical-align:top;width:45%;\">\n\n<$edit-text tiddler=\"$:/config/plugins/tiddlywiki/consent-banner/greeting-message\" tag=\"textarea\" class=\"tc-edit-texteditor\"/>\n\n</div>\n\n<div style=\"display:inline-block;vertical-align:top;width:45%;margin:0.5em;border:1px solid black;padding:0.5em;\" class=\"tc-consent-banner\">\n\n<$transclude tiddler=\"$:/config/plugins/tiddlywiki/consent-banner/greeting-message\" mode=\"block\"/>\n\n</div>\n\n</div>\n\n! Buttons\n\n|[[Accept caption|$:/config/plugins/tiddlywiki/consent-banner/buttons/accept/caption]] |<$edit-text tiddler=\"$:/config/plugins/tiddlywiki/consent-banner/buttons/accept/caption\" tag=\"input\"/> |\n|[[Accept hint|$:/config/plugins/tiddlywiki/consent-banner/buttons/accept/hint]] |<$edit-text tiddler=\"$:/config/plugins/tiddlywiki/consent-banner/buttons/accept/hint\" tag=\"input\"/> |\n|[[Decline caption|$:/config/plugins/tiddlywiki/consent-banner/buttons/decline/caption]] |<$edit-text tiddler=\"$:/config/plugins/tiddlywiki/consent-banner/buttons/decline/caption\" tag=\"input\"/> |\n|[[Decline hint|$:/config/plugins/tiddlywiki/consent-banner/buttons/decline/hint]] |<$edit-text tiddler=\"$:/config/plugins/tiddlywiki/consent-banner/buttons/decline/hint\" tag=\"input\"/> |\n\n! [[Consent Accepted Status|$:/state/consent-banner/accepted]]\n\nCurrent status: {{$:/state/consent-banner/accepted}} (blank indicates that consent has not yet been granted or declined)\n\n<$button message=\"tm-consent-accept\" tooltip={{$:/config/plugins/tiddlywiki/consent-banner/buttons/accept/hint}}>\n{{$:/config/plugins/tiddlywiki/consent-banner/buttons/accept/caption}}\n</$button>\n\n<$button message=\"tm-consent-decline\" tooltip={{$:/config/plugins/tiddlywiki/consent-banner/buttons/decline/hint}}>\n{{$:/config/plugins/tiddlywiki/consent-banner/buttons/decline/caption}}\n</$button>\n\n<$button message=\"tm-consent-clear\" tooltip={{$:/config/plugins/tiddlywiki/consent-banner/buttons/clear/hint}}>\n{{$:/config/plugins/tiddlywiki/consent-banner/buttons/clear/caption}}\n</$button>\n\n! Embedded Content Blocking\n\n//Requires page reload//\n\n<$checkbox tiddler=\"$:/config/plugins/tiddlywiki/consent-banner/block-embedded-content\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"no\"> Block all embedded content such as &lt;iframe>, &lt;embed> and &lt;object> unless consent has been granted</$checkbox>\n"},"$:/plugins/tiddlywiki/consent-banner/docs":{"title":"$:/plugins/tiddlywiki/consent-banner/docs","text":"! Features\n\nIf the same wiki is opened in multiple tabs then once the warning has been accepted or declined in one tab then the other tabs will autonatically follow suit.\n\nConsent is automatically granted if the user logged in (ie the tiddler [[$:/status/IsLoggedIn]] is set to `yes`).\n\n! Consent Banner Palette Entries\n\nAdd these entries to your current colour palette to change the colours used by the consent banner:\n\n* ''consent-banner-backdrop-background'' - the colour of the backdrop behind the consent banner (defaults to {{$:/config/DefaultColourMappings/consent-banner-backdrop-background}})\n* ''consent-banner-background'' - the background colour of the consent banner (defaults to {{$:/config/DefaultColourMappings/consent-banner-background}})\n* ''consent-banner-button-background'' - the background colour of buttons within the consent banner (defaults to {{$:/config/DefaultColourMappings/consent-banner-button-background}})\n* ''consent-banner-button-border'' - the border colour of buttons within the consent banner (defaults to {{$:/config/DefaultColourMappings/consent-banner-button-border}})\n* ''consent-banner-button-default-background'' - the background colour for the default button within the consent banner (defaults to {{$:/config/DefaultColourMappings/consent-banner-button-default-background}})\n* ''consent-banner-button-default-foreground'' - the foreground colour for the default button within the consent banner (defaults to {{$:/config/DefaultColourMappings/consent-banner-button-default-foreground}})\n* ''consent-banner-button-foreground'' - the foreground colour of buttons within the consent banner (defaults to {{$:/config/DefaultColourMappings/consent-banner-button-foreground}})\n* ''consent-banner-button-hover-background'' - the background colour of hovered buttons within the consent banner (defaults to {{$:/config/DefaultColourMappings/consent-banner-button-hover-background}})\n* ''consent-banner-button-hover-border'' - the border colour of hovered buttons within the consent banner (defaults to {{$:/config/DefaultColourMappings/consent-banner-button-hover-border}})\n* ''consent-banner-button-hover-foreground'' - the foreground colour of hovered buttons within the consent banner (defaults to {{$:/config/DefaultColourMappings/consent-banner-button-hover-foreground}})\n* ''consent-banner-foreground'' - the foreground colour of the consent banner (defaults to {{$:/config/DefaultColourMappings/consent-banner-foreground}})\n* ''consent-banner-hr-background'' - the background colour of horizontal rules within the consent banner (defaults to {{$:/config/DefaultColourMappings/consent-banner-hr-background}})\n* ''consent-banner-link-foreground'' - the foreground colour of tiddler links within the consent banner (defaults to {{$:/config/DefaultColourMappings/consent-banner-link-foreground}})\n\n! Embedded Content Blocking\n\nUnless disabled via the config tab, content embedded via &lt;iframe>, &lt;embed> or &lt;object> is blocked until the user consents to accept cookies.\n\n!! Implementation Details\n\nEmbedded content is blocked if the variable `tv-block-embedded-content` is set to `yes`. It is set to the current consent status by a [[global macro|$:/plugins/tiddlywiki/consent-banner/tv-block-embedded-content]]:\n\n<$codeblock code={{$:/plugins/tiddlywiki/consent-banner/tv-block-embedded-content}}/>\n\n! ~YouTube macro\n\nA simple macro for embedding ~YouTube videos is provided to show how to adapt content according to whether consent has been granted. It works by checking the tiddler [[$:/state/consent-banner/accepted]] for the following values:\n\n* ''empty or missing'' - the user has yet to accept or decline to give their consent\n* `yes` - the user has granted consent\n* `no` - the user has declined consent\n\n! Customising banner buttons\n\nThe [[\"accept\"|$:/plugins/tiddlywiki/consent-banner/buttons/accept]] and [[\"decline\"|$:/plugins/tiddlywiki/consent-banner/buttons/decline]] buttons in the banner are individual tiddlers with the tag [[$:/tags/ConsentBanner/Button]], allowing them to be customised and extended.\n\nA common use case is to add a \"login\" button allowing users to login directly to bypass the banner. This could be implemented as a tiddler tagged [[$:/tags/ConsentBanner/Button]] with the following text:\n\n```\n<$button message=\"tm-login\" class=\"tc-consent-button tc-btn-invisible\">\nLogin\n</$button>\n```\n\n! Integration with other plugins\n\nThird party plugins that set cookies can configure themselves to defer setting cookies until the user grants consent. There are several parts to this mechanism:\n\n* The consent-banner plugin includes a shadow tiddler [[$:/config/cookie-consent-required]] with the text `yes`. The third-party plugin should inspect this tiddler at startup; if it is not set to \"yes\" then it can proceed to set tiddlers immediately\n* Otherwise, the third-party plugin should listen for changes to the tiddler [[$:/state/consent-banner/accepted]] and only start setting cookies when and if the value changes to \"yes\"\n\nThe [[Google Analytics plugin|https://github.com/TiddlyWiki/TiddlyWiki5/tree/master/plugins/tiddlywiki/googleanalytics]] shows an example of how this mechanism can be implemented.\n"},"$:/core/modules/widgets/raw.js":{"title":"$:/core/modules/widgets/raw.js","text":"/*\\\ntitle: $:/core/modules/widgets/raw.js\ntype: application/javascript\nmodule-type: widget\n\nAn override of the raw widget that blocks raw content until the user has consented to accept cookies\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar RawWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nRawWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nRawWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.execute();\n\tthis.blocked = this.getVariable(\"tv-block-embedded-content\",\"no\") === \"yes\";\n\tif(this.blocked) {\n\t\tthis.makeChildWidgets([{\n\t\t\ttype: \"transclude\",\n\t\t\tattributes: {\n\t\t\t\ttiddler: {type: \"string\", value: \"$:/config/plugins/tiddlywiki/consent-banner/blocked-raw-message\"}\n\t\t\t}\n\t\t}]);\n\t\t// Render child widgets\n\t\tthis.renderChildren(parent,null);\n\t} else {\n\t\tvar div = this.document.createElement(\"div\");\n\t\tdiv.innerHTML=this.parseTreeNode.html;\n\t\tparent.insertBefore(div,nextSibling);\n\t\tthis.domNodes.push(div);\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nRawWidget.prototype.execute = function() {\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nRawWidget.prototype.refresh = function(changedTiddlers) {\n\tif(this.blocked) {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t} else {\n\t\treturn false;\t\t\n\t}\n};\n\nexports.raw = RawWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/plugins/tiddlywiki/consent-banner/readme":{"title":"$:/plugins/tiddlywiki/consent-banner/readme","text":"The ''consent-banner'' plugin helps make websites that are compliant with \"cookie legislation\" such as the [[EU General Data Protection Regulation|https://gdpr.eu/cookies/]].\nIt presents a banner inviting the user to accept or reject cookies, keeping track of their consent in local storage so that the banner can be hidden on subsequent visits.\n\nBy default, content embedded with &lt;iframe>, &lt;embed> and &lt;object> is blocked unless the user consents to accept cookies.\n\nConsent status is  available via a configuration tiddler so that it is possible to construct content that behaves differently depending upon whether consent has been granted. As an example, a macro is provided for embedding ~YouTube videos that automatically uses the youtube-nocookie.com variant of video URLs unless the user has accepted cookies.\n\nPlease note that using this plugin does not guarantee compliance with any particular legislation. You will need to understand the technical issues specific to your situation, and if necessary seek legal advice.\n"},"$:/plugins/tiddlywiki/consent-banner/startup.js":{"title":"$:/plugins/tiddlywiki/consent-banner/startup.js","text":"/*\\\ntitle: $:/plugins/tiddlywiki/consent-banner/startup.js\ntype: application/javascript\nmodule-type: startup\n\nStartup initialisation\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"consent-banner\";\nexports.platforms = [\"browser\"];\nexports.after = [\"startup\"];\nexports.before = [\"render\"];\nexports.synchronous = true;\n\nvar CHECK_CONSENT_INTERVAL = 1000, // Milliseconds between checking local storage\n\tIS_LOGGED_IN_TITLE = \"$:/status/IsLoggedIn\",\n\tCONSENT_KEY = \"COOKIE_CONSENT\", // Local storage keyname\n\tCONSENT_TITLE = \"$:/state/consent-banner/accepted\", // \"\": undeclared, \"yes\": accepted, \"no\": declined\n\tCONFIG_BLOCK_EMBEDDED_CONTENT_TITLE = \"$:/config/plugins/tiddlywiki/consent-banner/block-embedded-content\",\n\tEMBEDDED_MESSAGE_WRAPPER_TITLE = \"$:/plugins/tiddlywiki/consent-banner/blocked-embed-message-wrapper\";\n\nexports.startup = function() { \n\tvar consentState = \"\",\n\t\tsetConsentStatus = function(state) {\n\t\t\tif(consentState !== state) {\n\t\t\t\tconsentState = state;\n\t\t\t\t// Write to local storage\n\t\t\t\twindow.localStorage.setItem(CONSENT_KEY,state);\n\t\t\t\t// Write to a state tiddler\n\t\t\t\t$tw.wiki.addTiddler(new $tw.Tiddler({\n\t\t\t\t\ttitle: CONSENT_TITLE,\n\t\t\t\t\ttext: state\n\t\t\t\t}));\n\t\t\t}\n\t\t},\n\t\tcalculateConsentStatus = function() {\n\t\t\t// Consent is implied for logged in users, otherwise we check local storage\n\t\t\treturn ($tw.wiki.getTiddlerText(IS_LOGGED_IN_TITLE) === \"yes\" && \"yes\") || window.localStorage.getItem(CONSENT_KEY) || \"\";\n\t\t},\n\t\tcheckConsentStatus = function() {\n\t\t\tsetConsentStatus(calculateConsentStatus());\n\t\t\tif(consentState === \"\") {\n\t\t\t\tpollConsentStatus();\n\t\t\t}\n\t\t},\n\t\tpollConsentStatus = function() {\n\t\t\tsetTimeout(checkConsentStatus,CHECK_CONSENT_INTERVAL);\n\t\t};\n\t// Set the current consent status\n\tcheckConsentStatus();\n\t// Listen for consent messages\n\t$tw.rootWidget.addEventListener(\"tm-consent-accept\",function(event) {\n\t\tsetConsentStatus(\"yes\");\n\t});\n\t$tw.rootWidget.addEventListener(\"tm-consent-decline\",function(event) {\n\t\tsetConsentStatus(\"no\");\n\t});\n\t$tw.rootWidget.addEventListener(\"tm-consent-clear\",function(event) {\n\t\tsetConsentStatus(\"\");\n\t});\n\t// Add our element rendering hook\n\tif($tw.wiki.getTiddlerText(CONFIG_BLOCK_EMBEDDED_CONTENT_TITLE,\"no\") === \"yes\") {\n\t\t$tw.hooks.addHook(\"th-rendering-element\",function(parseTreeNodes,widget) {\n\t\t\tif(parseTreeNodes) {\n\t\t\t\treturn parseTreeNodes;\n\t\t\t}\n\t\t\tif([\"iframe\",\"object\",\"embed\"].indexOf(widget.tag) !== -1 && widget.getVariable(\"tv-block-embedded-content\",\"no\") === \"yes\") {\n\t\t\t\tvar url = widget.getAttribute(\"src\"),\n\t\t\t\t\taddUnitsIfMissing = function(str) {\n\t\t\t\t\t\tstr = \"\" + str;\n\t\t\t\t\t\treturn str + ((\"\" + parseInt(str,10)) === str ? \"px\" : \"\");\n\t\t\t\t\t},\n\t\t\t\t\twidth = addUnitsIfMissing(widget.getAttribute(\"width\",\"\")),\n\t\t\t\t\theight = addUnitsIfMissing(widget.getAttribute(\"height\",\"\"));\n\t\t\t\treturn [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"vars\",\n\t\t\t\t\t\tattributes: {\n\t\t\t\t\t\t\turl: {type: \"string\", value: url},\n\t\t\t\t\t\t\twidth: {type: \"string\", value: width},\n\t\t\t\t\t\t\theight: {type: \"string\", value: height}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tchildren: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: \"transclude\",\n\t\t\t\t\t\t\t\tattributes: {\n\t\t\t\t\t\t\t\t\ttiddler: {type: \"string\", value: EMBEDDED_MESSAGE_WRAPPER_TITLE},\n\t\t\t\t\t\t\t\t\tmode: {type: \"string\", value: \"inline\"}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t];\n\t\t\t}\n\t\t\treturn null;\n\t\t});\n\t}\n};\n\n})();\n","type":"application/javascript","module-type":"startup"},"$:/plugins/tiddlywiki/consent-banner/styles":{"title":"$:/plugins/tiddlywiki/consent-banner/styles","tags":"$:/tags/Stylesheet","text":".tc-consent-backdrop {\n\tz-index: 1999;\n\tposition: fixed;\n\tleft: 0;\n\tright: 0;\n\ttop: 0;\n\tbottom: 0;\n\tbackground: <<colour consent-banner-backdrop-background>>;\n}\n\n.tc-consent-banner-left {\n\tz-index: 2000;\n\tposition: fixed;\n\tleft: 0;\n\ttop: 0;\n\tbottom: 0;\n\tmax-width: 500px;\n\toverflow-y: auto;\n}\n\n.tc-consent-banner {\n\tpadding: 1em;\n\tbackground: <<colour consent-banner-background>>;\n\tcolor: <<colour consent-banner-foreground>>;\n\tbox-shadow: 0 0 20px rgba(0,0,0,.2);\n}\n\n.tc-consent-banner a.tc-tiddlylink-external {\n\ttext-decoration: underline;\n\tcolor: <<colour consent-banner-link-foreground>>;\n\tbackground-color: inherit;\n}\n\n.tc-consent-banner a.tc-tiddlylink-external:visited {\n\tcolor: <<colour consent-banner-link-foreground>>;\n\tbackground-color: inherit;\n}\n\n.tc-consent-banner hr {\n\tclear: both;\n\tpadding: 0;\n\twidth: 100%;\n\toverflow: hidden;\n\ttext-align: left;\n\tborder: 0 none;\n\tmargin: 24px 0;\n\theight: 1px;\n\tmax-height: 1px;\n\tbackground: <<colour consent-banner-hr-background>>;\n}\n\n.tc-consent-buttons {\n\t\n}\n\n.tc-consent-banner .tc-consent-button {\n\tmargin-right: 1em;\n}\n\n.tc-consent-button {\n\tborder: 1px solid <<colour consent-banner-button-border>>;\n\tmargin-top: 1em;\n\tpadding: 0.75em 1.5em;\n\tcolor: <<colour consent-banner-button-foreground>>;\n\tbackground: <<colour consent-banner-button-background>>;\n\tfont-weight: bold;\n}\n\n.tc-consent-button:hover {\n\tcolor: <<colour consent-banner-button-hover-foreground>>;\n\tborder-color: <<colour consent-banner-button-hover-border>>;\n\tbackground: <<colour consent-banner-button-hover-background>>;\n\topacity: .6;\n}\n\n.tc-consent-button-default {\n\tcolor: <<colour consent-banner-button-default-foreground>>;\n\tbackground: <<colour consent-banner-button-default-background>>;\n}\n\n.tc-blocked-embedded-content {\n\tdisplay: inline-block;\n\toverflow: hidden;\n\tcolor: <<colour background>>;\n\tbackground: <<colour muted-foreground>>;\n\tborder: 1px solid <<colour foreground>>;\n\t<<box-shadow \"inset 0 0 8px rgba(0, 0, 0, 0.15)\">>\n}\n\n.tc-blocked-embedded-content-inner {\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  width: 100%;\n  height: 100%;\n}\n\n.tc-blocked-embedded-content-inner-inner {\n\tdisplay: inline-block;\n\ttext-align: center;\n}\n\n.tc-blocked-embedded-content-inner-inner hr {\n    background: <<colour foreground>>;\n    height: 1px;\n    width: 80%;\n    border: none;\n}\n"},"$:/plugins/tiddlywiki/consent-banner/youtube":{"title":"$:/plugins/tiddlywiki/consent-banner/youtube","tags":"$:/tags/Macro","text":"\\define embed-video-with-consent(code)\n<$set name=\"tv-block-embedded-content\" value=\"no\">\n<$reveal state=\"$:/state/consent-banner/accepted\" type=\"match\" text=\"yes\" tag=\"div\">\n<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/$code$\" frameborder=\"0\" allow=\"autoplay; encrypted-media\" allowfullscreen></iframe>\n</$reveal>\n<$reveal state=\"$:/state/consent-banner/accepted\" type=\"nomatch\" text=\"yes\" tag=\"div\">\n<iframe width=\"560\" height=\"315\" src=\"https://www.youtube-nocookie.com/embed/$code$\" frameborder=\"0\" allow=\"autoplay; encrypted-media\" allowfullscreen></iframe>\n</$reveal>\n</$set>\n\\end\n\n! Macro source\n\n<$codeblock code={{$:/plugins/tiddlywiki/consent-banner/youtube}}/>\n\n! Example\n\n<<embed-video-with-consent KtCUr83XgyE>>\n"}}}
{"tiddlers":{"$:/plugins/tiddlywiki/googleanalytics/googleanalytics.js":{"title":"$:/plugins/tiddlywiki/googleanalytics/googleanalytics.js","text":"/*\\\ntitle: $:/plugins/tiddlywiki/googleanalytics/googleanalytics.js\ntype: application/javascript\nmodule-type: startup\n\nRuns Google Analytics with the measurement ID in the tiddler `$:/GoogleAnalyticsMeasurementID`\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"google-analytics\";\nexports.platforms = [\"browser\"];\nexports.synchronous = true;\n\nvar CONFIG_CONSENT_REQUIRED_TITLE = \"$:/config/cookie-consent-required\", // \"yes\" or \"no\" (the default)\n\tCONSENT_TITLE = \"$:/state/consent-banner/accepted\"; // \"\": undeclared, \"yes\": accepted, \"no\": declined\n\nexports.startup = function() {\n\tvar hasInitialised = false,\n\t\tinitialiseGoogleAnalytics = function() {\n\t\t\tconsole.log(\"Initialising Google Analytics\");\n\t\t\thasInitialised = true;\n\t\t\tvar gaMeasurementID = $tw.wiki.getTiddlerText(\"$:/GoogleAnalyticsMeasurementID\",\"\").replace(/\\n/g,\"\");\n\t\t\tvar url =\"https://www.googletagmanager.com/gtag/js?id=\" + gaMeasurementID;\n\t\t\twindow.dataLayer = window.dataLayer || [];\n\t\t\twindow.gtag = function() { window.dataLayer?.push(arguments); };\n\t\t\twindow.gtag(\"js\",new Date());\n\t\t\twindow.gtag(\"config\",gaMeasurementID);\n\t\t\tconst scriptElement = window.document.createElement(\"script\");\n\t\t\tscriptElement.async = true;\n\t\t\tscriptElement.src = url;\n\t\t\twindow.document.head.appendChild(scriptElement);\n\t\t};\n\t// Initialise now if consent isn't required\n\tif($tw.wiki.getTiddlerText(CONFIG_CONSENT_REQUIRED_TITLE) !== \"yes\") {\n\t\tinitialiseGoogleAnalytics();\n\t} else {\n\t\t// Or has been granted already\n\t\tif($tw.wiki.getTiddlerText(CONSENT_TITLE) === \"yes\") {\n\t\t\tinitialiseGoogleAnalytics();\n\t\t} else {\n\t\t\t// Or when our config tiddler changes\n\t\t\t$tw.wiki.addEventListener(\"change\",function(changes) {\n\t\t\t\tif(changes[CONSENT_TITLE]) {\n\t\t\t\t\tif(!hasInitialised && $tw.wiki.getTiddlerText(CONSENT_TITLE) === \"yes\") {\n\t\t\t\t\t\tinitialiseGoogleAnalytics();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n};\n\n\n\n})();\n","type":"application/javascript","module-type":"startup"},"$:/plugins/tiddlywiki/googleanalytics/readme":{"title":"$:/plugins/tiddlywiki/googleanalytics/readme","text":"This plugin enables you to use Google Analytics to track access to your online TiddlyWiki document.\n\nBy default, the user is not asked for permission before initialising Google Analytics. This plugin also optionally integrates with the \"Consent Banner\" plugin (also found in the official plugin library) so that Google Analytics is not initialised until the user grants explicit permission.\n\n[[Source code|https://github.com/TiddlyWiki/TiddlyWiki5/blob/master/plugins/tiddlywiki/googleanalytics]]\n"},"$:/plugins/tiddlywiki/googleanalytics/settings":{"title":"$:/plugins/tiddlywiki/googleanalytics/settings","text":"''[[Google Analytics Measurement ID|$:/GoogleAnalyticsMeasurementID]]'': (mandatory) a code of the form `G-XXXXXXXXXX` where X are digits or uppercase letters<br/><$edit-text tiddler=\"$:/GoogleAnalyticsMeasurementID\" default=\"\" tag=\"input\"/>\n\n"},"$:/plugins/tiddlywiki/googleanalytics/usage":{"title":"$:/plugins/tiddlywiki/googleanalytics/usage","text":"!! Create a Google Analytics account\n\nIf you don't already have an account:\n\n# Go to the Google Analytics website: http://www.google.com/analytics/\n# Click the ''Access Google Analytics'' button and follow instructions to set up your account\n# Enter the URL where the wiki is hosted\n# Note the Tracking ID for this domain of the form `G-XXXXXXXXXX`\n\n!! Install the plugin on your local copy of the TiddlyWiki\n\n# ''Backup your TiddlyWiki''. Just in case\n# Install the plugin via the plugin manager in control panel\n# Save the TiddlyWiki andrefresh the page to load the plugin\n# Go to [[$:/ControlPanel]] > Plugins tab and unfold the Google Analytics Plugin\n# Go to the //settings// tab and edit the parameters\n# Save the TiddlyWiki\n\n!! Upload the new version of your TiddlyWiki\n\n# Upload the saved TiddlyWiki to Tiddlyhost, GitHub, GitLab or other web host\n# Return to your Google Analytics page to check that your site is being tracked\n"}}}
{"tiddlers":{"$:/config/DefaultColourMappings/menubar-foreground":{"title":"$:/config/DefaultColourMappings/menubar-foreground","text":"#fff"},"$:/config/DefaultColourMappings/menubar-background":{"title":"$:/config/DefaultColourMappings/menubar-background","text":"#5778d8"},"$:/config/plugins/menubar/MenuItems/Visibility/$:/plugins/tiddlywiki/menubar/items/pagecontrols":{"title":"$:/config/plugins/menubar/MenuItems/Visibility/$:/plugins/tiddlywiki/menubar/items/pagecontrols","text":"hide"},"$:/config/plugins/menubar/MenuItems/Visibility/$:/plugins/tiddlywiki/menubar/items/server":{"title":"$:/config/plugins/menubar/MenuItems/Visibility/$:/plugins/tiddlywiki/menubar/items/server","text":"hide"},"$:/config/plugins/menubar/MenuItems/Visibility/$:/plugins/tiddlywiki/menubar/items/sidebar":{"title":"$:/config/plugins/menubar/MenuItems/Visibility/$:/plugins/tiddlywiki/menubar/items/sidebar","text":"hide"},"$:/config/plugins/menubar/TableOfContents/Tag":{"title":"$:/config/plugins/menubar/TableOfContents/Tag","text":"TableOfContents"},"$:/config/plugins/menubar/breakpoint":{"title":"$:/config/plugins/menubar/breakpoint","text":"620px"},"$:/plugins/tiddlywiki/menubar/config":{"title":"$:/plugins/tiddlywiki/menubar/config","tags":"$:/tags/ControlPanel/Toolbars","caption":"Menu Bar","text":"\\define config-base() $:/config/plugins/menubar/MenuItems/Visibility/\n\n! Menu Bar Configuration\n\n!! Menu Items\n\nSelect which menu items will be shown. You can also drag items to reorder them.\n\n<$set name=\"tv-config-toolbar-icons\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-text\" value=\"yes\">\n\n<$macrocall $name=\"list-tagged-draggable\" tag=\"$:/tags/MenuBar\" itemTemplate=\"$:/core/ui/ControlPanel/Toolbars/ItemTemplate\"/>\n\n</$set>\n\n</$set>\n\n!! Breakpoint Position\n\nThe breakpoint position between narrow and wide screens. Should include CSS units (eg. `400px`).\n\n<$edit-text tiddler=\"$:/config/plugins/menubar/breakpoint\" default=\"\" tag=\"input\"/>\n\n!! Contents Tag\n\nThe tag for the ~TableOfContents used in the Contents dropdown\n\n<$edit-text tiddler=\"$:/config/plugins/menubar/TableOfContents/Tag\" default=\"\" tag=\"input\"/>\n\n!! Menu Bar Colours\n\nTo change the colour of the menu bar, define the colours `menubar-foreground` and `menubar-background` in the currently selected palette\n"},"$:/plugins/tiddlywiki/menubar/items/contents":{"title":"$:/plugins/tiddlywiki/menubar/items/contents","caption":"Contents","description":"Table of Contents","is-dropdown":"yes","tags":"$:/tags/MenuBar","text":"<div class=\"tc-table-of-contents\">\n\n<$macrocall $name=\"toc-selective-expandable\" tag={{$:/config/plugins/menubar/TableOfContents/Tag}}/>\n\n</div>\n"},"$:/plugins/tiddlywiki/menubar/items/hamburger":{"title":"$:/plugins/tiddlywiki/menubar/items/hamburger","tags":"$:/tags/MenuBar","caption":"Hamburger","description":"Show the full menu bar on a narrow screen","custom-menu-content":"{{$:/plugins/tiddlywiki/menubar/items/hamburger}}","show-when":"narrow","text":"<$list filter=\"[[$:/state/popup/menubar/hamburger]get[text]else[no]match[no]]\">\n<$button set=\"$:/state/popup/menubar/hamburger\" setTo=\"yes\">\n{{$:/core/images/menu-button}}\n</$button>\n</$list>\n<$list filter=\"[[$:/state/popup/menubar/hamburger]get[text]else[no]match[yes]]\">\n<$button set=\"$:/state/popup/menubar/hamburger\" setTo=\"no\">\n{{$:/core/images/close-button}}\n</$button>\n</$list>\n"},"$:/plugins/tiddlywiki/menubar/items/pagecontrols":{"title":"$:/plugins/tiddlywiki/menubar/items/pagecontrols","tags":"$:/tags/MenuBar","description":"Page controls from the sidebar","caption":"Page controls","custom-menu-content":"<$transclude tiddler=\"$:/plugins/tiddlywiki/menubar/items/pagecontrols\" mode=\"inline\"/>","text":"\\whitespace trim\n\\define config-title() $:/config/PageControlButtons/Visibility/$(listItem)$\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/PageControls]!has[draft.of]]\" variable=\"listItem\">\n\t<$set name=\"hidden\" value=<<config-title>>>\n\t\t<$list filter=\"[<hidden>!text[hide]]\" storyview=\"pop\" variable=\"ignore\">\n\t\t\t<$set name=\"tv-config-toolbar-class\" filter=\"[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]\">\n\t\t\t\t<$transclude tiddler=<<listItem>> mode=\"inline\"/>\n\t\t\t</$set>\n\t\t</$list>\n\t</$set>\n</$list>\n"},"$:/plugins/tiddlywiki/menubar/items/search":{"title":"$:/plugins/tiddlywiki/menubar/items/search","custom-menu-content":"{{$:/plugins/tiddlywiki/menubar/items/search}}","description":"Search","caption":"Search","tags":"$:/tags/MenuBar","text":"\\define cancel-search-actions()\n<$set name=\"userInput\" value={{{ [<__storeTitle__>get[text]] }}}>\n<$list filter=\"[<__tiddler__>get[text]!match<userInput>]\" emptyMessage=\"\"\"<$action-deletetiddler $filter=\"[<__storeTitle__>] [<__tiddler__>] [<__selectionStateTitle__>]\"/>\"\"\">\n<$action-setfield $tiddler=<<__tiddler__>> text=<<userInput>>/><$action-setfield $tiddler=<<__refreshTitle__>> text=\"yes\"/>\n</$list>\n</$set>\n\\end\n\n\\define input-accept-actions() <$list filter=\"[{$:/config/Search/NavigateOnEnter/enable}match[yes]]\" emptyMessage=\"\"\"<$list filter=\"[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]\"><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>\"\"\"><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>\n\n\\define input-accept-variant-actions() <$list filter=\"[{$:/config/Search/NavigateOnEnter/enable}match[yes]]\" emptyMessage=\"\"\"<$list filter=\"[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]\"><$list filter=\"[<__tiddler__>get[text]minlength[1]]\"><$action-sendmessage $message=\"tm-edit-tiddler\" $param={{{  [<__tiddler__>get[text]] }}}/></$list></$list>\"\"\"><$list filter=\"[<__tiddler__>get[text]minlength[1]]\"><$action-sendmessage $message=\"tm-edit-tiddler\" $param={{{  [<__tiddler__>get[text]] }}}/></$list></$list>\n\n\\define set-next-input-tab(beforeafter:\"after\") <$macrocall $name=\"change-input-tab\" stateTitle=\"$:/state/tab/search-results/sidebar\" tag=\"$:/tags/SearchResults\" beforeafter=\"$beforeafter$\" defaultState={{$:/config/SearchResults/Default}} actions=\"\"\"<$action-setfield $tiddler=\"$:/state/search/currentTab\" text=<<nextTab>>/>\"\"\"/>\n\n\\whitespace trim\n<$vars searchTiddler=\"$:/temp/menubarsearch/input\" searchListState=<<qualify \"$:/state/search-list/selected-item\">>>\n<span style=\"margin: 0 0.5em;\">\n<$keyboard key=\"((input-tab-right))\" actions=<<set-next-input-tab>>>\n<$keyboard key=\"((input-tab-left))\" actions=<<set-next-input-tab \"before\">>>\n<form class=\"tc-form-inline\">\n<$macrocall $name=\"keyboard-driven-input\" tiddler=\"$:/temp/menubarsearch\" storeTitle=<<searchTiddler>> selectionStateTitle=<<searchListState>> \n\t\trefreshTitle=\"$:/temp/menubarsearch/refresh\" tag=\"input\" type=\"search\" focusPopup=\"$:/state/popup/menubar-search-dropdown\" \n\t\tclass=\"tc-popup-handle tc-menu-show-when-wide\" placeholder=\"Search...\" default=\"\" cancelPopups=\"yes\" \n\t\tinputAcceptActions=<<input-accept-actions>> inputAcceptVariantActions=<<input-accept-variant-actions>> inputCancelActions=<<cancel-search-actions>> \n\t\tfilterMinLength={{$:/config/Search/MinLength}} configTiddlerFilter=\"[[$:/state/search/currentTab]!is[missing]get[text]] ~[{$:/config/SearchResults/Default}]\" />\n</form>\n</$keyboard>\n</$keyboard>\n</span>\n<$reveal tag=\"div\" class=\"tc-block-dropdown-wrapper\" state=\"$:/state/popup/menubar-search-dropdown\" type=\"nomatch\" text=\"\" default=\"\">\n\n<div  class=\"tc-block-dropdown tc-search-drop-down\">\n\n<$list filter=\"[<searchTiddler>get[text]minlength[1]]\" emptyMessage=\"\"\"<div class=\"tc-search-results\">Type your search terms</div>\"\"\" variable=\"ignore\">\n\n<$list filter=\"[<searchTiddler>get[text]minlength{$:/config/Search/MinLength}limit[1]]\" emptyMessage=\"\"\"<div class=\"tc-search-results\">{{$:/language/Search/Search/TooShort}}</div>\"\"\" variable=\"listItem\">\n\n<$vars configTiddler={{{ [[$:/state/search/currentTab]!is[missing]get[text]] ~[{$:/config/SearchResults/Default}] }}} userInput={{{ [<searchTiddler>get[text]] }}}>\n\n{{$:/core/ui/SearchResults}}\n\n</$vars>\n\n</$list>\n\n</$list>\n\n</div>\n\n</$reveal>\n\n</$vars>\n"},"$:/plugins/tiddlywiki/menubar/items/server":{"title":"$:/plugins/tiddlywiki/menubar/items/server","tags":"$:/tags/MenuBar","description":"Server options","caption":"Server","custom-menu-content":"<$transclude tiddler=\"$:/plugins/tiddlywiki/menubar/items/server\" mode=\"inline\"/>","text":"<$list filter=\"[[$:/status/IsLoggedIn]get[text]else[no]match[yes]]\" variable=\"ignore\">\n<$transclude tiddler=\"$:/core/ui/Buttons/save-wiki\" mode=\"inline\"/>\n</$list>\n<$list filter=\"[[$:/status/IsLoggedIn]get[text]else[no]match[no]]\" variable=\"ignore\">\n<$button message=\"tm-login\">\nLogin\n</$button>\n</$list>\n"},"$:/plugins/tiddlywiki/menubar/items/sidebar":{"title":"$:/plugins/tiddlywiki/menubar/items/sidebar","caption":"Sidebar","description":"Sidebar","is-dropdown":"yes","tags":"$:/tags/MenuBar","text":"<$scrollable fallthrough=\"none\" class=\"tc-popup-keep tc-menubar-dropdown-sidebar\">\n\n<$transclude tiddler=\"$:/core/ui/SideBarSegments/tabs\" mode=\"inline\"/>\n\n</$scrollable>\n"},"$:/plugins/tiddlywiki/menubar/items/topleftbar":{"title":"$:/plugins/tiddlywiki/menubar/items/topleftbar","tags":"$:/tags/MenuBar","description":"Items from $:/tags/TopLeftBar","caption":"Legacy Top Left Bar","custom-menu-content":"<$transclude tiddler=\"$:/plugins/tiddlywiki/menubar/items/topleftbar\" mode=\"inline\"/>","text":"<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/TopLeftBar]!has[draft.of]]\" variable=\"listItem\" storyview=\"pop\">\n\n<$transclude tiddler=<<listItem>> mode=\"inline\"/>\n\n</$list>"},"$:/plugins/tiddlywiki/menubar/items/toprightbar":{"title":"$:/plugins/tiddlywiki/menubar/items/toprightbar","tags":"$:/tags/MenuBar","description":"Items from $:/tags/TopRightBar","caption":"Legacy Top Right Bar","custom-menu-content":"<$transclude tiddler=\"$:/plugins/tiddlywiki/menubar/items/toprightbar\" mode=\"inline\"/>","custom-menu-styles-wide":"float: right;","text":"<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/TopRightBar]!has[draft.of]reverse[]]\" variable=\"listItem\" storyview=\"pop\">\n\n<$transclude tiddler=<<listItem>> mode=\"inline\"/>\n\n</$list>"},"$:/plugins/tiddlywiki/menubar/menu":{"title":"$:/plugins/tiddlywiki/menubar/menu","tags":"$:/tags/PageTemplate","text":"\\define menubar-inner(size)\n<ul class=\"tc-menubar-list\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/MenuBar]!has[draft.of]] -[all[tiddlers+shadows]tag[$:/tags/TopLeftBar]limit[1]then[]else[$:/plugins/tiddlywiki/menubar/items/topleftbar]] -[all[tiddlers+shadows]tag[$:/tags/TopRightBar]limit[1]then[]else[$:/plugins/tiddlywiki/menubar/items/toprightbar]]\">\n<$list filter=\"[<currentTiddler>addprefix[$:/config/plugins/menubar/MenuItems/Visibility/]get[text]] ~show +[match[show]]\" variable=\"ignore\">\n<$list filter=\"[[$size$]match[wide]] ~[<currentTiddler>get[show-when]match[$size$]] ~[{$:/state/popup/menubar/hamburger}match[yes]]\" variable=\"ignore\">\n<li style={{!!custom-menu-styles-$size$}} class={{{ [<currentTiddler>get[show-when]addprefix[tc-menubar-]] tc-menubar-item +[join[ ]] }}}>\n<$list filter=\"[<currentTiddler>!is-dropdown[yes]]\" variable=\"listItem\" emptyMessage=\"\"\"\n\t<!-- Dropdown -->\n\t<$set name=\"dropdown-state\" value=<<qualify \"$:/state/popup/topmenu/dropdown/\">>>\n\t<$set name=\"dropdown-state\" value={{{ [<dropdown-state>addsuffix<currentTiddler>] }}}>\n\t<$button popup=<<dropdown-state>> selectedClass=\"tc-selected\">\n\t<$set name=\"tv-wikilinks\" value=\"no\">\n\t<$transclude field=\"caption\" mode=\"inline\"/>\n\t<$text text=\" \"/>\n\t<span class=\"tc-menubar-dropdown-arrow\">\n\t<$transclude tiddler=\"$:/core/images/down-arrow\" mode=\"inline\"/>\n\t</span>\n\t</$set>\n\t</$button>\n\t</$set>\n\t</$set>\n\"\"\">\n<$list filter=\"[<currentTiddler>has[custom-menu-content]]\" variable=\"listItem\" emptyMessage=\"\"\"\n\t<!-- Link -->\n\t<$link to={{!!target}}>\n\t<$set name=\"tv-wikilinks\" value=\"no\">\n\t<$transclude field=\"caption\" mode=\"inline\"/>\n\t</$set>\n\t</$link>\n\"\"\">\n<!-- Custom content -->\n<$transclude field=\"custom-menu-content\" mode=\"inline\"/>\n</$list>\n</$list>\n</li>\n</$list>\n</$list>\n</$list>\n</ul>\n\\end\n\n<$list filter=\"[<tv-config-static>!match[yes]]\" variable=\"ignore\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/MenuBar]!has[draft.of]] -[all[tiddlers+shadows]tag[$:/tags/TopLeftBar]limit[1]then[]else[$:/plugins/tiddlywiki/menubar/items/topleftbar]] -[all[tiddlers+shadows]tag[$:/tags/TopRightBar]limit[1]then[]else[$:/plugins/tiddlywiki/menubar/items/toprightbar]] +[limit[1]]\" variable=\"listItem\">\n<nav class=\"tc-menubar tc-adjust-top-of-scroll\">\n<div class=\"tc-menubar-narrow\">\n<<menubar-inner narrow>>\n</div>\n<div class=\"tc-menubar-wide\">\n<<menubar-inner wide>>\n</div>\n<div style=\"clear:both;\"/>\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/MenuBar]!has[draft.of]is-dropdown[yes]]\">\n<$list filter=\"[<currentTiddler>addprefix[$:/config/plugins/menubar/MenuItems/Visibility/]get[text]] ~show +[match[show]]\" variable=\"ignore\">\n<$set name=\"dropdown-state\" value=<<qualify \"$:/state/popup/topmenu/dropdown/\">>>\n<$set name=\"dropdown-state\" value={{{ [<dropdown-state>addsuffix<currentTiddler>] }}}>\n<$reveal type=\"popup\" state=<<dropdown-state>> position={{{ [<currentTiddler>get[dropdown-position]else[below]] }}} class={{{ [<currentTiddler>get[class]] }}} tag=\"div\">\n<div class=\"tc-drop-down\">\n<$transclude/>\n</div>\n</$reveal>\n</$set>\n</$set>\n</$list>\n</$list>\n</nav>\n</$list>\n</$list>\n"},"$:/core/ui/PageTemplate/topleftbar":{"title":"$:/core/ui/PageTemplate/topleftbar","text":"<!-- The menubar plugin overrides this tiddler to remove the core top left menu. The menu items that it would include are instead included in the menubar -->"},"$:/core/ui/PageTemplate/toprightbar":{"title":"$:/core/ui/PageTemplate/toprightbar","text":"<!-- The menubar plugin overrides this tiddler to remove the core top right menu. The menu items that it would include are instead included in the menubar -->"},"$:/plugins/tiddlywiki/menubar/readme":{"title":"$:/plugins/tiddlywiki/menubar/readme","text":"!! Introduction\n\nThis plugin provides a menu bar with the following features:\n\n* Menu items take the form of simple text links, dropdowns, or entirely custom content\n* Menu items can be individually enabled via the control panel\n* Responds to reduced screen width by abbreviating the menu items to a \"hamburger\" dropdown\n\n!! Menu Item Tiddlers\n\nMenu items are tagged <<tag $:/tags/MenuBar>>. The following fields are used by this plugin:\n\n|!Field Name |!Purpose |\n|title |Each menu item must have a unique title (not shown to the user) |\n|description |Description for use in listings |\n|tags |Must contain `$:/tags/MenuBar` |\n|caption |The text that is displayed for the menu item. Avoid links, using `~` to suppress CamelCase links if required |\n|target |For simple link menu items specifies a tiddler title as the target of the link |\n|is-dropdown |Set to `yes` to indicate a dropdown menu item |\n|dropdown-position |Optional position for the dropdown (can be ''left'', ''above'', ''aboveleft'', ''aboveright'', ''right'', ''belowleft'', ''belowright'' or ''below'') |\n|text |For dropdown menu items, specifies the body of the dropdown |\n|custom-menu-content |Optional wikitext to be displayed in place of the caption |\n|custom-menu-styles-wide |Optional string of styles to be applied to menu item when the menubar is wide |\n|custom-menu-styles-narrow |Optional string of styles to be applied to menu item when the menubar is narrow |\n\nCustom menu items should make sure that the clickable link or button is an immediate child, and not wrapped in another element.\n\nNote that menu items can be pushed to the right of the menu bar setting the ''custom-menu-styles'' field to `float: right;`.\n"},"$:/plugins/tiddlywiki/menubar/styles":{"title":"$:/plugins/tiddlywiki/menubar/styles","tags":"[[$:/tags/Stylesheet]]","text":"\\define breakpoint-plus-one()\n<$text text={{{ [{$:/config/plugins/menubar/breakpoint}removesuffix[px]add[1]addsuffix[px]] ~[{$:/config/plugins/menubar/breakpoint}] }}} />\n\\end\n\n\\define sidebarbreakpoint-minus-one()\n<$text text={{{ [{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}removesuffix[px]subtract[1]addsuffix[px]] ~[{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}] }}} />\n\\end\n\n\\define set-sidebar-scrollable-top-if-hamburger()\n<$list filter=\"[all[tiddlers+shadows]tag[$:/tags/MenuBar]] -[all[tiddlers+shadows]prefix[$:/config/plugins/menubar/MenuItems/Visibility/]regexp:text[hide]removeprefix[$:/config/plugins/menubar/MenuItems/Visibility/]] -[all[tiddlers+shadows]tag[$:/tags/TopLeftBar]limit[1]then[]else[$:/plugins/tiddlywiki/menubar/items/topleftbar]] -[all[tiddlers+shadows]tag[$:/tags/TopRightBar]limit[1]then[$:/plugins/tiddlywiki/menubar/items/toprightbar]] -$:/plugins/tiddlywiki/menubar/items/hamburger +[limit[1]]\">\n\n\t.tc-sidebar-scrollable {\n\t\tmargin-top: 2em;\n\t}\n\n</$list>\n\\end\n\n\\define set-sidebar-scrollable-top()\n<$list filter=\"[all[tiddlers+shadows]tag[$:/tags/MenuBar]] -[all[tiddlers+shadows]prefix[$:/config/plugins/menubar/MenuItems/Visibility/]regexp:text[hide]removeprefix[$:/config/plugins/menubar/MenuItems/Visibility/]] -[all[tiddlers+shadows]tag[$:/tags/TopLeftBar]limit[1]then[]else[$:/plugins/tiddlywiki/menubar/items/topleftbar]] -[all[tiddlers+shadows]tag[$:/tags/TopRightBar]limit[1]then[$:/plugins/tiddlywiki/menubar/items/toprightbar]] +[limit[1]]\">\n\n\t.tc-sidebar-scrollable {\n\t\tmargin-top: 2em;\n\t}\n\n</$list>\n<$reveal state=\"$:/state/popup/menubar/hamburger\" type=\"match\" text=\"yes\">\n\n\t<$set name=\"itemCount\" value={{{ [all[tiddlers+shadows]tag[$:/tags/MenuBar]] -[all[tiddlers+shadows]prefix[$:/config/plugins/menubar/MenuItems/Visibility/]regexp:text[hide]removeprefix[$:/config/plugins/menubar/MenuItems/Visibility/]] -[all[tiddlers+shadows]tag[$:/tags/TopLeftBar]limit[1]then[]else[$:/plugins/tiddlywiki/menubar/items/topleftbar]] -[all[tiddlers+shadows]tag[$:/tags/TopRightBar]limit[1]then[]else[$:/plugins/tiddlywiki/menubar/items/toprightbar]] +[count[]] }}}>\n\n\t\t.tc-sidebar-scrollable {\n\t\t\tmargin-top: calc(<<itemCount>> * 2em);\n\t\t}\n\n\t</$set>\n\n</$reveal>\n\\end\n\n\\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline\n\nnav.tc-menubar {\n\tposition: fixed;\n\tz-index: 850;\n\tdisplay: inline-block;\n\ttop: 0;\n\tright: 0;\n\tleft: 0;\n}\n\nnav.tc-menubar ul.tc-menubar-list {\n\tposition: relative;\n\tlist-style-type: none;\n\tmargin: 0;\n\tpadding: 0 0 0 42px;\n\tbackground: <<colour background>>;\n\tbackground: <<colour menubar-background>>;\n\t<<box-shadow \"1px 1px 5px rgba(0, 0, 0, 0.3)\">>\n}\n\n@media (max-width: <<sidebarbreakpoint-minus-one>>) {\n\n\thtml nav.tc-menubar ul.tc-menubar-list {\n\t\tpadding: 0 0 0 8px;\n\t}\n\n}\n\nnav.tc-menubar li.tc-menubar-item {\n\tdisplay: inline-block;\n\tmargin: 0;\n\tpadding: 0;\n}\n\nnav.tc-menubar .tc-menubar-narrow li.tc-menubar-item {\n\tdisplay: block;\n}\n\nnav.tc-menubar li.tc-menubar-item > a,\nnav.tc-menubar li.tc-menubar-item > button {\n\tdisplay: inline-block;\n/*\ttext-transform: uppercase; */\n\tline-height: 1;\n\tfont-weight: 700;\n\tcolor: <<colour foreground>>;\n\tcolor: <<colour menubar-foreground>>;\n\tfill: <<colour foreground>>;\n\tfill: <<colour menubar-foreground>>;\n\ttext-decoration: none;\n\tpadding: 0.5em;\n\tmargin: 0;\n\tbackground: none;\n\tborder: none;\n\tcursor: pointer;\n\tborder-radius: 0;\n\ttext-decoration: none;\n}\n\nnav.tc-menubar li.tc-menubar-item > a.tc-selected,\nnav.tc-menubar li.tc-menubar-item > button.tc-selected {\n\tbackground: <<colour foreground>>;\n\tbackground: <<colour menubar-foreground>>;\n\tcolor: <<colour background>>;\n\tcolor: <<colour menubar-background>>;\n\tfill: <<colour background>>;\n\tfill: <<colour menubar-background>>;\n}\n\nnav.tc-menubar li.tc-menubar-item svg {\n\ttransition: none;\n\twidth: 1em;\n\theight: 1em;\n\tfill: <<colour foreground>>;\n\tfill: <<colour menubar-foreground>>;\n}\n\nnav.tc-menubar li.tc-menubar-item .tc-menubar-dropdown-arrow svg {\n\twidth: 0.5em;\n\theight: 0.5em;\n}\n\nnav.tc-menubar li.tc-menubar-item > a.tc-selected svg,\nnav.tc-menubar li.tc-menubar-item > button.tc-selected svg {\n\tfill: <<colour background>>;\n\tfill: <<colour menubar-background>>;\n}\n\nnav.tc-menubar li.tc-menubar-item > a:hover,\nnav.tc-menubar li.tc-menubar-item > button:hover svg,\nnav.tc-menubar li.tc-menubar-item > button:hover {\n\tbackground: <<colour foreground>>;\n\tbackground: <<colour menubar-foreground>>;\n\tcolor: <<colour background>>;\n\tcolor: <<colour menubar-background>>;\n\tfill: <<colour background>>;\n\tfill: <<colour menubar-background>>;\n\tborder-radius: 0;\n\ttext-decoration: none;\n}\n\nnav.tc-menubar li.tc-menubar-item > a:active,\nnav.tc-menubar li.tc-menubar-item > button:active svg,\nnav.tc-menubar li.tc-menubar-item > button:active {\n\tbackground: <<colour foreground>>;\n\tbackground: <<colour menubar-foreground>>;\n\tcolor: <<colour background>>;\n\tcolor: <<colour menubar-background>>;\n\tfill: <<colour background>>;\n\tfill: <<colour menubar-background>>;\n\tborder-radius: 0;\n\ttext-decoration: none;\n}\n\nnav.tc-menubar .tc-drop-down,\nnav.tc-menubar .tc-block-dropdown {\n\tmax-width: 70vw;\n\tmax-height: 70vh;\n\toverflow: auto;\n}\n\nnav.tc-menubar .tc-drop-down a {\n\ttext-decoration: none;\n}\n\nnav.tc-menubar .tc-drop-down .tc-table-of-contents button {\n\tdisplay: inline-block;\n\twidth: auto;\n}\n\nnav.tc-menubar .tc-drop-down ol {\n\tmargin: 0;\n}\n\nnav.tc-menubar .tc-drop-down .tc-menubar-dropdown-sidebar a,\nnav.tc-menubar .tc-drop-down .tc-menubar-dropdown-sidebar button {\n\tdisplay: inline;\n\twidth: auto;\n}\n\nnav.tc-menubar .tc-more-sidebar > .tc-tab-set > .tc-tab-buttons > button {\n\tdisplay: block;\n\twidth: 100%;\n}\n\n@media (max-width: {{$:/config/plugins/menubar/breakpoint}}) {\n\n\t.tc-menubar-wide {\n\t\tdisplay: none;\n\t}\n\n}\n\n@media (min-width: <<breakpoint-plus-one>>) {\n\n\tnav.tc-menubar li.tc-menubar-item.tc-menubar-narrow,\n\t.tc-menubar-narrow {\n\t\tdisplay: none;\n\t}\n\n}\n\n@media (max-width: <<sidebarbreakpoint-minus-one>>) {\n\n\t<<set-sidebar-scrollable-top-if-hamburger>>\n\n}\n\n@media (max-width: {{$:/config/plugins/menubar/breakpoint}}) {\n\n\t<<set-sidebar-scrollable-top>>\n\n}\n@media print {\n\n\tnav.tc-menubar {\n\t\tdisplay: none;\n\t}\n\n}\n"},"$:/tags/MenuBar":{"title":"$:/tags/MenuBar","list":"$:/plugins/tiddlywiki/menubar/items/hamburger $:/plugins/tiddlywiki/menubar/items/topleftbar $:/plugins/tiddlywiki/menubar/items/contents $:/plugins/tiddlywiki/menubar/items/search $:/plugins/tiddlywiki/menubar/items/pagecontrols $:/plugins/tiddlywiki/menubar/items/server $:/plugins/tiddlywiki/menubar/items/toprightbar"}}}



450px
fluid-fixed
3316699902_c3d93e61ce.jpg


!! Using the AIM cards for Active Planning

<center>{{AIM cards pic1.jpg}}</center>

The AIM cards are an example of applying the [[Active Planning]] triangle in practice.They are used to ''sensitively attune'' to the clients' perspectives, to ''broadcast our intentions'' as the worker, and to begin developing a focus or structure for work together. The AIM cards can be used as a goals-based outcome measures to develop and measure specific goals based on what matters most to the client.

>//This is an example of a page that has been ''cloned and customised'' from the original work by the ''AMASS team in Islington'' - to whom we are immensely grateful.//

*This video produced by the AMASS team in Islington (@ambit-amass) shows an example of how the cards can be used in a session with a client:

<html><iframe width="420" height="315" src="//www.youtube.com/embed/wG9Of1PCHPI" frameborder="0" allowfullscreen></iframe></html>

The AMASS Team have developed a framework for using the AIM cards. Their suggested steps and learning points are set out below. Here we also highlight examples of the ''active planning triangle'' with the intention of showing how active planning may look in practice. 

''Please note this framework can be adapted according to the client and service context''.

''When to use the AIM cards''

The AIM cards are usually used fairly early on in the contact with the client, as part of efforts to build a relationship. It is usually helpful that the client has met the worker at least once before using the cards. Exactly when they're used will vary according to the degree to which the worker thinks that the client would find it ok to share a bit about how things are with someone who they don't know/yet trust and the extent to which they are actively help-seeking.

It can be helpful to hold in mind that using the cards can help build [[Epistemic Trust]], if the worker takes care to reflect back what they are learning about the clients' perspective from completing the cards ''(senisitive attunement)''


Similarly, a client does not have to be actively or explicitly help-seeking in order for the cards to be used. In fact, it can be more helpful for the worker not to assume any help-seeking on the part of the client when using the cards, instead holding in mind that their first priority is to understand how life is currently from the clients' perspective ''(sensitive attunement'') 

''1. Introducing the cards''-
the worker should explain to the client what the cards are and their purpose. This is an example ''[[Broadcasting Intentions]]''.

>//I've bought some cards along that I do with lots of young people when I'm trying to get to know them. These cards have got different topics on that relate to different areas of a young person’s life//

>// I'd like to try to understand a bit how life is for you at the moment, to see if there's anything I could be helpful with - how does that sound?//


>//If you're not sure, you can take a look at the cards and then decide if you'd like me to bring them again another time - that's totally fine too
''(sensitive attunement)''//

''2. Agree how to look through the cards'' - Would they prefer to read through the cards themselves? or if they would like them to be read out by the worker? Remind them they can always ask for help with reading and can ask you questions if there are any that they are not sure about.

''Agree on how to divide up the cards - as a first step, usually 3 piles:''

*Things that are difficult/a problem

*Things that are going well/are strengths, and

*It doesn't apply to me


''3. Client sorts through the cards''-
allow the client to take the lead.
The worker should try to notice how actively the client looks to involve the worker in the process, and attune to this. The worker should hold in mind that using the cards is about understanding the clients' ideas about their life ''(sensitive attunement)'' rather than the worker seeking to influence these.  

Quite often, some extra piles can develop (i.e. sometimes a problem; not sure etc).

Pay attention to how much the client seems able to tolerate naming something as a difficulty – some people will describe thngs in a high impact way “Really hard for me”; others will only be able to acknowledge something being difficult, but with minimal impact (i.e. sometimes a problem). Either way, we consider anything that is labelled as a bit of a difficulty as something that constitutes a “problem” and we don't talk it up or down in terms of severity or frequency - go with the clients' current description ''(sensitive attunement'').

Similarly, notice how easy the client finds it to identify strengths and attune to their level of comfort with this.

Check in on how they found the process of sorting and if it would be ok for you to ask a bit more about some of the cards.

''4.Exploring the strengths pile''-
start with the strengths – explore each of these in detail. The purpose is to show interest and build a bit of an understanding about areas of life that are going well.


It can be helpful to offer some summaries back about what you feel you are learning about them, their skills, strengths and abilities as you look through this pile ''(sensitive attunment)''.

In time, it can be helpful to support the client to think about how their strengths might help with some of the areas they are finding more difficult. Time spent focusing on strengths may also help them to feel comfortable in the session and potentially more open to move onto exploring aspects of their life that might feel more difficult.

''5. Exploring the difficulties pile''-
lay out the difficulties cards on the table. Ask them if they would be ok with talking you through why they chose these cards as difficulties. If so, ask where they would like to start.

Again, attune to how much exploration the client can tolerate, so that they are not feeling pressured into talking about things that are too uncomfortable or difficult ''(sensitive attunement)''.

Comment on the process in a sensitive manner - i.e. let them know how well they are doing about thinking about something that’s difficult; notice if they are finding it hard; check if they are ok to continue.

Follow the clients' lead in terms of how much they wish to share about these cards at this stage. Using the cards can help us learn how able the client is to think about themselves and their situation and how much they feel willing/able/ready to accept some help with these matters ''(sensitive attunment).''


''6. Exploring how the cards fit together''- it can be helpful to explore whether the client feels that there are any links between the cards that they have chosen. 

Ask them to arrange the cards around to reflect this – for example, difficulties at school or with family might go together with a series of other cards.

Let the client take the lead in this. Usually, this process results in the cards being sorted into a smaller number of groups, around particular themes (e.g. how things are at home or at school or with friends, for example). The worker can ask questions to gain an understanding of why the client feels that certain cards go together, supporting them in the process of trying to make some sense of how these areas of difficulty might fit together and be influencing each other.



''7. Explore whether there is anything that the client might want help with''-
 it is important that workers do not assume that a client wants to have help (from them) just because they have identified something as an area of difficulty.

With this in mind, it can be helpful for the worker to:

Ask the client whether there are any of the difficulty cards that they would like to see looking a bit different. Are there any areas that they would make a change to if they could? If they identify some, check in about whether its something that they think you could be useful for by meeting together. Which cards would be their priority to focus on (usually 2-4 cards is realistic).

Here is a point where we may ''broadcast intentions''

>// I’d really like to be helpful if I can, so if there were any of the cards here that you feel you would like some help with, then I would be happy to try to help if I can//

Attune to the degree to which the client seems comfortable with the idea of being in need – it may be more appropriate to position them as the expert.

>// You’ve got a lot of strengths/things you’re good at; maybe we can figure out a way that those could help with the things that are feeling more tricky at the moment//

''8.Contract what help might look like and where to start''-
think with the client about how to turn these cards into goals, decide which they would like to start with and think about how you might begin to work on these cards together ''(making a plan!)''.

!!Using AIM cards to measure outcomes:



*The client can rate the severity of the problem indicated on the card (or cards) that they feel are most important to change or to focus on. They are able to rate how much this affects them at the moment, using the numbers on the cards. This can then be used as a goals-based outcome measure and tracked over the course of the work together. This is a helpful way of checking 'how are things now?' in relation to what matters most to the client in comparison with the beginning of the work together.  If the clients' rating is not changing, or getting worse this is also really important, as it can open conversations about why this might be, what might need to change for the ratings to move from x to x. Ratings can be plotted on a graph showing progress or change over time. This can also be shared and reflected on with the client. 

*At the end of the intervention the AIM card session can be repeated and the ratings of the chosen cards can be compared from the pre-intervention AIM card session. 







 
* Being curious about what the young person brings, rather than assuming things or trying to jump to solutions straight away
* Being curious about the card they have chosen – not assuming that you know why they have chosen a particular card or what it might have meant to them. 
* Not making assumptions about what links together – taking time to explore it
* Being curious about the process of using them – mentalizing what is it like to have things bought up that they might not have usually bought; what might it be like to see a big pile of challenges or not many strengths etc
* Being curious about what thoughts/feelings might come up for a young person while doing the task – tuning in to what it seems like for the young person to do the cards. Not just about the end point of finishing the cards; remembering to sensitively attune. Taking responsibility as a worker for supporting a young person to remain in a regulated zone. 
* Could use to support perspective taking – what do you think your Mum/teacher would pick? Do you think anyone else would see this differently? What do you think your teacher would say if he/she could see which ones you’d picked?

We have produced 3 sets of <<tag [[AMBIT playing cards]]>> for use within supervision or case discussion contexts, which are based on ideas from several different AMBIT teams who had developed and used such cards in their team meetings. Each of these card sets is described below. 

''AMBIT stance cards''

The AMBIT stance playing cards were developed by the CASUS team, a substance use service for adolescents in Cambridgeshire. 

{{AIM cards pic1.jpg}}

Each area of the AMBIT stance is printed on individual cards which are dealt out to team members. Each team member is responsible for holding that particular area of the stance in mind during the discussions. The purpose of this is to support a team to remain "on balance" by attending to the four different domains of AMBIT - Client, Team, Network and Learning - within the discussion taking place. 

''AMBIT Marking the Task cards''

The AMBIT Marking the Task cards are based on cards developed by the AMASS team in Islington, an edge of care team for adolescents, for use in their weekly group supervision. 

{{AMBIT Marking the Task cards}}

The purpose of the cards is to assist team members in [[Marking the Task]], which is the first of the four steps in [[Thinking Together|Thinking Together]]. The cards contain a number of different categories of task that a worker might want help with. Sometimes selecting a clear and specific task can be a challenge for workers, particularly since the experience of having a dilemma or feeling stuck is often related to a loss of mentalizing, which can make it more challenging for a worker to think through "//What exactly do I need help with?//".  The intention of getting a worker to select the relevant card and place it on the table is therefore to help with both the identification of the task and to create a playful way of helping the worker and the team hold the boundary around being clear about task //before //moving into [[Stating the Case|Stating the Case]] i.e. ("//You can't start until you've chosen your card and helped us understand what the task is//!"). 

''AMBIT usual suspects cards''

Developed by CASUS workers, the AMBIT usual suspects cards are intended to be given out to team members who are wanting to assist a worker in thinking about ''Dis-integration'' within a network. 

{{AMBIT usual suspects cards}}

The worker can select the relevant professionals from the pack of cards, assign each of these cards to a member of the team and ask each team member to mentalize that worker's perspective in the discussion that follows. This may help to identify areas of agreement, dis-integration and possibilities for Connecting Conversations that may be helpful. Additionally the cards may be used within a group discussion or individual supervision to “sculpt” a network in order to make sense of the client’s system of help, visually map out dis-integration and consider the the differing perspectives. This is a quick and easy alternative to the [[Sculpting a Network]] exercise and use of [[The AMBIT Pro-Gram]].
This page provides you with a list of all the pages that are relevant to the AMBIT Training. You may come across some broken links as these pages have been copied across the AMBIT manual - bear with us while we try to sort through these!

!!Pages on AMBIT
<<list-links "[tag[TrainingCore]tag[TrainingCore]]">>

!!Pages from training

<<list-links "[tag[AMBIT Training]tag[AMBIT Training]]">>
[[AMBIT Wiki|https://manuals.annafreud.org/ambit/index.html]]

[[AMBIT learning at work|https://manuals.annafreud.org/ambit/index.html#LEARNING%20at%20work:%5B%5BLEARNING%20at%20work%5D%5D]]

{{nathan-anderson-kTaIjvHsyJg-unsplash.jpg}}

!!''What is AMBIT? ''

* A Mentalization-based approach, designed for teams and services who work with clients presenting with multiple and complex problems
*AMBIT has been developed with a focus on those for whom help-seeking, or using conventional forms of help, can be particularly challenging

* AMBIT works to support services in developing systems of care adapted to their local context and client group
*AMBIT is guided by a central theory- [[Mentalization]]- which is applied in a conscious and deliberate way to 4 areas of practice:

**''In direct face to face work'' - Applying a [[Mentalizing Stance|The Therapist's Mentalizing Stance]] to therapeutic work.
**''Between members of the team'' - The ways in which colleagues support each other in their work to foster a [[well-connected team|Keyworker well-connected to wider team]].
**''To the wider professional network'' - The way in which the service relates to and supports the complex network of professionals that often develop around this client group.
**''To the way in which teams learn about their work'' - Through encouraging a culture of continuous learning and adaptation.

The range of problems that AMBIT-influenced services address are varied, there may be many different treatment aims- addressing clients' fundamental Relationship to help is often one of the core treatment aims shared by the many services that use or adapt this approach.

!!!(<4 mins) A very brief introduction
By AMBIT Trainers Liz Cracknell and John Lincoln

<html><iframe width="480" height="360" src="https://www.youtube.com/embed/NusFc_HrYRM?rel=0" frameborder="0" allowfullscreen></iframe></html>


!!!(10 mins) The AMBIT model

<html><iframe width="560" height="315" src="https://www.youtube.com/embed/HrEgDdsohNo" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></html>

!!In summary…

''AMBIT is NOT:''

* A ''"one-size-fits-all"'' rigidly-determined "tick-box" approach to therapy
* A new form of individual therapy
* A template for team structure and organisational arrangements
* An approach for specific psychiatric disorders
* An approach that can only be delivered by statutory services

''AMBIT is:''

* A ''mentalization based approach''
* A team approach
* An approach for clients with severe and complex problems including mental health problems 
* An approach for clients who may have a very poor or negative relationship to help
* An outreach approach, but one which can be adapted for other types of service delivery
* An approach that emphasises relationship building and uses ideas from Attachment theory




* A manualized framework with a strong emphasis on supporting local adaptations and further development of the model within a local context (see[[ Manualization|Manualization]])


AMBIT's name changed recently from Adolescent Mentalization Based Integrative Treatment to ''ADAPTIVE Mentalization Based Integrative Treatment'', because many of the clients that teams using this approach are working with now fall outside the category of adolescence.


''The Core Features of AMBIT''

For the worker the [[Core Features of AMBIT]] are intended to be practical "grab-rails" - which describe a STANCE - and important features of PRACTICE, that are designed to help the worker stay 'on track' - especially at those times of high stress or anxiety that are common in this work. The AMBIT Wheel is an attempt to present them in a simple and memorable way.


!!!(<10 minutes) Walking through the Wheel
See the [[Core Features of AMBIT]] for more

<html><object width="420" height="315"><param name="movie" value="https://www.youtube.com/v/VC-xzsR89s0?hl=en_US&amp;version=3&amp;rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="https://www.youtube.com/v/VC-xzsR89s0?hl=en_US&amp;version=3&amp;rel=0" type="application/x-shockwave-flash" width="420" height="315" allowscriptaccess="always" allowfullscreen="true"></embed></object></html>


''For those who would like to read and watch more, below you will find more text and links explaining in further detail (and in slightly different ways) what AMBIT is, as well as directing you to other useful pages////.''


*In 2017, a 'book of the AMBIT wiki' was published by Oxford University Press - and there are a number of publications too, find these at Academic references

!!''Feedback from AMBIT-influenced teams''
Here are some comments received in a 2014 survey of teams who have undertaken AMBIT training.

>>"//AMBIT has been helpful in bringing together a shared sense of purpose for a team while under re-organisation//"

>>"//Team was newly set up when AMBIT training was attended so it has been key to the team's development and ethos from the beginning.//"

>>"//We continue to use AMBIT as a focus to ensure that we work in a different way. AMBIT is becoming the language by which we do this//"

>>"//Has offered a set of principles for working with complex systems organised around mentalizing which we can compare ourselves against and relate to as we develop how we work//".

>>"//We are growing a pilot multidisciplinary young person's service (including support for providers of youth services) ... and find that AMBIT helps us better support young people as well as build non-adversarial and positive working relationships with colleagues from other services//"


----

!!Relevant links
# [[Core Features of AMBIT]] - This should be your next step in understanding AMBIT - it provides the main "grab rails" for a practitioner to remember that determine his or her STANCE in the work, and the key features of PRACTICE that flow from this. 
# [[Mentalization]] - This is the key supporting theory, that shapes specific work with the young person and family, and the work of the team. 


   !!''What is Active Planning ? ''
<center>{{ap..png}}</center> 

* Active Planning is a practice that underpins how we make plans together with clients


* It is a way of helping maintain an appropriate balance between having a purpose, being open about our intentions, and attuning to what's happening in the here and now

*It involves applying [[Mentalizing|Mentalization]] to the process of making and working to plans

This is a 10 minute teaching session on Active Planning by Dickon Bevington at a training for AMBIT Local Trainers:

<html><iframe width="640" height="360" src="//www.youtube.com/embed/v8BeQeABRvM" frameborder="0" allowfullscreen></iframe></html>

!!Why focus on planning?
Evidence-based approaches tell us that having clear and jointly constructed goals and plans are essential to creating change. 

However, there are a number of factors that can make planned work difficult in the contexts within which AMBIT influenced teams work. 

''These can be related to both:''

''1.Worker barriers'',

for example:

*Challenging work in isolation or without strong connections to team members  ([[Keyworker well-connected to wider team]]) to help think about where the work is headed and what might need to happen next
*Working within a team where members do not feel confident or supported adequately to raise and address difficult issues with their clients
*A stressed or overwhelmed worker (and/or team) meaning there is less capacity to ''mentalize'' the client and attune to what might be important or helpful for them in the 'here and now'. 

''2. Client barriers'', 

for example:

*For people who have complex and multiple problems and a fragile Relationship to help, trusting that a plan is well intentioned or that it may be useful, can be a significant challenge
*Motivation can fluctuate and there may be important reasons for keeping things as they are 
*States of mind may shift rapidly and  the ability to focus on a plan changes
*Intentions or priorities shift
*Previously unknown problems or crises can arise which need attending to.


''In practice these barriers can look a bit like.....''

* Meetings overun and things that were agreed don't get thought about
*The focus seems to change constantly between or within meetings

*Lots of talking but not much action

*A worker imposing their own ideas about what would be helpful, or allowing the client to lead without any particular purpose or input in our mind.

!!How do you do it?

''Active planning is about holding a balance between 3 key points:''

1. In any therapeutic interaction the worker having a ''purpose'' (i.e. a plan) in mind about 'what we're trying to do here and why', is essential

2. Our purpose or intention should be made open and explicit. We call this [[Broadcasting our intentions|Broadcasting Intentions]]

3. At the same time, we aim to attune to the clients situation and state of mind 'in the moment'. We call this ''sensitive attunement''.

We can apply these principles to any planned work with a client, from making a brief phone call, to setting overarching care plans (which some teams use to guide their work towards goals).

Below is an example of how we might structure the start of a session or a meeting with a client, holding in mind the active planning triangle:


>// Last week you were talking about how cutting down the self-harm is the most important thing that you want to change in your life right now....I was thinking that it would be really helpful for us to understand more about the self-harm and why it happens ''(purpose/ plan)''.  If we can understand better some of the things that lead to self-harm, we can start to think more about what might need to change ''(Broadcasting intentions)''.  How do you think that would be for you to think about today?...are there other things we might need to talk about too? ''(sensitive attunement)''//


We suggest using the [[AIM cards|AIM Cards]] as a way of applying active planning in practice to develop collaborative plans with clients. The AIM cards give a structure to support clients think through and prioritise the most important areas for them, whilst the  worker listens and attunes to the clients' perspective  (sensitive attunement). The cards then allow workers to contribute their own ideas (Broadcasting intentions) in designing a joint plan about the way forward.


!!Holding the balance

The 3 points of active planning do not follow any particular order. Rather, by the worker mentalizing themselves and their client, we attempt to hold an appropriate balance between them. 

 
If we can maintain sensitive attunement to the clients' state of mind and situation it is more likely they will experience our offers of help as 'fitting' with where they are at (whether our offer of help is ''contingent''). 

For example, rigidly sticking to a plan from last week, with a client who arrives overwhelmed by an argument at home, may well undermine the client-worker relationship. This would be an example of a worker in teleological thinking or ''Quick fix'' one of the Features of unsuccessful Mentalizing.

At the same time, if we were only focusing on sensitive attunement, this would risk losing the worker (and teams') perspectives on other factors, such as risks, or situations that can't be ignored. This might take on a kind of Pretend mode thinking where we are not addressing some important realities. 

The above points are held in balance with , [[Broadcasting Intentions|Broadcasting Intentions]]. Here the worker is explicit and open about their purpose, in order to make their behaviour understandable. We assume that our intentions and behaviour are not clear to our client, (or, that they may expect that we have negative intentions). In this sense, we try to increase the chances that a client can clearly understand our intentions (i.e. mentalize us, the worker), and opt in or out of a plan, rather than it being experienced as something done //to them//. Again, the worker attempts to balance this appropriately, as over-reliance on broadcasting intentions would be another example of Pretend mode (or ''waffle'') and not connected with the experience of the client in the 'here and now'.


''Please see here for a tool to support active planning with clients:''

The Egg and Triangle is a tool that we would usually use after early contact with a client as a way of explicitly sharing our 'best efforts at understanding so far' (broadcasting our intentions and sensitve attunement). This allows the opportunity to 'correct' and further adapt this understanding together (sensitive attunement), based on the clients' perspective. This helps us begin shaping a collaborative plan about the work ahead. 


<<image [[ {{ActivePlanningTriad}} ]] width:560 height:480>>



!!''Video example: Active Planning in action''

Balancing sensitive attunement with the need for work towards a planned focus is a constant dilemma for the worker, and one which may need help from Supervisory Structures in the team.

Here, a worker's initial plan is clearly out of sync with the dilemma that the young person is wrestling with, and adjustment is required:

<html><object width="560" height="315"><param name="movie" value="//www.youtube.com/v/tdXhCvXHcY0?version=3&amp;hl=en_GB&amp;rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="//www.youtube.com/v/tdXhCvXHcY0?version=3&amp;hl=en_GB&amp;rel=0" type="application/x-shockwave-flash" width="560" height="315" allowscriptaccess="always" allowfullscreen="true"></embed></object></html>

----

''The Active Planning Triangle is not only applied to face to face client work. We can equally hold this stance in any situation where we are working towards plans in relationship with others.''

For example;
  

*A meeting with professionals in the network around a client,

If these three points become un-balanced there is a risk that network meetings fall into lots of discussion or broadcasting of intentions, without any clear plans or actions taking place (''pretend mode''). On the other hand, losing balance could mean too much rigid setting of plans without sensitive attunement to the clients' immediate situation (or to the workers' current state of mind). We suggest that this can be a helpful stance when chairing or running meetings in this context.







 



This page gathers together our ideas about how we are applying [[Active Planning|Active Planning]] in our work. 

In a helping interaction, there is a worker, the client and the plan. The plan (both the overall plan for the work and what is going to happen in each interaction/session) needs ideally to be collaboratively agreed between worker and client. This involves the worker showing curiosity towards the client in trying to understand what they might be thinking/feeling, as well as sharing with the client what is going on in their own mind, to help the client make sense of their behaviour and intentions. This is an example of applying the idea of mentalizing to collaborative working - neither the client nor the worker can read each other's minds! Reaching shared understandings upon which to base plans is the purpose of holding an active planning stance. 

''__Active Planning during the engagement and assessment phase__
''

When we are meeting clients for the first time, we are [[broadcasting our intentions|Broadcasting Intentions]] to help them make sense of our behaviour. This might include explaining who we are, what our role is and most importantly why we are there. Most of the time, it is useful to be explicit about our intention to be helpful and we might also be able to be specific about what we are there to be helpful with (i.e. helping school to work a bit better for you; to help with how you are feeling at the moment). We should be mindful to balance transparency with not imposing a focus for the work on the young person which may be coming from someone else, not them. 

The first phase of the work focuses on building engagement and getting to know the young person. It might be possible to do this through a more structured assessment process or a young person may be more easily about to share things about themselves and their current situation through more creative activities, such as games or quizzes. Either way, the principle that we are holding in mind is that of ''sensitive attunement'' - we want to understand how things are for the child or young person at the moment, which we imagine will include a mixture of things that are going well and things that feel a bit more tricky. 

Some young people may find it hard to tell a worker about how things are for them through just being invited to talk or being asked questions, so we might need to find ways to scaffold this process. It is helpful for a worker to try to mentalize the likely experience of the young person - what is going to the best way for this child to share how things are for them? Some workers may choose to ask the client this directly or to think with those who know the client (i.e. the referrer) for any ideas they have about how this might be best facilitated.

 For adolescents, we can use the [[AIM cards|AIM Cards]] to help with building an understanding about how things are for them in terms of current strengths and needs, how these fit together and whether there are any particular needs that they would like to have some help with. We are going to trial using these online. 

For younger children, we have made an adapted version of the AIM cards, to help provide some structure to help them both think about and express how things are for them at the moment. 

Using active planning to set session agendas

It is helpful for the worker and client to have agendas for the sessions. Generally speaking, the worker will have some objectives in mind that they may want to achieve through the session. It is helpful to share these with the young person, both to check that this ok and also to ask them what else they feel it would be helpful/important to cover. 

Workers should remember to be clear about WHAT they want to do and WHY this might be helpful. If goals have already been set, it is useful to explain how the plan links to the goals:

//"One of your goals is to get some help with anger, so I have bought an activity today to help us work out the kinds of things that make you feel angry"//

! __Dilemmas that come up that active planning might help with__

Although the above description talks about applying these ideas to interactions with children and young people, they are helpful for interactions with other "clients" that we have (i.e. parents, teachers, other professionals). 

*''I attended a school meeting and didn't get to ask the questions that I wanted - the teachers were just giving me a lot of information, talking about how difficult things are and asking me what I was going to offer!''

It is very understandable that this might happen, given how stressed referrers might be when they come to us for help. It might be hard for them to organise their own thinking about what information it might most feel relevant to share, particularly if there are strong feelings around. Generally speaking, it is helpful to start meetings by broadcasting your ideas about how the meeting might most usefully run, so that the meeting has some structure and that people are talking about the same things at the same time rather than everyone going into different aspects of the situation simultaneously, which may be hard to keep up with. 

//'Today I thought we could use the time for me to hear about your concerns about the young person, things that are going well and what you are hoping to get from a piece of work from the WEST team. We can go through each of those things in turn - where do you want to start?'//

*''I explained some breathing exercises to a young person but I don't think they were really that bought into them. How can I get them to use them?''

In our efforts to be helpful, we can sometimes forget that something that might seem helpful to us is not necessarily perceived as helpful by someone else. Strategies are a good example of this - they are simply some things that some people have found to be helpful. We can ask young people from their own ideas about what might help the with a particular issue, before making suggestions. If we are going to make suggestions, we should mark this explicitly (//"I could share some things that other young people have found helpful"//). It is really important to remember to offer strategies in a collaborative way - to broadcast clearly the thinking behind them, but to balance this with sensitive attunement, i.e. to check in what the young person thinks about them. We can still take a position of providing encouragement to young people to try things out and a spirit of experimentation around this - 

//' I thought I would show you x, which some young people have found helps them with y. Here's a bit about what it is and how it works. We could try out an example now and you can tell me what you think about it.... Do you think this is something that you'd like to try out this week and then you could let me know how you found it?'//

The clearer we are about the purpose of particular strategies that we are sharing, the easier it will be to find alternatives if they don't fit for the young person. We should avoid falling into positions of certainty (i.e. //"I think that this strategy is helpful/the evidence says this strategy is helpful and therefore it must be"!//)








<<tag [[Addressing Dis-integration]]>> brings together the practices and tools that AMBIT influenced teams may use when working with their networks, trying to work in integrated ways and reduce Dis-integration. 

!!Firstly.....

To address Dis-integration effectively, we propose that first of all we need to re-shape our expectations...

!!//Anticipating// misunderstanding and conflict

A fundamental assumption is that network differences and conflicts should be ''//anticipated as inevitable//'' and not be seen as an indication that people in the network around the client are somehow //''getting it wrong''//.

 AMBIT adopts a position that ''actively anticipates the likelihood of conflict and contradiction between agencies or professionals'', and promotes the explicit view that this is //understandable//, as an aspect of ''our best intentions and best efforts'' to provide services for the client.  

<a class="tc-float-right">[img width= 600 [Dis-integration pic.jpg]]</a>

!!What to do?  

With shared understanding of the problem, agreed intervention and collaborative relationships, effectiveness will improve

!!The Dis-integration Grid


The [[Dis-integration grid]] is a practical tool aimed at supporting Mentalizing of the network. It helps us to think about which parts of the system may be helping or hindering integration and where we may be able to bring a helpful influence towards integration.


!!Sculpting a network

The Sculpting a network exercise which is a way of physically mapping and making sense of network dis-integration. This is an exercise that can be carried out with your team.

!!AMBIT Pro-Gram
[[The AMBIT Program|The AMBIT Pro-Gram]] is a tool for workers to use with clients to help them map out and make sense of their network. It is a way of thinking with clients about which relationships are most helpful for them, who members of the network are and what they do. It is also used for the worker to understand how the client see's these areas and to guide the worker in how they might support or scaffold the existing relationships.

!!Training Exercises

There are other training exercises on working with your network here that explicitly encourage workers to practice mentalizing the network or each other in your team. These include wearing different hats exercise and the what's it like to be exercise.

 
!!Why do we do this? 

The purpose of paying close attention to the wider network is partly to improve the effectiveness of interventions, but it also consistent with the overall mentalizing stance of AMBIT.  One of the core aims for the keyworker is to help the client //make sense of the professionals' behaviours// - by encouraging the client and family to mentalize. 

In our view, [[Mentalization]] provides a crucial technique in trying to help professionals to make sense of each others' behaviour, and hence reduce mis-understandings in the same way. We believe this opens up opportunities for authentic collaboration between members of the network.

!!Addressing Disintegration Video

Liz Cracknell 
<html><iframe width="560" height="315" src="https://www.youtube.com/embed/QxCNC08TJo8" frameborder="0" allowfullscreen></iframe></html>

''Examples of Behaviours''

*Being defiant
*Oppositional
*Impulsive
*Answering back
*Rude
*Shouting
*Not doing what asked
*Passive within relationships with parents
*Leaving house without permission, and not sharing with whereabouts (Push vs. Pull factors)
*Parent relationships – not having helpful conversations e.g. annoyed at young person, low mood themselves 

''Understanding the context - network vs. family''

*Distinguish a plan of where the work is going to be focused. Is the behaviour manageable via parents, or does it involve the network and fall under, e.g. social care

''Thinking about the intervention''

*Strengths and weaknesses
*Trying to identify the causes
*Shared agreement on goals 

-Agreement initially about what  is going on in the house e.g. “Let’s think about why … might be …” (Rules too harsh / no rules / implementation of rule – praise?)

-Once you have secured a goal, you need to secure agreement on how it is going to be solved. “Not always helpful for one person to do something, everyone can do something differently – this will help the work to occur faster 

-Key to involve parents as much as possible

*Asking for help from network
*Thinking about teams involvement with family - Is it appropriate for one person to work with young person and one person to work with Parent/Guardian 
*Setting rules / agreements: 

-Parent sending message reminders of when they are due back home / where are they going and with who / consequences of what will happen if they don't follow rules / Diary to fill in when they get back - monitoring expectations / Reward charts

*Identifying positive communication that goes on, and what negative communication goes on: Pie chart
*Sequences - why behaviour has happened
*Monitoring to find examples of when things go well some of the time. Parents/Guardians may often find it difficult to find positive points and feel that bad behaviour is the only thing that is happening. Asking parents to explicitly look out for good examples of behaviour

''Common issues''

*Parent and child disagree on what is needed to done and who is responsible for that
*Thinking about your relationship with young person and how to make it a 'trusting' and open, whilst bringing in parents: Frame parents' involvement / think about your positioning - "It's quite annoying that rules exist, how are we going to manage following them". 


There are many GSH manuals that could be used to help guide practice.

!!!Adolescent Anxiety:

''Camden and Islington Self Help Guides'' for the following:

*Stress and Worry
*Panic and Phobias
*Depression and Low Mood

<<link-pdf "Camden and Islington self-help guides" "https://drive.google.com/open?id=0B-tACu2wi4-4a0NocmRXaElfOHM">>

''Northumberland Tyne and Wear NHS Foundation Trust'':
an alternative guided anxiety Self-Help Booklet in which page 17 provides a brief description of facing anxiety in small steps:

<<link-pdf "Anxiety Self-Help Booklet" "https://drive.google.com/open?id=0B-tACu2wi4-4OVM4WUU0UlM5OWs">>

''Moodjuice self help guides'' for the following:

* [[Anxiety|http://www.moodjuice.scot.nhs.uk/anxiety.asp]]
*[[Depression|https://www.moodjuice.scot.nhs.uk/depression.asp]]



''Braintrain booklet'': which highlights the helpfulness of exercise in mental well-being.

<<link-pdf "Braintrain" "https://drive.google.com/open?id=0B-tACu2wi4-4SkE0TXBsbjlmS0U">>
The Anna Freud National Centre for Children and Families is a charity dedicated to ''Innovation'' in the the treatment of mental health difficulties in Children and Young people, ''Evaluation'' of new treatments, and the ''Dissemination'' of effective techniques to the widest possible audience.  Further information can be found at the Centre's  [[website|http://www.annafreudcentre.org/]].

[img width= 300 [AF-logo-RGB-Green.png]]




<<list-links "[tag[Assessments]]">>
Attachment Theory brief re-capp

Here we have reviewed key elements of attachment theory as part of our training/discussions in working with Looked After Children

Re-introduction for attachment theory:
Biological innate mechanism that humans have developed for keeping safe.
Having a secure base to explore the world and develop relationships and come back to the base for safety. But when the main caregiver is unsafe and not predictable, attachment difficulties arise. 
The process of repairing makes it a safe base.

Attachment styles can vary between cultures. 

A secure base/ 'safe base' is really important to help one learn about who they are; what's going on inside - this is the basis of mentalization. 

''Strange situation'' - a way to measure of attachment. Can the child be settled by the parent, and then carry on exploring? This can be a helpful way to establish whether the child feels they have a safe base. 

''Avoidant attachment'' - more independent, withdrawing, not seeming bothered when parents leave (although cortisol is actually shown to raise in these situations).

''Anxious/ resistant attachment'' - often when caregiver is inconsistent. These children can often be very clingy - very push/ pull; carer struggles to settle them. Preoccupied with the caregiver's availability. 

High percentage of LAC will show a ''disorganised attachment style''. Distressed DUE TO carer, yet they are all I have for safety, despite being scared of them. Often seen where there's severe neglect/ violence/ drug/ alcohol abuse. Will often be hyper-alert and in survival mode; high fight/ flight response. Called disorganised because there isn't much consistency/ organisation in their attachment. 

''Earned Secure'' - if a caregiver can provide enough security and consistency later in life, can encourage re-learning of attachment and relationships.

Attachment styles don't seem to change, unless there are big changes in behaviour and safety felt with caregiver.

''Mirroring'' is an important part of development - particularly in terms of developing mentalisation. This is when a caregiver reflects the expression/ emotion shown on a LAC' face. LAC may not get this experience; may change between different foster care or not experience this with their parents/ caregivers. 
<<list-links "[tag[Autism]]">>
!!What we can do as a service
*For new referrals coming to WEST that are clearly for an ADHD or ASD assessment, we or the original referrer will refer on to CAMHS
*For open cases where we are querying ADHD or ASD, we would try to gather additional screening information from parents, school and sessions with the child, depending on service capacity (e.g. SCQ, ASSQ, school report / information, brief neurodevelopmental history etc. using the above) and write these up and refer on to CAMHS


<<link-doc "Autism Pre Screening Documents" "https://drive.google.com/drive/folders/151AL84y0vSzeRnTL00gFO8pVi084X7bV?usp=sharing">>



Build up a developmental History so that you can produce a CAMHS Report

!!Developmental history
!!!!Ask about this historically and currently 
*family context
**who they live with, where, siblings, who looks after child
**relationship with both parents
*history of Autism / ADHD
**Pregnancy, Delivery, Milestones
**language development- any unusual
*medical problems 
*activity level 
*social interactions 
**friendships how many, how close to friends 
**how do they play - on their own, with others 
*unusual interests/ obsessions
*Eating 
**any unusual habits - textures of foods, colours, touching 
**Unusual sensory responses- covering ears, rocking

!!Sending the report to CAMHS 
*Contact CAMHS Gateway and attach the screening report
!!!What is BOAT?
* Mainstream service of 2-18 yr olds servicing 800 children who have a diagnosis of Autism
* Do not discharge young people
* funded to be ''support with schools'' but work closely with families
*usually involved with families and young people throughout their school career
*anyone who has a diagnosis of ASD who live in Brent and in a mainstream education (and have consent from parents).
*only get discharged if go to a special school or leave the borough.
*currently applying for funding to work with children and families pre-diagnostically which will include support groups and support with the diagnostic process.

!!!Parent support?

* Parents often also have a lot of need 
*offer a ''post diagnostic sessions'' (run each term depending on need) in which BOAT explain what autism is, which are run by the allocated practitioners. These are now being run virtually
*no time limit on how long after the diagnosis they can attend post diagnostic sessions 
*Post diagnostic sessions focus on the strengths of autism and discuss key aspects of difficulties such as sleep, eating etc.
*run sessions on supporting ''choosing and transitioning to secondary schools''
*support families with the grief cycle through developmental / life changes cause changes in the child's wellbeing and behaviour

!!!Supporting sharing the diagnosis 
*believe in ''sharing the diagnosis'' with the child/  young person
*often advocate for families to share this with children before going to secondary school
*''peer support sessions'' -we offer sessions in schools to support the school class/ peers understand the differences in a child who has autism.
*have a lesson plans for schools to run a autism session 
*we ''support parents to explain the diagnosis'' to the children in a calm way

!!!Other support groups

* ''Cygnets'' which is a group for parents - 6-7 weeks and do not need to be in a special school 
* ''Pegasus'' course run by CAMHS which is run jointly with parents and young people - usually older young people 
* ''Barnet- resources for Autism'' - offer for respite, art and music therapy
* ''Harrow- centre for autism'' - drop ins for parents, speakers/ presentations.
* ''Autism education trust'' - online platform lots of information for parents and shows what the government is funding for children on the spectrum 
* ''Reachout afc'' - free resources for parents and families, you can subscribe for £10 a month 
* ''Support for girls with autism'' - yellow lady bugs and lavender Facebook groups


!!!Supporting schools
*Support schools but often need to challenge practice in some schools 
*Build good relationships with schools 
*Focus on the priority and needs of the child '''we are the child's advocate'''
*support the schools to understand the parents experiences in the past.
*Supporting school to shift in what they do

!!!Graduated approach document
* outlines the types of support for autistic children 
*''universal support'' - expected that school can offer this level of support
* ''targeted support'' - things that BOAT can help schools to manage
* ''specialised support'' - for things such as school refusal and mental health distress

!!!Strategies
*thinking about individualised adaptions/ strategies that can be used for children in the class
*ABC chart
*the bucket analogy- things that fill the bucket and empty the bucket. What is adding to dis-regulation and what helps regulate. 
*considering the conflict in what the teacher need and what the child needs are and finding a compromise
*helping schools understand that behaviours are a form of communication
*reverse exclusions- wasted time in class mean staying longer after school and involving mum in this
*simplifying choices
*helping people remember that it is difficult the put into words how they are feelings and expecting them to answer difficult questions.


!!!Resources 
Tony Atwood - circles 
roadmaps different roads that lead us to positivity or misery - the choices we make 


<<list-links "[tag[Behaviour Problems]]">>
__Examples of boundary struggles__

* What's an appropriate way to be in a friendship?

* What's an appropriate way to be in a romantic relationship?

* Appropriate social boundaries in school and with friends?

*CYP understanding the boundaries of our working relationship with them and how we help them to remain within those

__How do we learn boundaries?__

* Learn from what you see - life experiences

* How the other person in the relationship behaves - e.g. leader and follower

* What you ultimately want - boundaries may be bypassed in pursuit of something - ''motivation''
* Who you care about and how much you care about what they think of you

* Reinforcement - vicariously and directly - how others react to our behaviour (or how others respond to others' behaviour) 

* What others tell us (or don't tell us) - we may be given strong messages about developmentally or socially appropriate boundaries 

* Sometimes we may disregard boundaries:

__When do boundaries fall down?__

* When behaviour is driven by how you feel then boundaries may not be taken into account

* Boundaries may be bypassed in pursuit of something

__What maintains boundaries__

* Might not get back reaction that helps boundaries to be held

* Reinforced - got the goal you wanted

* Reputation 'points' may reinforce for teenagers - i.e. it's 'cool' to get into a fight/ have an older boyfriend

* More/ longer boundaries continue, the more they are normalised

__How can we help with teaching healthy boundaries?__

* Modelling to them via our relationship 

* __Map out__ current relationships - what are the current boundaries and expectations?

* Often difficulties with boundaries will be raised by others, not usually by the YP themselves

How might we map this out with people in the network to understand it better?

* What is the problem with boundaries? What does it look like? - ''Creating a picture''
//Explore strengths and exceptions - Is this something that happens all the time? Are they able to manage some relationships/ boundaries well?//

* What is it ''supposed'' to look like in these relationships (as far as everyone can agree)
//Being as clear and explicit as possible with the YP - trying to help them see the perspective from others (i.e. what is it they're doing that you don't like/ would like to see//

* Sometimes may need to be the ''worker'' that brings out discussion around relationships and boundaries, if its something that the worker is noticing in the stories that the CYP is bringing (e.g. arguments with friends; stories about boyfriend/girlfriend etc) - may do this by being strategic in reflections (to try and get shared agreement to open up this topic for discussion) 

__Asking:__ //What does a good friend look like? What helps people to like each other? What helps people to get on/ not fall out? What do you think would make a good boyfriend/girlfriend? How could you be a good boyfriend/girlfriend?// 

We want to elicit what THEY think - helps us to know what they've got in their head about it already, before we start assuming that they need "education" around boundaries (might be more that they do have appropriate ideas, but we need to explore what's making it hard to act within these in this particular relationship)

* Check out/ narrow down on their ''beliefs'' around relationships/ boundaries and what is OK/ not OK - could bring materials to sessions to stimulate discussion if it would be harder for them to generate this themselves - e.g. power and control wheel/ consent/ assertiveness/ what's a good friend (explore whether they agree)

* OK to ''share'' the dilemma a little with them - validating that it IS really hard sometimes to know the best way to be in certain relationships, but also encouraging YP to have their own mind about it so that they don't feel you are another adult "telling them", but that you're open to discussing it, as well as sharing some advice 


//"a lot of the other YP I've spoken to, sometimes we've done a lot of work on what to expect from situations/ how we might behave etc. - how would you feel about that?// 

* Moving away from constantly hearing the story about things and moving towards actively do something to help - ''interrupt the constant story telling'' if you feel that you are only ever hearing examples of the problem. 

* Be strategic in your validations/reflections - which bits of what you are hearing might you want to amplify in order to move towards being able to focus in on some of the general themes of what you are hearing, rather than each specific example. 

**The friendship stuff sounds quite tough at the moment! 
**I'm just thinking back on some of the other things you've told me about how it is with these friends and it feels like you're never quite sure why they end up reacting like this to you?
**It often sounds like you end up having to go along with things that you're not exactly sure about / comfortable with - is that a bit how it feels?

* Aim to come to ''shared agreement'' to talk about it, so that you're on the same page about this being relevant (does it connect to a goal they already have?)

* Worksheets to support what you discuss could be helpful

__Our own boundaries__

We talked about how tricky it can feel when CYP refer to you as a friend or where you are being treated in a way that you imagine they might more treat a friend (e.g. updating you on the latest gossip). 
 
When they refer to it being good to have someone like you to talk to, as they don't have many friends. 

As workers, it can feel hard to know how best to respond - don't want to invalidate what they are saying, but also want to help them understand what the limits are of the relationship. 

Extra hard when working remotely - we are at home or chatting on whatsapp, so might feel like the boundaries are more blurred. 

''Ideas''

* Whatever "positive feedback" they give about you and the relationship, ask them who else they have that they notice this with - //what other people do you feel the same way with? //. You can say that its good that they notice what they find helpful in other people/relationships and part of what you want to help with is getting that happening in more relationships in their life. 

//It's good that you see me as someone you can talk a bit to, but I wouldn't want to be the only person that you feel you can do that with.//

* It can be helpful to gently draw some differences as to why you are also NOT like a friend! You can use your humour too. This can help to remind them of the boundary in a way that might not feel as rejecting. 

//I get that I do a lot of things that a friend might, but there's also lots of things your friends do that I wouldn't do too! You probably wouldn't want me turning up at Nandos for example! (remind them of ways you're different)// 

You can acknowledge that you are glad they find you friendly, a good listener etc as it's important to you to hear whether they are finding you helpful. 

* Can be hard to have this feedback or know how to handle it when you have a sense that the CYP is more isolated and genuinely isn't that well-connected to other relationships. Not so much as making the relationships they have better as it might be helping them to find people who they could connect up with. Many ways to explore this - e.g. helping them to become more aware of their interests etc to think about new activities they could take up. Could also use the network to help think about "scaffolding" more friendships in school (not necessarily with the YP's knowledge if you feel that this would be counter-productive)

<center>{{broadcasting Pic.jpg}}</center>

Broadcasting Intentions is a key part of the active planning stance. This is when the KeyWorker makes an effort to be EXPLICIT and clear about their intentions or ideas to their client. In other words, the worker is open about 'what my intention or purpose is, and why'.

The point of this is that we cannot assume that our clients will have the kind of relationship to help in which they would experience our approaches as well-intentioned.  It may be that our behaviour does not make sense, or represents something more threatening or troubling, in relation to their past experiences of others.

//In the anxiety of the therapeutic encounter it is often hard for young people to [[Mentalize|Mentalization]] their therapist accurately.//

So, we Broadcast our Intentions in order to;

*Prevent an intention from being misunderstood.
*Help an intention be understood
* Resolve a misunderstanding
*Build trust 

This is also a key element in the process of Engagement:

<html><object width="480" height="360"><param name="movie" value="https://youtube.com/v/s5A41EGo--o?version=3&amp;hl=en_GB&amp;rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="https://youtube.com/v/s5A41EGo--o?version=3&amp;hl=en_GB&amp;rel=0" type="application/x-shockwave-flash" width="480" height="360" allowscriptaccess="always" allowfullscreen="true"></embed></object></html>

!!How to broadcast our intentions

The AMBIT KeyWorker is encouraged to verbalise his/her intentions.  

This might be in terms of their general aims of the intervention such as "being helpful" to the young person, or the specifics, such as //"to register for a college course"//..

My invitation to consider registering for a college course might be well-intended, but might be read my client as a move to separate her from her boyfriend, or to humiliate her mother, etc...  If those were my true intentions, then it would make sense for my client to resist them, and I am unlikely to have any influence in that sphere!


Intention can be expressed in moment to moment interactions, for instance:

>//"My intention here is just to try to understand more accurately what you are feeling, and why."//
or

>//"What I am trying to do here is to be helpful, or at least to think of some new ideas about this familiar problem, and definitely to to avoid being unhelpful!"//
Being clear about moment to moment interactions would be adopting an explicitly intentional stance. 

>//"I may not have got things quite right yet, but these are the things that at the moment seem to me the most important ones for me to try to help you deal with... ...I would like to hear from you which bits you think I have got about right, and which bits I still need to work on so that you can recognise them more clearly..."//

!! A tool to help this: 
The Egg and Triangle (also known as the Egg and Triangle) is about helping the worker to share their "first effort" in 
'"what I have understood from you", then inviting the young person to help improve it.  When you are sharing your first effort, ''that'' is Broadcasting Intentions!.  

Go to [[this link|https://docs.google.com/file/d/0B5h_CVBdhJPYNkJNamFPVXhsYXM/edit?usp=sharing]] to download this in PDF format, or just use the back of an envelope!

[img[https://lh5.googleusercontent.com/-loMP5VnnI1Q/URG08pJR4OI/AAAAAAAAGpY/o21-QH6rBw0/s640/ActivePlanningSheet.jpg]]
[img[https://lh5.googleusercontent.com/-EXERk6bOad4/URG07sRVqzI/AAAAAAAAGpc/W6cVjCoCoHA/s640/ActivePlanningSheet_DEMO.jpg]]










.






* What things we need to do?
* Closing letter that needs to be written by Wellbeing Practitioners and then sent to Eleanor, who sends it to the relevant people (eg. referrer, GP, family members).
* Ending summaries/reports/portfolios.
* ESQ outcome measure and written feedback, SRS of the last session, SDQ follow up.
* Clinician outcome case closure done by practitioner.
* Pod and PSS closure: end contact. 
PSS: look up the contact, double click your name, put the end date.
POD: Go to status, and change from current to completed intervention.
* Put the date of closure in the spreadsheet.
!!'''Helping Your Child with Fears and Worries 2nd Edition: A self-help guide for parents ''

PLEASE NOTE –  BOTH THE MANUAL AND BOOK HAVE BEEN RECENTLY UPDATED. THIS IS THE MOST RECENT VERSION OF CATHY'S BOOK. THIS MEANS SOME OF THE PREVIOUSLY DEVELOPED CHAPTER SUMMARIES AND TRANSLATED VERSIONS ARE BASED ON THE PREVIOUS VERSION. 

----

''The most recent version'' of the Cathy Creswell's therapist guide 'Helping Your Child with Fears and Worries: A self-help guide for parents Treatment Manual for Therapists'. The therapist manual is free to download, just click the following link and click on the box labelled ‘Request copy from Reading author’ and following the instructions. 

[[Treatment Manual for Therapists|http://centaur.reading.ac.uk/87041/]]

----

This is an excellent self help guide written for parents based on extensive research and practice.The book includes a step by step guide to helping a parent provide effective support to their anxious child.

This book follows the parent led intervention for child anxiety developed by Cathy Creswell. As such parents will be encouraged to read this book as part of the intervention. 
This book can be easily purchased and we would encourage parents and practitioners to purchase a copy of this.

 We are indebted to Cathy Creswell and her team for generously sharing their work on child anxiety with the London and South East CYP-IAPT Collaborative.

For translated version of the Cathy Creswell book please go to [[Cathy Creswell's Book- Translated Versions]]

Chapter summaries are also available (with Cathy's permission) for practitioners to use as a quick reminder of core ideas.  

<<link-doc "Chapter Summary Part 1 "  "https://docs.google.com/document/d/1CdLmESbIUql6mGDIgitzBZ-hssC2ORHAVca0nHarF8k/edit?usp=sharing">>

 <<link-doc "Chapter Summary Part 2" "https://docs.google.com/document/d/1MicoU_0T5RYC4UX5pBX_m0t0R_tYVuGpwDFmFw4OVhw/edit?usp=sharing">>  

 <<link-doc "Chapter Summary Part 3 "  "https://docs.google.com/document/d/1vv7k0BnlZybNkPo3Y4AuzUrLcMh2XRVa4LKDDG_DA18/edit?usp=sharing">>
<<link-doc "Creswell English Audio" "https://drive.google.com/open?id=1hiq_qeG-QA6nGwcO5Ywd6W9WJnH1mRIR">>

<<link-doc "Creswell Sylheti Audio" "https://drive.google.com/open?id=1VVMtenh0tmVbctmjGdVene-gxh-bKuD7">>
<<list-links "[tag[Clinical Framework/ Principals]]">>
!! What different ways can we collect SRS feedback?
* Directly on the phone/video call
* Via text message/WhatsApp following session
* Via email

!!! Collecting SRS feedback directly on a phone/video call - 
* Prior to asking for it, encourage honesty and tell them that it will help to improve the sessions
* If using video call you can get their POD up on your screen and share the screen and fill it out with them there
* If just speaking over the phone you can ask them to rate each scale out of 10

!!! Collecting SRS feedback via text message/WhatsApp - 
* You can send a screenshot of the SRS form to the client via text message/WhatsApp and ask them to edit it and put a cross on the scale where their response is
* You can send the feedback questions one by one and ask for a rating out of 10 for each question 

!!! Collecting SRS feedback via email - 
* This is the least effective way of getting SRS feedback (according to team)
* Attach the SRS form to the email and ask for responses as a scale from 1-10


!! Who do we need to ask for feedback from?

* Children and young people we are working with
* Parents 
* Professionals

The team find that it is easier to get feedback from the CYP and parents than from professionals. A suggestion is to ask for the feedback in a follow up email and put it at the beginning, before the summary of the call and any actions. 

!! How do we keep track of feedback not obtained?
* Change the format of our record keeping template so that after each session/intervention we can note whether //SRS was obtained//; //SRS requested and not received//; //SRS not asked for//. 
* During admin catch up sessions with each practitioner we should keep a note of the SRS feedback that has not been obtained (so that we can report on this eventually in the report). 


<center>{{Community of practice pic.jpg}}</center>

!!Developing and sharing learning within a community of practice

The “evidence-base” (e.g. core content of this manual) tends to develop slowly over time. However, the innovation, development and learning within local practice-based evidence can move along at a much quicker pace (as the hares and tortoise picture above tries to highlight !)

This is a core idea underpinning the AMBIT community of practice- to learn, develop and share local expertise.


!!''What is a community of practice ?''
This is a way of describing how groups of practitioners (from many, even any, fields) can function in collaborative ways - to compare and share ways of working so as to sustain and grow knowledge about "what works, for which situations".  


AMBIT and the wiki Manuals that support it are significantly influenced by this simple idea, that ''practitioners like to get better at what they are doing, and, given the chance, they like to share their expertise with other practitioners''.  

''This is why every team trained in AMBIT gets its own local version of the AMBIT manual which it is encouraged to use as a 'practice scrapbook' to document and share its present expertise and ongoing learning about "//what works for whom, __here__//."''


!!''Membership of the AMBIT ~CoP''
You can see a list of all the teams who have received AMBIT training on the manuals sign posting site. 

The Wiki Manuals that support AMBIT, function as “windows” upon the work of other teams, encouraging ''//curiosity//'' and the ''//sharing of emerging expertise//'' between services that, although geographically remote, frequently address similar clinical dilemmas.  

This aspect of [[Manualization]] builds on themes opened by ''Lave and Wenger (1991)''  in their landmark study of ''apprenticeship'' that has led to the theory of ‘Communities of Practice’ - the establishment of which is an explicit goal for AMBIT.

If you would like to read more about Communities of Practice, theory and how they apply to AMBIT please see
<<tag [[Extended learning]]>>


!!!Contact us for help connecting:
Feel free to email us and we can direct you to teams who are manualizing and who may be of a similar service. mailto:ambit@annafreud.org 








!!How to complete your data on the caseload spreadsheet

You should be completing every column on the spreadsheet in relation to your child including date of first contact regarding the referral (for example, with the referrer, another professional or the child or family) for example as Elly will not have this information.

!!!__Direct Session – face to face, telephone or video__

This includes the following:

*Individual assessment or intervention session with a child or young person
*Session with family
*School observation (see ‘please note’ below for more information)
*TAC meeting if family present (see ‘please note’ below for more information)
 
!!!__Indirect Session - face to face, telephone or video__

This includes the following:

*Session with professionals (school, social care, Family Solutions, CAMHS etc.)
 
!!!Please Note:

*If you have conducted a school observation and a meeting with a teacher this is two sessions 
*the school observation is direct work and the meeting with the class teacher is an indirect session
*If two members of our team conduct a meeting with a parent/child you would both enter this as a direct session i.e. on each of your spreadsheets. The last column on the spreadsheet asks whether there was involvement from any other member of our team ‘other WEST clinician involvement’ please note here who did the session with you and how many sessions you did together and whether you are referring to direct or indirect sessions. Example: ‘1 indirect session with CHe’
*If two members of our team conducted a session with a professional then you would both record this as an indirect session as above
*If a session was conducted where a child/family member and a professional was involved (for example a Team around the Child meeting etc.) then this should be recorded as a direct session. If following the meeting you then had a conversation with the involved professional(s) about the child/family you would note this as an additional indirect session.
*All group work should be noted in the ‘groups’ tab as direct work but all meetings regarding group work with schools, virtual school colleagues etc. should be noted as indirect work in the inter/intra team columns on the spreadsheet.
 
!!!__Wellbeing Review - Direct Session – face to face, telephone or video__

This includes the following:

•	A direct wellbeing review is with the family or child

!!!Please Note:
*A wellbeing review is when you are checking in with children/young people and their families and offering structured social support, checking how things are going – you might be helping them notice that things are going well and checking that they are happy with the current support. 
*If we are talking to a professional about the child/family then all of this contact should be counted as an indirect session (see above) and not an indirect wellbeing review as previously stated. Once we have updated the spreadsheet this will be removed as an option.
 
!!!__Supervision __

This includes the following:

•	If you are offering supervision to a member of another team (not an individual within WEST) then this should be recorded under the ‘supervision tab’ on your spreadsheet.

!!!Please note:
*This is for ongoing supervision. Any one off supervision support is a consultation and should be recorded as one in the consultation tab.
 
!!!__Cancellations/ DNA__

This includes the following:

*If your child/young person or any member of the family or professional network let you know they will not be able to meet/talk at their allocated time (even if they text you just before or during the allocated time) this should be counted as a cancellation
*If they do not pick up the phone at the allocated time and do not notify you at all that they cannot speak – this should be counted as a DNA


!!!This will be reviewed continuously. We need to consider how we will represent number of sessions conducted over the phone and face to face.
! This page contains the discussions held within the team about our consultation process


!!! A discussion between Jyoti, Scott & Eleanor to clarify our consultation service and the process of initial consultations (19/11/2020).

* ''Telephone consultation service ''– advice about a CYP not known to the service 
*'' Assessment ''– telephone conversations around referrals, more fluid, we already have a lot of the information 

!! Telephone Consultation Service

We will stick with our previous model of - 

* Someone call/email enquiring about the service
* They complete screening form on phone with Eleanor or via email
* Book in 1.5 hours in Scott or Jyoti's diary (half hour to read, half hour for consultation, half hour to write up afterwards)
* Write summary letter/email
* SRS form taken (add to POD using name of consultee)
* Send over referral form if the consultation resulted in referral


!!! To consider  -
* How do we get more uptake for telephone consultation?
* Haven’t had many requests for consultation service
* We would like to have more consultation service consultations, so that they have a conversation before referring, as many referrals are not suitable 

!! "Assessment" stage of referrals

Previously described this as Initial Consultation but we agreed on calling this Assessment to avoid confusion. 

!!! To consider - 
* We need to discuss this section with the wellbeing practitioners so we can understand what is useful for them to know.
* Do we need to change the initial assessment section of the record keeping template so that it prompts the right kind of questions to ask?
* This could be based on the Three Houses?
* Could we create a scaffold sheet to represent where the family fit in? 
* What is the model of the Schools Remote Therapy Service?

!! Discussion with Wellbeing Practitioners (20/01/2021)

!!! To consider - 
* What is working well?
* What is not working well?
* What do we need to know from consultations?

!!! Discussed - 
* Good information received from Scott if you call to discuss referral
* A lot of notes to write up about initial assessments done by Scott. Can we support this process?
* When Scott discusses therapeutic plan during assessment process, important to clarify that the type of work is subject to change. Once they speak with wellbeing practitioner there may need to be flexibility for what we offer. 
* Sometimes parents are not prepared for the work that will be involved (in partivular with child anxiety referrals)

!!! Points to cover during assessment

* How willing the parents are to be involved
* Face/face or virtual?
* What is going well/what is not going well? (Expand on the referral form)
* What does the referrer envisage the support to be?
* What has Scott offered? What are their expectations?
* Who is in the network?
* Address/clarify complexity factors
* What are the next steps for the practitioner? What has Scott informed the referred will happen? When do they expect to hear from the practitioner?
* Which people in the CYP network has he spoken to?

!! Training Sessions with James

The team decided to use the wellbeing practitioner training session to continue discussions regarding what a consultation is - 

!!! 21/01/2021
!!! Focus of discussion - 
* Clarifying initial consultations/assessments
* Looking at the process, how would the wellbeing practitioners feel doing them
* Use fishbowl exercise; Jyoti, James & Scott will discuss consultation, wellbeing practitioners to observe and question/discuss after

!!! Consultation defined by Scott & Jyoti -
Notes from Scott - 

* A discussion in an open and transparent way, with the referrer or another member of CYP network
* Practical thinking about the next steps
* Filtering down process
* Use the Signs of Safety and Wellbeing model (this is always in his mind when Scott is consulting)
* Is the work about the young person or the parent?
* What will our role in the work be?
* Is there an existing relationship that we can strengthen?

Notes from Jyoti -

* Depends what the other person is asking for / what their intentions are 
* It works well when it is an open and curious conversation
* Think through some of the dilemmas they have 
* Who is who in the network? What can they all offer?
* The role of the person offering the consultation is a neutral role, to provide an outside perspective and to problem solve
*  Does this person even need extra support? If so, who would be best placed for this?
* Often the person at the other end just wants us to take on a referral (pass on risk)

!!! Themes 
* Defining what the problems are
* Taking a curious stance
* Dialogue between two professionals
* Importance of networks
* Understanding difficulties and strengths
*How we broadcast our intentions as the consultant- structure the conversation
*Use analogy- ripples in the pond- helping the consultee to make sense of the situation and problem solve

!!! Thoughts from wellbeing practitioners - 

*Consultations make people feel heard, and like their problems have been recognised
* Good aspect to our service that not a lot of other services have
* Not a clear cut/definitive thing
* It helps the referrer to understand the challenges 

!!! Reflections
* Sometimes there is a long time between agreeing the work and then starting the work. Situations for families can change in this time
* Important to be curious, validate their feelings and support them in their own problem solving ability. 
* Use the method of marking the task, and coming back to this at the end. 
* When you notice that someone has come along with a different idea to how the consultation will go/what will come out of it, how do you redefine the conversation?
* There can be an expectation that you will be able to provide them with an answer they have never heard before/a new solution
* How can I provide help/insight to someone like a social worker with so many more experiences than myself?

!!! Next week - Focus on the practical questions surrounding consultation.
When is it a consultation? When is it something else? Are there different types of consultation? 
Clarify our language within the team.


!! 04/02/2021

James provided some definitions of consultations

School consultation - 

* Collaborative problem-solving approach
* Emphasis on consultant leading and structuring but holding a balance of power

Sometimes by just validating and listening to the experience of the consultee we can allow themselves to problem solve. By going straight into strategies you often get met with "I've already tried that"

!!! Overlap between assessment and consultation 

Assessment - 

* Looking at other nuances of complicating factors
* Things can be different to how they appear in consultation 
* Look at goals and how to move forward 
* Can go on for a few weeks, multi-modal, can use a wide variety of sources and questionnaires

Consultation - 

* Finding bare bones and information 
* Focused and targeted piece of work 
* Shorter piece of work than an assessment 
* Ask about network 
* One off snapshot of situation
* Nailing down what the help is that is needed 

Ideas to draw from other services - 

* Support the mentalizing of the worker who is holding the case
* Create reflective and curious space
* Pro-active stance as support to the worker
* Emphasis on working through the existing relationship (rather than overburdening with more new relationships)
* Be careful not to affect any relationships between other networks that are already existing

!!! Reflections 

* How do we get schools to recognise consultation as an intervention in itself?
* Use a diagram to illustrate the network?
* People in the network have different ideas about the problem and what they expect from you
* Can use AMBIT disintegration grid to map out different ideas of people in network 
* In our referral form the views from the child are often written by the parent/professional so they aren't actually the views of the child 

What happens when things change - 

* Focus of work changes or more difficult to find focus of work, how do we work around this?
* //It is okay// for the direction of work to change 
* Share with network that things have changed
* Put young person at centre (what is working for them)
<<list-links "[tag[Consultations]]">>
<center>{{Capturecon.PNG}}</center>

You can contact us at the AFNCCF by phone or email:

''T: +44 (0)20 7794 2313''

''E: info@annafreud.org''

or, if you have a login, please feel free to leave a ''comment ''on the manual. You will see the comment box at the bottom of each page!


In draft

The key outcomes from the contract. 

Process outcomes 

1. 100% of accepted referrals will have a consultation from one of the team. This will usually be done by phone. 

2. 100% of referrals to be accepted. This is not possible or good practice as some referrals need to be directed to other services. For example child protection referrals or referrals of young people with sever mental health problems.   



Wellbeing Outcomes 

1. 70% of children, young people or parents to show improvement for the mental health need that they sought help for. 
Generally, 50-60% of children show some improvement. 25-30% of children show no change. 5-10% get worse. To be discussed with commissioners. 


We are developing a 6 - 8 session group for children and young people (YP) with mild / moderate behavioural and emotional needs. 

At current, 9 YP have been identified for the group (8 who are care leavers, post-18, and 1 who is a looked after child, under-18). 

The hope is to run the group face to face in the summer term (from 19th April), over an 8-week period. There will be a pre- and post- screen for participants to fill out outcome measures. This will make the group 10 sessions in total. 

__Initial Tasks__

*Send email to keyworkers of YP who have been identified for the group to book in consultations
*Hold mini consultations with keyworkers of YP who have been identified for the group 
**Ages of YP
**Learning needs - Cognitive reports
**How engaged in education are they? If they are?
**First language
**Who is in their network, and who would be important for us to feedback to? 
**What change would they like to see in their YP or what change do they think that the YP would want? 
*Connect others who work within learning disabilities, and see if they have any previous experiences of delivering groups and if so what was helpful / not.  

__Ideas for what the group will aim to cover__

*Maintaining relationships - Social Communication
*Sense of belonging 
*Self-esteem 
*Life Skills
*Transitions 

__Timeline / Steps of setting up Group__

*Initial Calls
*Connecting with others who work within LD
*Think about the actual content of the group
*Leaflet
*Referrals
*SDQ Goals
*Set up running of group (From April 19th 2021)

Pre-group meetings - do with YP  
-Empowered and responsibility 
-Go to meetings with structure
-Do a bit of explaining
-Structure their thinking around 
-'If you talked about independence... what do you think about' 
-We were thinking of doing this

Structure to build the group around
Friends - Classroom in
!!''AMBIT Core Features ''

''These are:''

* The five key elements of AMBIT practice (inner ring and centre of the AMBIT wheel)
* The eight elements of the AMBIT stance (outer ring of the AMBIT wheel)
* illustrated by the AMBIT Wheel

!!''The AMBIT Wheel''
<center>{{AMBIT wheel 2014_SMALL.png}}</center>


''Please scroll down for videos explaining the Core features''

!!''AMBIT Basic Practice (inner 5 sections of wheel)''

  

These aspects are key areas of practice and service delivery for an AMBIT-influenced team: if they were missing or not held in some kind of balance, this would imply that what is being delivered is not AMBIT.  The practice of [[Mentalization]] is at the centre of the model. This is like the '''load bearing axle''' or '''hub''' of the model, as it underpins practice in each of the 4 quadrants around it.

#[[Mentalization]]
#[[Working with Your Client]] 
#[[Working with Your Team]] 
#[[Working with Your Networks]] 
#[[Learning at Work]]

In AMBIT we emphasise the importance of a balance of activity across these areas of basic practice. We stress that each are important. However, it is sometimes inevitable that workers, teams and services can lose sight of any of these areas, given the complexity and intensity within which AMBIT influenced teams often work. It is also difficult to keep all of these in mind at the same time! For this reason the AMBIT wheel acts as a way of supporting services to hold onto and develop these key areas of basic practice.

AMBIT is not a one-size-fits-all approach, it works to help teams adapt the model, ideas and tools within each area of basic practice, to fit their own contexts and client groups. 


!!''AMBIT Basic Stance (outer ring of wheel)''

''8 elements of a basic stance:''  These define the core "stance" of an AMBIT practitioner in their work - the stance describes the "way of being-with", or approaching work within each area of basic practice. 

The stance elements are arranged in pairs, with one pair fitting into an area of basic practice. 

Each pair of stance elements highlights points that can easily be experienced by workers as contradictory. In other words, points whereby workers and teams can experience a kind of 'tension' or 'push-pull' which can need balancing.

These stance points can be seen as "grab-rails", a way of keeping or regaining balance. They aim to help keep an individual or team 'on track' - especially when the situation is stressful, risky, or simply uncertain.

At times of high anxiety or confusion it is easy to find that one element of the stance has come to dominate, sometimes at the cost of losing other principles that would help if re-activated.  //At any time we can ask a colleague, or ourselves, ''"am I holding the basic stance?"''//

# [[Individual keyworker relationship|KeyWorker]]
# [[Keyworker well-connected to wider team]]
# [[Working in Multiple Domains]]
# [[Taking Responsibility for Integration]]
# [[Scaffolding Existing Relationships]]
# [[Managing Risk]]
# [[Respect Local Practice and Expertise]]
# [[Respect for Evidence]]


!!''Practise makes perfect''

As a way of checking whether we are holding onto the AMBIT stance points, there is a questionnaire AMBIT Practice Audit Tool (APrAT). This is used to audit a specific case (perhaps with your supervisor) in relation to the AMBIT stance points. 

Here also are a set of AMBIT Stance Exercises to help teams to practise the stance. 

!!''A Very Brief Overviews of the Core Features''

<html><object width="420" height="315"><param name="movie" value="//www.youtube.com/v/VC-xzsR89s0?hl=en_US&amp;version=3&amp;rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="//www.youtube.com/v/VC-xzsR89s0?hl=en_US&amp;version=3&amp;rel=0" type="application/x-shockwave-flash" width="420" height="315" allowscriptaccess="always" allowfullscreen="true"></embed></object></html>






<<list-links "[tag[Core Skills]]">>
__''Portfolios''__

We looked through an example of a portfolio that was made for a young person to capture the work that they had done in their sessions. 

__Format__

* Letter to young person to introduce the portfolio
* Overview of "assessment process" (i.e. AIM cards) and goals set
*Summary of work undertaken towards each goal
*Closing letter - to say goodbye

__Reflections from the portfolio__

* A helpful way of sharing the key ideas from the work
* Liked the emphasis on supporting the young person to develop their own ideas about what might be useful to try (rather than being an expert and giving strategies/ideas that may not work for them)
* Helpful to see how balance was held between following a plan, but making it personalised (e.g. using young person's interests)
* Useful that a trusted person from the network was brought in early on, referred to in the portfolio and that the portfolio was shared with them. 
* Portfolios would help the likelihood of change sustaining post-intervention, as would give others in the network an idea about what to continue helping the young person with

__Ideas arising__

* How could we make our own wellbeing journals/workbooks for young people? 
*Could we make a template that we could adapt? 
*What resources/worksheets could we create that we could then include as relevant according to the young person's needs?
<html><a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Creative Commons Licence" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /></a><br />This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a></html>

See a readable summary of the terms of this license [[here|https://creativecommons.org/licenses/by-nc-sa/4.0/]]
!! To cover with team:

''Data: 2pm-2:45''

*what we need from from them data wise - direct, indirect and when we need this by 
*new spreadsheet - presenting need and focus of work
*POD data when we need this

''Review of service: 3:00-3:30''

Spilt into two groups
*think about successes/ challenges over the last year 
*What we need to keep same and what we need to change for next year

!!Groups: 
# AS, CHe, Cha, 
# JP, EJ, CL, RS

Data:

* Direct and indirect sessions, accurate in what counts as an email.
* Same spreadsheet used previously.
* Pod data: make sure SDQ, GBO, RCADS, SRS are up to date by the 30th September.
* Reporting period is from 1st July to 30th September.
* * Direct sessions are only with a parent and/or child. Indirect is with anyone else.
* The last day of data collection is 30th September. If your first day of work is the 30th September, then make sure data is entered the previous week.

!!Questions regarding data:

* ''When we work with LAC, who counts as direct and indirect?''

**direct: parents, Foster carers and young people.
**indirect: a key worker or another professional who are involved in the network would **There may be times you speak with a parent quickly to check in how things are going, that should be recorded as a well-being review.

*''what is a well-being review?''
**a type of direct session 
**quick general check in 
** Some of us can't work with the established goals or engage in the services they wanted to, so it is to check in how things are going.
** troubleshooting, if they managed to get to school well, and if they managed to do the homework you provided. 
* ''Are all calls are recorded as sessions? ''
** not necessarily - could be to book in  time for a session 

* ''If you do not have an SRS and GBO, is that considered a session? ''
**Sessions do not have to have outcome measures to be counted as a session.
**The first direct sessions does not have to have necessarily goals established if you cannot identify them yet. Despite not having established goals yet, these conversations are still considered direct sessions.

* ''When do emails count?''
**indirect: to professionals 
**direct: to parents/ CYP 
** Emails do not count as another contact if they are summarising a conversation that has been had over the phone.
** It does not count if it is an email arranging contact with the family. 
**it does count if you are phoning a social worker to find out more about the current problems 
**Individual emails do not count, emails chains regarding a specific topic or information counts as 1.
**If you have an email chain with social care and school, that counts as one indirect session. 
**An email to two different professionals, and then two phone calls about the same topic to different professionals, it is considered one indirect session. 
**If we summarise the feedback in an email after a phone call, we do not record that, it is still one session. 
* ''what if you split the session into two over the same week? ''
**If it is about the same intervention/ topic then it is one session but if its more than 1 intervention then it is considered 2 sessions. 
* ''When a consultation is done, and you have different conversations with people, how does it count? ''
**That counts as 1 session. 

* ''How do we count text messages?''

** They could disclose something risky over text message
** Difficult to maintain boundaries - some will only use text messages and will reply when suits them 
** Some people are using text messages as main form of communication 
** Difficult to decide what this counts as, session or well-being review? There is an element of relationship building, but goals have not been decided yet.
** Discussing how they feel, what are bad feelings etc. - this sounds like an intervention.
** Can count as a well-being review or a session based on the content of the text messages

!!Review of service:
* Clinician goals.
* LAC/Complex cases reporting.





!!What is here?
This is an introduction to this important concept, that sits at the heart of the AMBIT approach to [[Learning at Work]], which is part of the [[Core Features of AMBIT]].

!!AMBIT emphasises learning 
Implementation science suggests that embedding research evidence in our day to day practice is a challenge.

There is also limited research evidence for what works with clients typically seen by AMBIT-influenced teams.

''Therefore we need to learn as much from our local experience as from the existing evidence.''

//''So how do we create organisations that genuinly learn together from their experiences, so they can adapt and work more effectively ?''//
 

AMBIT's ideas in this area are influenced by the work of Prof Peter Senge (Harvard Business School) - whose book "The Fifth Discipline" about learning organisations applies systemic thinking to the work environment.

Senge proposes that successful organisations are those which have the capacity for adaptation and learning. He emphasises that learning ''collectively'' as a group is at the core of this.


It advocates that teams:

*Fimd ways to promote the conditions that encourage team learning

*Develop shared mental models (ways of thinking about their practice) that underpin their work.

* In order to do that above, and for for learning and change, there needs to be a balance between 'enquiry' (about others' ideas) and 'advocacy' (being explicit about your own ideas). These need to be balanced NB this fits closely with [[Mentalization]]



*Learning needs to be given an explicit place in the everyday routine work of every team, with a focus on teams better understanding:

1.How they do things

2.Why they do things that they 

3.How they could do things even better

''In AMBIT Manualizing is a vehicle to support this kind of team learning. Over time a team’s local version of the manual comes to represent the collective thinking and learning of the team.''

Please see here for a very brief overview by Peter Senge of some of the key themes of his work. 

<html><iframe width="560" height="315" src="https://youtube.com/embed/HOPfVVMCwYg" frameborder="0" allowfullscreen></iframe></html>

Please see here for a video of Peter Fuggle discussing: 'Is the concept of a Learning Organisation useful in AMBIT?'  (AMBIT conference 2013)
<html><object width="560" height="315"><param name="movie" value="//www.youtube.com/v/bKBRDVVf5yc?version=3&amp;hl=en_GB&amp;rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="//www.youtube.com/v/bKBRDVVf5yc?version=3&amp;hl=en_GB&amp;rel=0" type="application/x-shockwave-flash" width="560" height="315" allowscriptaccess="always" allowfullscreen="true"></embed></object></html>

In summary, the reasons for encouraging AMBIT teams to consider the ideas of Learning Organisations are:-

*To connect teams to some of the evidence base around organisational practice
*To emphasise that team functioning is a core aspect of AMBIT and will be affected by organisational factors
*To help teams consider their own values around learning
*To help teams think about conditions that promote openness to learning and barriers to learning in their contexts
*To highlight that many of these ideas over lap with [[Mentalization]] and that mentalization itself is an important part of a learning e.g. why do we do it like this and not this? What is it about our team that means we do things this way and not that way?  






 

* What are the key dilemmas to cover in the next 4 weeks?

* Teenagers who previously struggled to engage in school and had attendance issues. It may present a problem if they have to go back to school now. Also children who used to have challenging behaviour at school.

* Parenting evidence based interventions for ADHD issues, in terms of supporting home and school, Adapt interventions to ADHD and practical ideas. Are there particular models that have been tested? Eg. focus on praise, communicate effectively. But it is important to have clear adaptions. 

* How to help parents manage their time when there are other siblings in the room, eg. giving quality time. 
* Self emotional regulation interventions, more specialised to each child's needs.

* relationship between home and school. When school and home have different ideas about their perception on behaviours.

* Have a shared drive or use the wiki to put the resources we use. Share the resources with each other.

* Someone can bring a case with questions, and invite the group to train each other and share their ideas. Applying theory to the actual case. We can do this according to the topic of the week. 

* Do a session about ASD, ADHD, parenting relationships. More knowledge based and have discussions together about it. 

* Go over anger work, emotional regulation, motivational interviewing, working with separation anxiety, working with parents and their relationships difficulties they have with their children and the children's school. Working with parents to support emotional regulation, self harm, work on self-esteem.

* How can we structure this?
1. One brings a case of emotional regulation. We can start by presenting the ideas to do with emotional regulation and what do we know related to the topic. Eg: what is emotional regulation, what ways are there to help parents regulate emotions, what other ways you can apply ideas for emotional regulation. Present the case and what has been done which has worked. Tie this with a specific issues you have encountered. 

2. Invite more ideas to learn from each other.

* For next week each one can bring their own ideas about what they have worked on regarding self-esteem.

! Ideas to hold in mind when working with parents
! 
''Parents who do not want to be involved in sessions''

It is helpful to think about how parents/carers can be involved in our work. Ideally we do not want to be setting up separate relationships with children and young people that their parents have no involvement in. Keeping linked into the child or young person's network helps to increase the likelihood of creating sustainable change. We can also miss out on important parts of the picture and perspectives if we do not try to include parents in our work. 

Some points to consider:


**how can we understand parents' thinking behind not wanting to be involved or wanting someone else to "solve the problem" and how can we validate this to show that we can see why this perspective makes sense?
**when we feel that parents feel understood/recognised by us, how can we broadcast our own thinking about why we think it might be helpful to have them involved? 
**helpful to broadcast //positive// reasons for parental involvement - they know the child the best; they might have ideas about what will/won't work; they will be around to support the YP during the week; you want to help them feel more able to understand/respond to the YP, rather than it being reliant on the worker, who will only be around for a short-time. Some parents may be sensitive to feeling judged or blamed, so we should be clear to avoid misunderstandings by naming things like having them involved is not about it being their fault, them being the problem etc. Generally the more people who are involved, the easier it can be to come up with ideas about what can help!
**having parents join for beginning or end of sessions can be helpful, so that worker and YP can share what they have been talking about and anything that can be tried out during the week before the next session
**workers could offer to update parents after sessions through a text/phonecall
**workers could collaboratively agree with the parent the plan for the session with the YP together - i.e. is there anything you'd like me to focus on this week? 


''When parents are sharing negative feelings/thoughts about the child with us''

We want to respond to this in a way that is helpful to the parent, but does not collude or reinforce their view. How can we offer the parent a sense of feeling understood and mentalized? We can use our OARS/active listening skills to respond:

-//What is it that's making you feel like that?// 

- //Can you give me an example of something that's happened that has left you feeling this way?//

- //I can see that being sworn at would make you feel completely disrespected and like he doesn't care.//

-//Its hard to remain calm and patient when you're not being listened to//. 

- //Things are pretty stressful with him at the moment//

It might feel appropriate to move the conversation into acknowledging that it sounds stressful for //both// people, i.e. the parent and the child

- //Arguments are pretty stressful all round//

-//It doesn't sound like this situation was nice for either of you - there were things you were both unhappy about//

- //You both got quite worked up//

- //I'm really sorry that you both had such a difficult evening//

If you notice that the parent is calming or appearing to feel that you are understanding them well, you may feel that it is appropriate to move into exploring the young person's perspective, although this should be done very carefully as doing so prematurely may feel quite invalidating to the parent. Acknowledging that it might be helpful to see if we could understand why this happened or where the child might have been coming from, to help us work out the best way to respond can be a useful way of testing the waters before asking anything directly. Parents will not be able to mentalize their child or be able to make guesses about what might be going on behind their behaviour if they are feeling too emotional, so it might be about marking this as something to come back or offering to make enquiries with the YP in your next session. 

Some relevant questions when the moment seems right could be: 

- //did you have any ideas about what was going on for him that made him do that?//

-//what do you think was behind that?//

- //it seems to hard to understand why someone might do that. Do you have any ideas about what might have been going on for her?//

-//what do you think he might be meaning or trying to communicate when he does that?//


<center>{{Grid Pic.jpg}}</center>






The Dis-integration Grid is a downloadable tool for exploring and planning how to go about [[Addressing Dis-integration]] in the wider network.  
 

This tool supports the worker (and client or family member) to [[Mentalize|Mentalization]] the different parts of the wider network of support.  

It supports two particular elements from the stance of the ''Core Features of AMBIT'':
 [[Respect Local Practice and Expertise]]
 and 
[[Taking Responsibility for Integration]]


!!''The Dis-integration grid:''
You can download this as a PDF file from [[here|https://docs.google.com/file/d/0B5h_CVBdhJPYOEpMRXZJd3E5V3M/edit?usp=sharing]]

{{Dgrid.png}}

  
!!''Using the grid''
The dis-integration grid is the basis of a simple brief exercise to
map out the understandings of everyone’s perspectives within a particular network around a client.

The worker does not require a proper form and might, for instance, draw up a grid on "the back of an envelope" during a meeting. 

The grid invites the practitioner to map out and to ''Mentalize'' the network. 

Firstly, we name the key people around the client (The network should include parent/carer). Secondly we use the grid to consider where are the areas of agreement and disagreement within the network?

We do this by asking ''three questions from the perspective of each person in the network''. This is the workers'//best guess//
of what //they think others think//.



 The three questions are:
 

# ''What is the problem?'' (why is it happening?) - Looking for difference/dis-integration around the explanations/theories people hold
# ''What to do?'' (what could help this problem?) - Looking for dis-integration/difference around practice
# ''Who does what?'' (who should be helping with this problem or possible solution?) - Looking for disintegrations/differences in the wider system around understandings of people's responsibilities

NB Sometimes we realise we don’t actually know the
answer in some of these areas, which can be helpful to identify in itself.


!!''Finding the Connecting Conversations''
When filling in the grid, the keyworker will particularly be asking themselves...

*Where are the 'sticking points' in the network?
*Who may need to talk to whom and about what?
*Which parts of this picture can I influence, even if only a little?


So, the point of systematically mentalizing the different positions in a network is to spot the crucial few  ''key conversations'' that need to occur between different parties within a care network in order to reduce dis-integration and increase integration where we can.  

We call these ''Connecting Conversations''


So, having completed the grid, the keyworker considers:

#What ''Connecting Conversations'' (probably no more than two) might help the network to work better?
	
#What could I do to //facilitate// such conversations - so as to maximise the likelihood of improved understanding of roles and responsibilities?

!!''Additional information''
Please see [[Addressing Dis-integration]] for more explanation of the problem that this "back of an envelope" tool is designed to address.  

This 2-part video gives a 40 min explanation on Addressing Dis-integration and using the Disintegration grid


<html><object width="640" height="480"><param name="movie" value="https://youtube.com/v/tOPf5IaNlvc?version=3&amp;hl=en_US&amp;rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="https://youtube.com/v/tOPf5IaNlvc?version=3&amp;hl=en_US&amp;rel=0" type="application/x-shockwave-flash" width="640" height="480" allowscriptaccess="always" allowfullscreen="true"></embed></object></html>

<html><object width="640" height="480"><param name="movie" value="https://youtube.com/v/sS11nRVtf8Y?version=3&amp;hl=en_US&amp;rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="https://youtube.com/v/sS11nRVtf8Y?version=3&amp;hl=en_US&amp;rel=0" type="application/x-shockwave-flash" width="640" height="480" allowscriptaccess="always" allowfullscreen="true"></embed></object></html>





!!''Feedback from AMBIT-influenced teams (2014)''
>>"Disintegration grid has really helped in working with partner agencies and ensuring we identify when there are differing goals in the network. Also has helped greatly in understanding viewpoint of young person and family."
>>"Disintegration grid has been v useful. We are developing a network protocol to help us recognise familiar situations and to have a written aide memoir of things to do and consider."

This page provides you with a list of all the pages that are relevant to the AMBIT Training. You may come across some broken links as these pages have been copied across the AMBIT manual - bear with us while we try to sort through these!

<<list-links "[tag[TrainingCore]tag[TrainingCore]]">>



[[EMHP Wiki|https://manuals.annafreud.org/emhp/]]
! What is this page about?

These are some of our ideas about how to support families with home schooling during the period of lockdown. 

''School work: mentalizing the parents' perspective''

Be curious and respectful in relation to parents' stance on school work at the current time. Check out what the arrangements are from the child's school with respect to getting on with work and the parents' view on how they want to respond to this. Some parents may feel that it is possible/helpful to them to have a set structure throughout the day; other parents may be prioritising things differently around work etc. Think about the balance of children being able to access some learning and educational opportunities through the day and consider how link up could happen with CYP's school if you feel that it would be helpful to think with them about how best the child's education should be supported at the current time. 

!Questions to explore with parents

* What have the school set? What are the arrangements?
* What are you idea about what your child should be doing around education?
*What's the current communication between school and home, both with parent and child?
*Is there anything school could help with from the parents' or CYPs' perspective?

*Do parents need any support with education? Which parts do they feel they are able to manage? Are there parts they would like more help with?
*How could we involve the network in supporting schooling? It might be helpful to draw on others outside the home for remote support, ideas, to do some learning activities with children. Other parents might provide good moral support. Children might be able to work together with other children over the internet or work on things to then do "show and tell" with each other when they've finished etc. Remember to enquire about: 
**Family members 
**Older siblings
** Family friends
** school friends 
**parents of school friends

! Ideas to help make school work more fun:

There might be lots of ways that parents could help to make the work more manageable for CYP. Not all of these would work for all children!

*Mixing up school work with things that are more fun!
*Visual timetable (CYP could design it)
*Put it in shorter chunks of time
* Sticker charts for progress
*Making certificates each week
* Praise board - sticking up notes/messages somewhere visible in the house to show positive feedback about how children in the house are doing with their learning
*Making a space for learning in the home (any ways that the child could personalise this, maybe make a sign to say "School time, do not disturb etc)
* Could they have a toy to keep them company? Could they set some work for their toy as well?

! Mentalizing the child/young person's perspective

How might they be feeling about the change for schooling?



!Other considerations:

*Some children might be missing school and their friends
*Help people to remember that home schooling isn't forever
*Helping boost confidence for those that it might feel harder to learn at home rather than in school environment (they might be getting less tailored help)
*remembering that parents might be feeling deskilled or unable to do it enquire what do they feel able to do.
*Could consider sharing with families ideas from online. 
* Eligibility criteria will need to be different for the Wellbeing and Targeted Services

! Wellbeing Service 
will be based on specific problems - mild to moderate difficulties with low mood, anxiety and behaviour. Less professional involvement. The problem may have a mild impact on functioning. Referrals likely to be received from self/parent/schools

!!Possible inclusion criteria: 
# A parent or young person who is actively wanting help (not just a referrer identifying the problem but the parents/YP themselves) 
# A parent who actively supports the process of help seeking for the young person. 
# Some likelihood that the problem started within the last six months. 
# Some indication that the problem is not part of multiple problems. 
# The severity of the problem may be defined using a standardised questionnaire. 
# A range of scores on the Parent SDQ could be agreed. So cases falling within the SDQ high range (the third highest of Goodman's four category model). Using this four band classification, we could take an Parent SDQ in the high range (emotional score 5-6: conduct score 4-5) as indicating a moderate level of severity.  
#Similarly we could take an agreed cut off score on the RCADS. 
# In practice, local services are likely to agree a combination of the above. 

!!Possible Exclusion criteria: 

# Evidence that problems have been around for over six months. 
# Evidence of high level of family dysfunction and family conflict. 
# Evidence of multiple problems. 
# Extreme risk 
# If engaged in other work, then may not be able to focus fully on the intervention 


!Targeted Service 
will be children and young people that fall in to one of the vulnerable groups. They may not need a direct intervention. The network around the child may need an consultation.
<<list-links "[tag[Emotion Regulation]]">> 

''What might Emotion Regulation difficulties look like?''

* Externalising behaviour: aggression and violence towards others.
* Hard to label emotions.
* Hard to talk about emotions. 
* Not being able to express how they feel using words.
* Might be hard to focus on tasks.
* Could be living in chaotic/stressful circumstances- children might be finding it hard to make sense of things going on around them.
* Impacting on their relationships – fallings out, conflict.
* Not being able to respond to people appropriately.
* Not being able to show emotions in an age appropriate way.
* Big feelings, but might not be seeing the other emotions that might be going on – either because they are getting misattributed by adults as anger or because children might not feel safe to express particular feelings (e.g. worry, sadness etc). 

''What might be like for these children who struggle with emotion regulation?''

* Might be lots of negative interactions.
* People reacting to them in less helpful ways.
* Becoming isolated or not much space to talk/share with others.
* Might be not be being responded to with empathy and connection – underlying needs might be the same as a children who is withdrawn, but the child may attract less sympathy/understanding, rather a focus on their behaviour
* Might feel unable to control their behaviour easily, might feel powerless.
* Might feel that their point of view isn’t heard or asked for.
* So much focus on behaviour, that people might not sit down and explore much with them about how they feel.
* Misattributions around intentions – framed as doing things deliberately, on purpose, to wind people up, etc. 


''How do children develop emotion regulation skills?''

* Through interactions with people around them – ie. Parents/carers are initially very important, but other adults can be influential too.
* When parents can make sense of what the child is thinking and feeling.
* Parents that help the child to manage their feelings and have sensitive responding. Then the child moves to being able to manage the feelings more independently.
* Having family members who help us by labelling/guessing how we might be feeling; using emotional labels about self/others. 
* Family relationships where a range of emotions are expressed and examples of how these feelings get managed and resolved and how we can move on from them.
* Sensitive responding – parents being curious, empathic, trying to understand things from the child’s perspective.
* Modelling how conflict gets resolved.
* Teaching moment vs. discipline moment – trying to make sense of behaviour, rather than giving reaction. 
* Setting appropriate boundaries and limits in an appropriate way.
* Adults might forget to think about the behaviour as being something that you might not yet have mastered or know how to manage independently.
* People might be responding in ways that are not attuned to the YP’s stage of development, so they are missing opportunities to do it.
* Might find it hard to use their parents for help (looking at circle of security).

''Parental/Family Factors
''

*  Gender stereotypes – what families might expect of boys/girls.
* Culture – how are feelings talked about/expressed in the family?

''
Emotion regulation: questions to build an understanding''

* What are the current behaviours? What do they look like? Give an example? Explore onset, frequency, duration.	
* How does it look at home, school?
* What does a good day look like?
* How often do they become dysregulated?
* Has it always been like this? When did it start?
* What helps them to calm down? How does it usually end?
* What do they do/do you notice when they are feeling x?
* What feelings are particularly problematic? What do they not notice much of?
* What do you notice about how it starts? What are the triggers?
* How do the other children respond? What’s the impact on others around the child?
* What are the relationships like? Siblings, who is it better or worse with?
* What are the rules/boundaries at home/school? How are these being communicated? 
* What are the current strategies to manage the behaviour in the classroom?
* How are emotions spoken/shown about about in the family?
* What kinds of things prevent from happening or help?
* Are there things that make it worse or more likely to happen?
* Do parents/adults have a sense of what is going on behind the feelings? 
* Is there anything going on that might have made them feel angry? 
* What’s it like for you when that’s going on? I can imagine it would be hard to stay calm!
* Developmental history.

''Intervention Ideas''

* Play/creative methods can be useful to explore and intervene (What feelings do children know? Which ones come to visit them (at home, at school, with friends etc)?
* Using feelings cards – which one is this? How do people show this? What does someone look like when they feel this? What kinds of things might make someone feel this? Can you think of a time when you felt like this? Someone you know felt like this? 
* Feelings charades – acting out what the feelings look like and having to guess.
* Using scenarios – give a picture/scenario and asking what the people involved might be feeling and why. Again using questions to link back to their experiences (have you felt like this?)
* Feelings backpack – which ones do they carry around, which ones weigh them down?
* How we manage different feelings: Understanding what might trigger them – what kinds of things make you feel x?
* What helps – what do you do, what do other people do that helps when you’re feeling x?
* Ideas of what might help – which have they tried, could they try, which have/haven’t previously helped.
* Using hot cross bun to explore the experience of a feeling in detail, in terms of accompanying thoughts, behaviours and body sessions.
* Metaphors like anger thermometer, volcano, racing car etc to explore the experience of the onset of the feeling – gradual, sudden, how can we spot the signs its coming and what could we do at different points before it boils over, gets too hot etc etc.
* Acting out stories/scenarios with the Lego people or toys to help explore situations, feelings, perspectives, behaviour and different endings – how people could have helped each other to make a different ending.
* When you’re like this, let’s pretend this one is your parent/carer, what can they do to help you? What doesn’t help etc.

''What might emotion regulation difficulties look like?''
* Externalising behaviour: aggression and violence towards others.
* Feelings of denial and resistance in last session.
* Perhaps many things will come up in the ending, finding more difficult to wrap things up. Maybe it is better to have a last session with the child and parent, to manage their feelings about the ending in a better way and for the parent to see how the child is managing the ending.
* Things can come out because of the ending, maybe young people panic it is the last session or because they know they will not be able to get into it as it is the last one.
* Some young people may project rejecting feelings into you, leaving you with all difficult feelings.
* Difficult endings when there is pressure from the rest of the system to carry on and becomes difficult to hold your own line and being firm about what you need to do, being realistic about the amount of sessions provided. Particularly when you are the good object in their perspective. 
* Adolescents with higher needs: try to set relationships with people that were already working with them, those relationships can be left in a better state when you finish working with the adolescent.
* The end is also in the beginning: being clear about the amount of the sessions and the ending is hold in mind from the outset of the work.
* Prompt to express and name with your client how it is like to get to the end.
* It can be difficult to put the boundaries and to decide the end but authority is important too.
* Who can adolescents speak to if you are not there? Do the scaffolding relationships, improving connections in the network. What can you do if the young person says he/she does not want to speak to anybody else except you? Do pros and cons, do motivational interviewing that may influence that.
* Things that went well in ending sessions: portfolio, do a belcro for him to do activities to share things he does with parents. Have a final session, acknowledging things that went well and things that did not go well and why they didn't, and what will they do to reach those goals when you are not working with them.
* do a reflective task: reflected all the good things about working with the young person. What we would have done differently if it was face to face? Also acknowledging difficulties.
* Have a TAC meeting before the ending or send an email, to have everyone together to know what you have done with the young person and to support them how they can carry on. Leave the network with a clear idea of what has been done and what they can do next to be supportive.
! Building and sustaining engagement when working remotely

We want to capture our ideas about how we are approaching this, as we move to online/telephone working

! Paying attention to the space/structure

*Can the CYP talk freely in the space that they are in?
*Is it helpful to have the same time each week?
* Shortening the session according to what feels manageable for the YP (shorter sessions may help with concentration)


! Skills and stance

* Showing ''empathy'' about their situation - really trying to understand how things are for them at the moment. Acknowledging the difficulties that they might be raising (e.g. conflicts at home, boredom etc) and validating it
*''Sensitive attunement'' - getting the right balance between paying attention/inviting discussion about things that are important to them at the moment, rather than starting with things that might be important to us 
*Being aware that we might need to spend a little longer ''building the relationship'' particularly when its people who we haven't met before. 

! Practical ideas and activities

Which of these are helpful  will depend on the age and stage of the child. 

*Asking the YP to give you a virtual tour of their house and/or introduce you to family members
* Encourage them to draw while we were meeting and then the YP could show me (e.g. if they are struggling to sit down)
* Comment on something they are doing (e.g. eating cereal - what's their favourite etc?)
*Thinking with CYP about keeping a ''diary/record'' of things that have happened during the week so that they have something to refer to during the session
*Giving the parent enough space to ''mentalize'' their own perspective/position about the current situation, before expecting them to be able to mentalize their CYP's position. 
*''Playing games'' - playing connect-4! Worker had a connect-4 set. YP was talking about what was on his mind as the game was being played. 
* Asking the YP to show you drawings, their favourite game, something they like
* Kick ups - find a ball, ask YP to see how many kick ups they can do; how many they do determines which question they answer on the list of "getting to know you questions". 
* Jenga - online version? Online spinners with getting to know you questions?. 
*rolling a dice - number relates to a question. 
*Physical activity challenges through the sessions to help provide movement breaks - roll the dice and see what the activity is (star jumps; lap of the house) - helps with regulation and concentration and also to support YP to start to notice when they need to have a movement break
*sentence starters/completion - could make a quiz out of those


*Setting ''tasks'' between sessions - asking child to draw a picture of something he's done during the week each day that he can then show during the sessions. Could then talk about "how were you feeling? when you were doing this?". This can help motivate them or build a connection to the next session

! Ideas for adolescents

*Quiz?
* Chatting about their week - what have they been doing?
*Might be easier than playing a game

! Barriers

__YP cancelling sessions__

Different options:

- Could just defer to the next scheduled session
- Could offer a shorter check in at an alternative time if this can be accommodated (perhaps especially if this is near the beginning, where you might be trying to build the relationship)
- Could have an explicit conversation to check whether the current arrangements are working or could be changed to suit the YP's circumstances better - what was the reason for the cancellation etc?

__Practical barriers - e.g. phone broken, no access to iPad, battery too low!!!__

-Send a reminder text/message (with enough notice!)

- Pre-empting technology problems or other practical problems - make sure your phone is charged and you've got a room etc

- Agree an alternative method; do some problem solving.

- YP could put the appt in their phone calendar or set an alarm to remind them

-Being persistent and problem-solve


__When YP don't want to use video, which makes it harder to pick up on non-verbal cues__

*Remembering that you can't see each other! Making your reactions verbal, as they won't be able to see you nodding etc. Might need to do more verbal cues that you are listening (e.g. mmm, ok, etc) 
*If want to show the YP something - "I would like to put my camera on a bit so that I can show you something - you don't have to put yours on or you could put a sticker over it so I can't see"
* You always offer to show your face even if they don't want to use video
*Could use video for some of the session if that would feel manageable
*Be mindful that the camera could be a barrier in itself - e.g. might make a shy YP feel less confident

__Worker not being clear of the plan/ideas of how to engage them over the phone (i.e. in Active Planning terms the plan is not clear in our own minds!)__

*Talk to our supervisor to make sure we have specific plans for each of our clients
*Have more team discussions about how to adapt the resources that we have for remote working
* Ask the client (CYP or parent)



<center>{{Epistemic Trust image.jpg}}</center>


!!What is it? 
''Epistemic'' (the greek word for //knowledge//, or //the roots of knowledge//) ''Trust'' refers to the specific kind of trust required by someone to allow learning to take place by one person from another person. 

In other words, the kind of trust needed to learn //through// a relationship. 

This concept is linked closely with the idea of the relationship to help, which conceptualises how a client may experience and relate to those attempting to offer help.


Epistemic trust describes a state in  which the person who is the //learner// holds a sense of trust that what is being offered by the //teacher// has social value to them// i.e. a sense of trust that this information is meaningful and relevant //''for me''. 


Epistemic trust is triggered by the experience that the person who is in the //teacher// position (known as the 'pedagogical stance') has authentically connected and understood the crucial  things about the //learner//  - not about people in general, but about ''__me in particular__'': the sense that "you have noticed and understood what it is like to be me, here, now, in THIS predicament."

''What this refers to, then, is the experience that a //teacher// has accurately [[Mentalized|Mentalization]] the //learner//.'' 

*It is this experience of //being mentalized// and feeling understood, that opens up a state of epistemic trust necessary to receive and learn new social knowledge. This knowledge then has the potential to change our perception of ourselves or the social world


* This is thought to be an //evolved mechanism// for helping humans to take on complex social learning from safe sources...//"When I saw in your eyes that you had accepted me, ''understood me'', right here, right now, it was as if the door opened and I was interested in what you had to say..."//

Below is an animated sequence briefly representing the concept of Epistemic Trust.


<html><iframe width="480" height="360" src="https://www.youtube.com/embed/5PabhW_8JoY?rel=0" frameborder="0" allowfullscreen></iframe></html>




It is possible to see how this kind of trust is important in the process of learning through many different types of relationships e.g. a student and teacher, a client and therapist, a parent/carer and child etc.

But, whilst the learning that goes on through one specific relationship can of course be very important, it is thought that there is a broader and more general benefit that may come from the creation of epistemic trust. ''This is the ability to generalize epistemic trust to other relationships and situations, which then open the capacity to continue learning about the social world in other contexts.'' e.g. outside of the therapy relationship.

!!What is the relevance to AMBIT?

Epistemic trust is a crucial concept in AMBIT ultimately because we want to support people to learn and move forward in life. However, many of the clients with whom AMBIT influenced teams work, can be in a state of being 'closed off to new learning'  (known as epistemic hypervigilance) This means that adapting or changing based on new information is very hard. This may often be for good reason- that past experiences of relationships may not have been helpful or entirely trustworthy, hence it is adaptive //not// to trust what comes from relationships. 

So, a key challenge for AMBIT influenced teams is the creation of epistemic trust between a client and a member (or members) of their helping network so that new learning can take place. Much of AMBIT focusses around how a team around the worker can //support// a Key worker to do this. However, in AMBIT we emphasise that 'workers' energy must be balanced between developing that crucial keyworker relationship, and, conversely, ensuring that there is a [[Keyworker well-connected to wider team]]'' - AMBIT is not individual therapeutic work, but using a team to support individual helping relationships.
 


<html><iframe width="560" height="315" src="https://www.youtube.com/embed/ZBeEOkwLToM" frameborder="0" allowfullscreen></iframe></html>


Below is a video clip of Prof Fonagy explaining this concept in 15 minutes.

<html><iframe width="640" height="360" src="https://www.youtube.com/embed/X1TBqEJMe3k?rel=0" frameborder="0" allowfullscreen></iframe></html>

This theory derives from experimental work by Gyorgy Gergely, Gergely Csibra and colleagues. You can find a link to a key academic paper by the authors titled ''The social construction of the subjective self''.




*YP wants help to manage his anger. Parent wants the YP to manage their anger better
* To help parent manage child's behaviour (angry outbursts) - how to prevent situations from escalating to that point
* To increase stucture, routine, boundaries
*Parent asking for their CYP to have different ways to put their feelings into words

We would like to write a page to reflect on our experiences of practicing in a culturally-sensitive way, so that we can ensure we maintain this focus in the new service
This page provides editors with guidance on how to format pages in the wiki, keeping in mind the accessibility of our readers

!!''General format''
*All manuals to have a Top Menu bar 
*All manuals to have the same size side bar 
*All manuals to have the Anna Freud logo on the side bar
*All manuals to have the name of the manual on the side bar in same colour (black)

!!''Colours''
*Colour on brand for links, top bars, titles, text colors (ie make the standard ‘blue’ a AF blue?)
*Different colors (as long as on brand) for top bars for different manuals
* Avoid the following colour ''combinations ''as they are commonly unfriendly to those with colour vision deficiencies: 
**green/red, blue/purple and light green/yellow

!!''Text''
*All text to be in ‘New verdana’
*The spacing should reflect the size of the font- i.e. headings should have larger spacing around them/ underneath them and main text should have smaller spacing (By a fixed amount that is consistent across manuals)

!!''Headings''
*Use headings correctly to give structure to pages and make content scannable. Do not use bold text //instead //of headings (choose H2, H3, etc.) 
*All word in headings to begin with upper case except for joining words such as: a, and, of 

* ! (H1): ''don’t use'' in page text as too big (same size as page title)
* !! (H2): used for all Headings, and to be in'' bold black ''
* !!! (H3): used for all subheading and to be in bold black
* !!!!! (H5): to be used for ‘Source:’ not bold (Should be at the top of the page)
* Headings should not include any symbols such as ':' or full stops

!!''Linking''
*Google doc buttons: need to be smaller, rounded edges – change colour when you hover over it?
* YouTube button- to be created small as well but different colour – link to style of youtube- to make it clear 
* Website links- to be hidden by:
 [[ 
word | website ]]

!!Videos & Images

*Use captions for video content & images
*Do ''not ''convey meaning via visual media alone – especially avoid text on images (this is not screen reader accessible and won’t respond well to resizing on different devices.) 

!!Other
*''Never use'' ‘click here’, ‘read more’ or ‘here’ for your hyperlink titles. Use a short and descriptive title that describes the link destination e.g. 'Manual on Anxiety & Depression'
*Remember reading is more difficult online than in print 
*Keep copy concise and meaningful
* Something that you might do near the beginning, to help you pull together information about a young person

*There are different approaches to formulation, depending on model

** CBT - might be focused on understanding how people's perception of events (thoughts, beliefs etc) might be contributing to their emotional distress and unhelpful patterns of behaviour. 

** Systemic - deconstructing problems and understanding patterns. How does the problem fit in context. Attempted solutions to problems keep the problem going

* A formulation is a hypothesis or set of hypotheses - its a best guess and can always be changed/revised. 

* Formulation is ideally a collaborative thing

*5Ps approach to formulation - a broader way of formulating. 

**Presenting Problem
**Predisposing factors - things that has made them vulnerable to having this problem (early experiences)
**Precipitating factors - triggering events, more recent things that have happened (around the time of onset)
**Perpetuating factors - things that keep the problem going in the here-and-now
**Protective factors - things that are going well, that might be going well, resilience factors, 

* Aim of formulation - to come to shared understanding of the problem 

* Can you do another formulation at the end to see if anything has changed?

!!!''Summary of the Green Paper''
This summary is provided by the ~DoE and ~DoH as a short guide to the Green Paper.

{{Audit Age distribution.PNG}}
  
''1. About the green paper''
This green paper is about what we want to do to help children and young people with their mental health. A green paper is a document where the government states what it wants to do, so that people can tell the government what they think.

In this quick read version of the children and young people’s mental health green paper we explain what changes we want to make. The changes will affect:

*pupils, students and staff at schools and colleges
*specialist mental health services
*families and communities


''2. Plans for schools and the NHS''

2.1 ''A mental health lead in every school and college''
We want every school and college to have a designated lead in mental health by 2025. The designated lead will be a trained member of staff who is responsible for the school’s approach to mental health.

This designated lead will:

*oversee the help the school gives to pupils with mental health problems
*help staff to spot pupils who show signs of mental health problems
*offer advice to staff about mental health
*refer children to specialist services if they need to

The designated leads will be offered training to develop their skills in leading mental health work. We will use the Teaching and Leadership Innovation Fund to look at developing training to build the skills of the designated leads and support them in delivering whole school approaches.

We also plan to ask for people’s views on how children and young people should learn about mental health in school.

2.2 ''Mental health support teams working with schools and colleges''

Mental health support teams will be trained staff linked to groups of schools and colleges. They will offer individual and group help to young people with mild to moderate mental health issues including anxiety, low mood and behavioural difficulties.

The support teams will work with the designated mental health leads and provide a link with more specialist mental health services. This will mean that schools and colleges will find it much easier to contact and work with mental health services.

Mental health support teams will be the link between the NHS and schools. They will work alongside other people who provide mental health support including:

*school nurses
*educational psychologists
*school counsellors
*voluntary and community organisations
*social workers

2.3 ''Shorter waiting times''

The government wants to reduce the time it takes to get treatment from children and young people’s mental health services. Some of the areas with new mental health support teams will try out ways of bringing this time to 4 weeks (quicker for young people who need very urgent help).

2.4 ''Mental health of 16- to 25-year-olds''

We will set up a new national partnership to improve mental health services for young people aged 16 to 25. The partnership will start by deciding which areas to focus on. This might be student mental health, and looking at how universities, colleges, local authorities and health services work together.

3. ''Improving understanding of mental health''

3.1 ''Internet and social media''
We will work with the Children’s Commissioner to explore how social media affects the health of children and young people.

The Chief Medical Officer will produce a report on the impact that technology has on children and young people’s mental health.

3.2 ''Researching how to support families''

We want to know how we can give the best support to families who need more help. We will gather information to look at:

*how parents and carers can bond better with their children, which helps their mental health
*how we can support families where parents or their children have a higher risk of developing a mental health problem

We will use the results of our research to create guidance for local areas about the best parenting programmes. This will help local areas improve the support they give to families and get value for money.

3.3 ''Researching how to prevent mental health problems''

We will bring different mental health experts together to look at how mental health problems can be prevented.

The group of experts will consider the best evidence and look at where we need to do more research on how to prevent mental health problems.

The full Green Paper report and the government responses to the consultation can be found [[here.|https://www.gov.uk/government/consultations/transforming-children-and-young-peoples-mental-health-provision-a-green-paper]]

The service offer of providing group support to unaccompanied minors has had to change to online working.

!!!What hasn't worked well about this group 
!!!What has worked well?
!!!What ideas do we have to improve the running of this group.?
*Needs to be held in school time
*Need to have one key contact at school or schools that helps to organise the time for the young people
*Need to organise the support groups by age and by languages spoken - more than 1 non English speaker in one group can become complicated with interpreters.

!!Update on the UM group - tree of life 2020
*patchy engagement 
*we feel this is for different reasons; late getting home after school, appropriateness of referral; how much the referral was explained to them before-hand; prior comments- both school and social services/immigration service meetings.
*''Ending letters to be sent''

!!New group- 2021
*to take some of the TRT material - particularly strategies and bereavement 
*to make every session a stand alone session within itself so that we are not having to recap
*we will need to consider if the DAlanguages company have any other multi-language 
*pre-referral meeting - to screen them before the referrals are discussed with the YP/ made to our service.
*To make a referral protocol/pathway that can be shared with prospective referrers.
*to create a leaflet to share before referrals 
*To pull referrals from different schools- need to be clear with Jo and Nayna about this.


!!Referral pathway
#''WEST to meet with Nayna''- to screen potential schools and young people. To also include the change in the type of group.
#''WEST to meet with school leads'' NCC/ other schools DSL/SENCOS to think with them regarding potential referrals 
#''School lead and Nayna to have a discussion with the YP'' regarding a potential referral to group
#''For school lead to JOINTLY create a referral form with YP'' 
#''Initial individual meetings with YP'' during school hours for school leads to support these.
''NOTE:'' To have a key contact that we bring any concerns/ information - for this to be either school or Nayna?

__''Considering the inclusion team''__

*Need to consider the expertise of the inclusion officers and how they could be brought in to support schools
*what is our role or would it be our role along with the inclusion team

__exploring concrete strategies with the school __

* What does a good day look like? what does a bad day look like? What made the good day look like that?
* What strategies have you tried?What is working well what isn't working well? What part of the things that you've tried that aren't working?
* Whats been done in the past with children that have similar problems? How did this work? 
* Involve others in the network from the school that may be less emotionally effected by the behaviour such as the SENCO or deputy head. These people may then step in to support the teacher or may be able to give a different less emotionally charged perspective (on the shore of the pond). 
* create a record of the suggested strategies and refer back to it if/when school struggle with the behaviour again. - more often than not the strategies haven't been executed/ tried fully.

___How to we feel about trying these thing?__

* Concern that the school are looking for specific answers and we are asking them more questions. - try to be as transparent/ broadcast intentions- the plan is a summary of stuff that have been developed through these questions. 
* Not always as simple as strategies so I just need to be clear on what you have tried already to make sure we are trying something that hasn't already been done.
*children that do not have an EHC - schools may feel reluctant to 'treat the child differently' or providing different support. - however if doing the same as everyone else isnt working we may need to change this. could state something like we would hope they could learn to behave the same as everyone else but may need to put in temporary solutions/ a bit of flexibility so that we can get them to this place.
*schools may have concerns that they wont be able to explain the difference in treatment- put the question back to them - how could we explain this ? how would we explain physical/ visually seen differences to others in the class?
*adolescents may feel embarrassed of having additional time/ support/ special treatment. - needs to be done in negotiation with school and the young person - finding the middle ground getting some support that feels acceptable and balancing this against the level of support that teachers feel is needed.

__The pandemic have caused specific issues with managing behaviour ___

* Inclusion team may have ideas/ suggestions that other schools are using
*'reintegration' plan may need to be created with school with support from inclusion team.
*everything is uncertain for schools at the moment 
*schools are making decisions not to accept children with behaviour problems to come back to school at the moment as they cannot 'stay in their bubble' space. Including those that are 'in need'. School have a right to protect their staff but this is difficult for families and us supporting them.
*what is a realistic task for schools to take on at the moment? 
*what are schools able to adapt at the moment with al the other adaptions
*Schools are aware that the situation is unlikely to change even once the summer holidays are over -not feasible for children with behaviour problems to just not come in. Not entirely our remit- need to consider networks. 
*children with EHC plans 
*not empirical workers need a network approach
*lots of children will be getting new teachers in September- good opportunity to 'start fresh'

___Specific strategies___

*most strategies will be similar for most children as the setting of school is similar. 
*Checking the expectations of the day/ classroom/ school are clear to the children. - class rules etc. in the language of the school
* Making sure that the expectations of school and the tasks being asked are accessible to the child (print outs etc.)
*considering the reason why a child may go off task - how long can they concentrate? What is ability and what is behaviour? 
*consider if the structure of the day/ lesson is feasible for the child.
*reward charts
*Time out that is less punitive- give them a 'task' or a 'calm room'.
*zone of regulation plan - green, amber, red - could create a document about what keeps them in these zones/ go into these zones
*can they have something to fiddle with or is this more of a temptation to misuse these
*fidget cushions/ calming weights
*chunking work into small tasks.
*TA support- what is the right amount of adult support?
*the mindset creating cycles/ patterns of behaviour. i.e. when they are doing the right thing are they chosen for tasks/ get picked when they put their hands up etc. How can we catch them being 'good'.
*exit cards
*where is the child sat? review where they are sat and who they are around, positioning of the table/ chair etc. 
*sitting on the carpet- can they wonder around in a non disruptive way?
*good to give children 'special jobs' to be noticed for 'good' things. 
*Are there additional adults in the school that could support the child with a space to go or someone to talk to- could do some work in their office etc.
*parent/ school link - sometimes the communication to parents only involves the negative behaviour. - could create a chart or diary that both the parent/ teacher write in.
*documenting/ using these systems reveal positive anomalies and positive moments more so than were previously thought.


__''ASC specific strategies''__

* Help drawing an understanding of ''where specific behaviours come from'' to try and understand what they're communicating. Similar to the iceberg - behaviours have so many different causes. The aim is to understand the causes/ triggers of specific behaviours to try and reduce them

* ''Low arousal approach'' - reducing stimulus within the environment (e.g. noise, number of people in the space) and increasing things like space and use of distractors

* ''Distractors'' - should be motivating for children and individualised for each child. Examples might be going to their favourite place - aim is to help them self-regulate by changing their environment. Another aim is to help the emotion pass so that you can reflect on the event in a calmer state

* Think about ''language'' when children are struggling (e.g. //'you look really upset, shall we go to the swing to distract ourselves//') - sharing your thought process to help model for them how they can think about the situation and validating their feelings whilst also encouraging them to move on to something else

* ''Talking out loud'' - help children to recognise their own emotions in the moment. This can be done by commenting on the child's emotions, or your own emotions or other children's emotions. This depends on child's stage of emotional development

* ''Normalising the experience of emotions'' - this can be done by noticing and pointing out others' emotions as well as your own to demonstrate that it's OK to have emotions and that everyone has them

* ''Timetables'' - giving children different things throughout their day that are motivating to help make other subjects within the timetable feel more rewarding to complete. These things within the day will be different for each child

* ''Routine/ consistency'' in activities throughout the day is important

* ''Movement break cards'' - used to say //'I'm struggling so I need a few minutes out'//

* ''Working for boards'' - reward scheme with starts/ ticks that are velcroed on. Contains motivating item: //'I'm working towards...'//. Can also be another way of keeping child on timetable and very adaptable depending on the day and child's abilities. Can also help staff to recognise that we can't have the same expectations of some children every day

* ''Individual support plans'' - created by using Zones of Regulation. Has strategies helpful for each child - general but also specific but individualised at the same time



!!<center>Welcome to the WEST Manual! </center>



!!!Welcome to the Wellbeing and Emotional Support Team's Manual. This manual is for the WEST Service at the Anna Freud Centre who will  be based in Brent.

<a class="tc-float-right">[img width= 500 [melissa-askew-tSlvoSZK77c-unsplash.jpg]]</a>

All the pages in this manual are connected via the following Tag

!!<<tag [[Wellbeing Service]]>>    

Here are pages specifically from the Wellbeing Practitioner training sessions

!!<<tag [[Wellbeing Training]]>>      

Here is a page with a list of tags for specific areas of our work...     

!!<<tag [[Training Themes]]>>   
        

When creating a new page, ''remember to tag the page with 'Wellbeing Service''' so that it appears in the list above.

!!How to Use & Edit the Manual
For more information on editing and using the manual see below.

<<image-link "How to edit your teams manual" "luciano-de-sa-ObwMZBdEWdI-unsplash (1).jpg" "How to edit your teams manual" "200">><<image-link "User Guide" "anastasia-petrova-xu2WYJek5AI-unsplash (1).jpg" "User Guide" "210">>

How do we learn from experience?

*Through supervision
* Could do more to draw from services around us to understand what works/what doesn't work. Probably is a lot of local expertise in practitioners who have worked in the communities for a long time, which we could learn more from and be more influenced by
** How could we learn how they have build relationships with particular communities, particular schools etc?
* How could we learn more from people's knowledge in the team?
* Do we make enough connections between getting a lot of referrals from a particular school/area and understanding what might be going on?
''Always start with what do you think it is?''

SEE: [[What we think wellbeing is]]

!!14+
#everyone has wellbeing 
#WB is out emotional and social health and how we can look after this 
#somethings can cause our feelings or emotions to become more difficult to deal with- which can affect our everyday life. (activities, friends etc.)
#together we can think of ways that might help you cope with these feelings better and so get the most out of everyday life.
#we can develop some helpful skills and tools that you can then use to maintain your wellbeing
#what helps your wellbeing is individual to you so it is important to try lots of different things out until you find what works best. - this is something I can help you with.

!!Under 14's/ younger children
#everyone has WB 
#WB is how we feel and how we look after our feelings to help us feel good and enjoy our lives
#sometimes feelings can get in the way of the things we enjoy doing or wan to do (link to childs interests/ challenges) 
#when this happens we can talk to people which can help us com eup with activities and things that can help us to feel better 

!!Parents
#explain in the same way that we might explain to a teenager 
#explain it in the same way we would explain to a child and explain this is how you would explain it to the child.

!!Teaching staff
#could us the patchwork idea to think about why a YP may be behaving a certain way and relate this to the things that help maintain good wellbeing.
POD (People's Outcome Database) is an ''outcomes monitoring system'' in a website where staff or clients can log in and ''complete measures using any web enabled device''. 

Scores are calculated instantly and you can view these online with a child, young person or parent within a session.

LINKED PAGE:  [[The Importance of Feedback]]

A link to the pdf POD manual is shown below, which gives a comprehensive overview of POD and how to use it.

<<link-pdf "POD Manual" "https://drive.google.com/open?id=0B-tACu2wi4-4MEVNbWUtZFllUFk">>
For more information on how to use POD please see PODs [[information page|https://pod-database.org/info/]]. Which provides comprehensive guidance on how to use pod accompanied by screen shots and videos.

Brief document outlining how to add a new patient and complete a measure for a patient please see the instruction document below:
<<link-pdf "Instruction Document" "https://docs.google.com/document/d/1EtAYqGjO7gyKnfgWwL1x3D5nkpLo-VGv3rYLxSJyoOE/edit?usp=sharing">>

!!!Instruction videos:

<html><iframe width="560" height="315" src="https://www.youtube.com/embed/OY6tuqbRD70" frameborder="0" allowfullscreen></iframe></html>

<html><iframe width="560" height="315" src="https://www.youtube.com/embed/OiJ0i1mAoZ4" frameborder="0" allowfullscreen></iframe></html>

Some of the work that we had already agreed to undertake with families will need to be adapted, as much of this was planned to be face-to-face. 

The format of meeting will change (i.e. moving to telephone or video sessions), but for some families there may be other changes. 

Some families may wish to pause the intervention, as they are not able to prioritise this at the current time. These decisions should be made in conjunction with members of the team and others in the professional network. 

Some families may wish to adjust the goals that had been agreed (e.g. focusing less on education goals and more on home/relationship goals). New goals may also be more relevant to address, depending on particular challenges that the situation is bringing. 

Wellbeing goals will likely be still relevant to work on, although again the impact of the wellbeing need may now be different for the child, young person or family member. There now may also be additional challenges that they are facing around wellbeing (e.g. anxiety, boredom, low mood, etc) which they may feel that it is more relevant to focus on. 

! How do we approach these conversations with families?

It can be helpful to hold in mind the [[active planning]] stance. This can remind us to both check out what is in the client's mind about the plan, as well as to share what is in our own mind about it. 

For example, we might be feeling unsure as to whether the goals that we have set are still relevant for the family or we might be aware of needing to change our plan of how we are going to work on them. 

We can be explicit about our state of mind with families, by sharing our questions and thoughts with them about this ([[broadcasting intentions]]). We might say something like:

//"I know we had made a plan together of what we were going to work on. I wanted to check in with you about this, as you might have changed your mind about some of the things in the plan, like what the goals are. We had agreed to work on x, y and z. Do those things still feel relevant or would you like to make some changes?"//

Other questions we might ask:

*Which of these feels like the priority at the moment?
*Do you want to make any changes to any of these?
*Do you want to pause working on any of these for now and pick them up later?
*Is there anything new that you want to add that I could be helpful with?

Things we might want to broadcast:

* I still want to be helpful to you during this time if you feel that there's a way that I can be
* I don't want to create any extra stress or pressure
* I realise your priorities and situation might have changed, so i don't want to assume you feel able to commit to what we had already agreed
* Your situation may also continue to change, so it would be ok to let me know if that's the case and you don't feel able to stick to the sessions
!!A Guide to Editing the Manual
 {{CapturePEN.PNG}}
(a) check that you, the individual responsible for typing, are logged in

(b) check that you are in your teams manual

(c) Create a new page by clicking the plus sign just above the search engine-  give your page a title, write some text and click the tick in the top right hand corner to save your edits.

Go to the [[manuals guide|https://manuals.annafreud.org/guide/]] for details on how to do more complex editing! 

!!Videos showing you how to do the basics:

!!!How to add a new tiddler (page)

<html><iframe width="560" height="315" src="https://www.youtube.com/embed/2jzfArg3RlY" frameborder="0" allowfullscreen></iframe></html>


!!!How to edit & delete tiddlers
<html><iframe width="560" height="315" src="https://www.youtube.com/embed/KxGKCOEu3hk" frameborder="0" allowfullscreen></iframe></html>


!!!How to tag tiddlers
<html><iframe width="560" height="315" src="https://www.youtube.com/embed/_96GxO6Kk5Y" frameborder="0" allowfullscreen></iframe></html>

!!!How to add documents using google drive
<iframe width="560" height="315" src="https://www.youtube.com/embed/L_clqTP3GBg" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

!!Points to consider - 

* Who are we talking about?
* Who do we want to be more connected to?
* Could we host a virtual meet and greet to share what we do and who we are?


!!!How have people been connecting recently?
* Quite a lot of this happens during individual work.
* Jyoti and Chantal have recently developed better relations with social care 
* Rumour recently worked with SENDIAS, and passed on a personal email address rather than a generic one
* Sharing key contacts when we find them out


!!! Ideas for the team - 
* Flow chart of different services 
* Make more of an effort to reach out to these people
* Look at different localities and induction page that gives more info about this 
* EJ to look at Local Offer
* Rolling agenda item about new contacts people have made recently
* Once a month we use our service development section to bring in someone from a different team (start with Sharon Bourla?)
* Invite new team leader of Inclusion Support
* Rotate attending the inclusion support meetings 
* Clarify crossover and differences between us and other services
* Wellbeing practitioners joining more meetings with Jyoti with other services
* How to explain their purpose to a young person (i.e. to see if what we are doing together is helping you)
* How can outcome measures be helpful?

#a measure of progress
#can help keep focused on goals
#can start a conversation about how things are from the young person
#exploring changes (e.g. what's been different that's made this week feel better/worse?)

* What's the most helpful stance to have as a worker about outcome monitoring? (showing enthusiasm)
* Practically, how to integrate into the session (don't give it at the end as a rush)
We identified this as a topic to come back to
Topics that we would hope to cover during an intervention around anger. 

!Understanding anger

* What does anger look like for them?

*Exploring a hot cross bun

* Understanding triggers

* Doing an ABC chart to understand triggers and what responses

*Mapping physical sensations in the body

Setting a goal to work on in relation to anger


! Psychoeducation about anger

* Find age appropriate resources to share with young people

! Intervention ideas

*What could be some alternative ways of expressing anger?

* How to Stop and Pause

* Using a traffic light system to keep track of zones of regulation

* Calming down plans

* Who's in the back up team that can help when they are feeling angry? What can other people to that helps? What is less helpful?

* Challenging negative thoughts 

* Relaxation exercises and techniques

*Anger bingo - anger management strategies bingo game

* Assertive vs. passive vs. aggressive - helping to work out different ways of communication that might be more effective. Could use a see-saw analogy - trying to be in the middle, being assertive, sometimes might be too passive/too aggressive. Could explore what they understand of those terms; use a worksheet to look at; explore incidents; what would a P/A/A response look like

! Monitoring anger throughout the week

* Keeping a diary of incidents to be able to reflect back on together - why did that happen and what could have gone differently?

! What is anger?

* Showing itself externally – displaying very heightened emotions that other people find it hard to know what to do with. 
* Can’t tolerate frustration
* Being impatient
* Snapping at people
* Getting quickly into fight or flight
* Being very reactive
* Getting easily into fights
* Getting very annoyed by little things
* Might notice them being intolerant of other people
* Could make reasoning with them hard
* Not listening, being stuck in their own mindset
* Appearing inflexible
* Swearing
* Hitting, punching, kicking
* Tantrums
* Self-harming – banging head against wall, punching walls
* Shouting at people
* Breaking things
* Insulting people, being rude
* Being disrespectful
* Throwing things
* Damaging physical environment
* Pushing people’s buttons (e.g. trying to get a reaction)
* Being impulsive
* Short-term thinking

! What might make children and young people angry?

* Early trauma – e.g. parent with low mood who finds it difficult to tune into their baby, there might then be a gap in child’s emotional development. Parents are key to helping children learn about their feelings and how to manage them 
* Misattunement – when the parent is not attuned to the child’s needs
* Being misunderstood
* Not getting their own way!
* Disagreeing with people
* Feeling powerless and that they don’t have control over their world
* Not being able to choose things for themselves – e.g. what they wear/eat etc
* Not feeling that they get enough attention
* Mismatch between expectations and reality
* Friendship issues
* School, homework and disagreement with teachers
* Particular lessons
* Can’t go out – e.g. disagreements about the rules
* Sibling rivalry – feeling that they get treated differently

! As you get older, expectations on CYP change...

* Expected to be able to say how you’re feeling
* To have more emotional control over your behaviour
* To have more awareness, to be able to put into words
* Expected to take more responsibility for getting things done
* More choice/freedom (hopefully!) about what you do
* Different things might start to become more difficult – (e.g. friendships in adolescent period)
* People expect you to be more accountable for your actions
* Consequences might be different, according to how far you’ve been perceived to do something outside of what’s expected for your age (e.g. hitting someone at nursery, vs. secondary school)
* ‘Acceptable’ ways to manage anger change as you get older
* Hormones have an impact on emotional state

! Theories of anger 
! Social Learning Theory

People learn from one another; through observation, imitation and modelling

Some questions we might ask:
How do people around you express anger?
How do people around you experience anger?
Have you seen anyone expressing anger in the ways that you’ve just described to me?
What happens when [someone they know] gets angry?
Who’s the most similar to you in  your family in the way they show anger? Who is the most different?

! Positive and Negative Reinforcement
 
Positive reinforcement: giving a motivating/ rewarding response to a behaviour that makes the behaviour more likely to occur
Negative reinforcement: withdrawing an aversive stimulus after a behaviour is exhibited, which makes the behaviour more likely to occur

Some questions we might ask:
* How do other people respond when you are angry?
* What do other people usually do when you do that?
* What does x do?
* How does it make you think/feel when that happens? Did it make you want to stop doing it? Did you get what you were looking for? Would it make you more likely to do that again?

* How do you react when they are angry?
* What do you do when they are angry?
* What do you find has been helpful/unhelpful?
* What you do think the purpose of their behaviour might be?
* What happened before they got angry? What happened after?
* Are there rules? What are the house rules? What happens if the rules get broken?
* Are there consequences? What are they?
* What/are there any rewards for good behaviour? 
* Are there any times when these behaviours don’t happen? What do you do at these times? What do you do/say if they haven’t done it?

How do you feel when they get angry?

! Emotion Regulation

* Self regulation: the ability to manage your emotions and your behaviour in a way that matches the demands of the situation
* Everyone has emotional reactions
* As we develop, we learn to manage these reactions with increasing independence from others; expressing emotion in a way that is proportionate to the situation and inhibiting extreme emotional reactions
* Children learn regulation skills through their interactions with their caregivers - children cannot self-regulate as infants, so they need adults to help them CO-REGULATE
* Did the child have the developmental building blocks to help them learn these skills?

Some questions to ask:

* Have you always acted in this way when you’ve been angry?
* How do you deal with emotions and feelings?
* Do you feel that you react in a similar or different way to others?
* Do you feel able to think about your reactions before they happen?
* How do you express your feelings?
* What situations do you react most strongly to?
* Is it possible to let people know when you feel like you’re going to “react”?
* Do you feel overwhelmed by your emotions?
* Could you tell me about a time when you felt overwhelmed? A time where you felt you were happy with how you managed your feelings?
* Which feelings come up at home/school/with friends? (use feelings cards)
* What do you do when you are feeling x feeling?
* Do you feel like you have the skills to manage?
* Is there anyone you makes you feel angry/happy/sad?
* How does your “family members” deal with anger/feeling scared?
* How do other people respond to you when you’re feeling x?
* Who do you feel helps  you the most when you’re feeling x?
* Do you think there’s anyone who gets it? 
* What does x do when you’re feeling x?
* Has the way that people respond to you changed?
* What is it that you would want people to do? What would be helpful when you’re feeling x?
* If you could imagine being angry, what would be the best scenario for what would happen?
* Creating a character and put it into a story context – what do you think would help this character?

! Emotion regulation - skills-focused approach, i.e. DBT perspective

Emotions are normal and everyone experiences them. Sometimes, particularly when we have had persistent, distressing experiences during our lives, we can emotionally react more often to situations that others may not find distressing, when we feel threatened. The distress can be very intense and it's difficult to manage ourselves and situations when things are feeling so overwhelming.

Learning emotion regulation skills will help us learn to effectively manage and change the way we feel and cope with situations.

* Sensory interventions – helping a young person to self-soothe through attending to their senses (i.e. strategies that appeal to sight, sound, smell, touch, taste)
* Safe space – a place that people can go that feels calming
* Something active – doing things to help channel emotional energy
* Using chain analysis – thinking about an event where anger (strong emotion) has happened. Look at the trigger event, to see if you could track back to see how the event unfolded. Looking at points where it could be possible to intervene at an earlier stage. 
* Skills that help regulation in some way:
Zones of regulation – people helping you to recognise what state you are in. To help a young person understand how they are feeling in that moment, might not have the language/awareness to express and then linking this with a strategy to bring them back to a more regulated state

! Hostile Attribution Bias (Dodge and Crick)

More likely to attribute negative intent to ambiguous/ neutral situations

Some questions we might ask:

* What caused you to react in that way?
* What did you think that person was thinking/meant by doing x?
* What do you think was going through their head?
* What would someone else who was watching have thought about what happened?
* Can you think about any other reasons why the other person might have done that?
* Is that usually the case, that you feel like other people are (i.e. talking about you)?
* Does it remind you of other situations that you’ve been in?
* What do you think you find difficult about this person?
* Difference between banter/joking and what is a dig – how do you tell the difference? Might be quite hard to work it out sometimes. 
* Have you tried asking them what they meant? Is there another way to work out what they were meaning?
* Have you asked anyone else’s perspective on it?
* Asking about previous negative experiences in relationships – to make sense of why they might be expecting things to go the same way. 

! Anger and Mentalisation

The brain science behind mentalizing – it’s a capacity that is located within the pre-frontal cortex, a part of the brain that has most recently developed, in evolutionary terms. For that reason, it is a part of the brain which is quite fragile and prone to being overtaken or drowned out by other parts of the brain when they are activated, namely the part of the brain that deals with threat (known as the amygdala). 

When the threat part of the brain is activated – and gets ready to kick us into fight, flight or freeze, it drowns out the PFC and its functions – which include our mz, our flexibility, our reflection our reason etc. And of course it does this for good reason – this is not a part of the brain that, were we to be using it permanently, would be particularly helpful to our survival!. 
* Set goals and think what they want. Aim cards with older young people.
* Differences between being in the same room than online. Face to face you may absorb more what is going on for him, it brings up different feelings in approaching the work. 
* Different energy when you are meeting the child in person which requires more energy from you, compared when working online.
* Being face to face you are more in the spot. You have to be more prepared, plus added intensity working face to face.
* When we first went face to face to working online, we were worried about how this would develop. It was unknown. 
* Being face to face with people may feel less huge for the children as they are at school seeing everyone face to face.
* with a younger child it is important to keep the balance, how do you broadcast to the child who you are and what are you about? Broadcast intentions to them and their parents.
* Younger kids may not have an idea why they are there. Have someone there that can introduce you to the child.
* How to set up the session with the parent and teacher too? 
* Ask the referrer to explain to the child why they are there. Ask the parent to ask the child what is his understanding of being here.
* One way could be that the first session is a remote session before they meet you in person. It is better for the child to see that your parent knows the practitioner, and it is a useful thing to be doing.
* Referrals are from schools and usually parents point of views are different. Parents have a right to know legally in terms of how the treatment is going and they have the highest impact on the child, therefore they have to be involved. Mapping out different perspectives, like our referral. Being aware of the different point of views and making them explicit. There might be not an easy way for both to agree on this.
* Active planning: balance different perspective and think what is the best way forward? You may get pulled too much on one way than the other. It is between school, family, child and practitioner.

* To a younger child, perhaps start that if they were by themselves, check and make sure they know until what time they are meeting and if they know how to get back to your classroom and where they would go. Try and let them take control of knowing where to go.

* When explaining about your role, keep it simple. Have you ever heard about what psychologists do? One of the things we do is trying to help young people about their feelings, or finding things difficult, we try to be helpful with that. We do that through talking as well with other people.  Ask: Do you know why you are here? 
* Setup of the room: get there a bit early to arrange it. Place two chairs opposite to each other with a table in between or chairs next to each other. It is better to have windows in the room, not door open. 
* People can come to check in during the initial session, this may give a sense of security.

* Explaining confidentiality to a younger child: maybe ask them help what they know about the word ‘confidentiality’. There is stuff that is important to talk about. Use the word ‘private’, what we talk about is private and some things you can talk about your parents and teachers. This may be linked with mapping relationships: Who is important to you and who their roles are. Who would you speak to about something if needed?

* Also setting up a contract: safety of the setting. Decorating their box.

* Kit per child: 2 or 3 games that are interactive, such as uno, jenga and connect 4, snakes and ladders. Pens, paper, stickers and markers. For younger children get toys to act things out. 

* Explain that we will do some talking drawing, playing, and ask ‘how does that sound?’ Let them lead, ask which one would they like to play.


* Explain to the child in case you finish the work abruptly: 'My job is that I go into different schools, but when things get difficult with covid we have to stop going into schools. So I wanted to let you know that this is something that might happen, but I will still see you online.'



* Being able to stop and think and to help understand / take on board other people's perspective / be curious about why other people might be acting the way they do. For example, why is the SENCO appearing anxious? 
* Help improve my capacity to think about others: in my team, networks, young people / children, young people / children networks
* An ongoing learning process 
* Develop a common language as a team
* How to work with other networks

* How to use the spaces that we have in our team in the most effective way
 
* How to communicate most effectively within the team - using the right channels (practically) and making sure we are communicating consistently with each other 
 
* Learning from other members of the team
* Strengthen our relationships with the networks we work with
* Give some skills and ideas about how we might work within networks and how we might approach networks
* Give a shared understanding within the team about how we might approach cases and the work we do
*A shared model of how to approach the work and situations that we may come across in our work.
*A model that we can apply to a diverse group of people and groups (YP, parents, professionals, schools etc.) 
*How we can share and promote this knowledge, rationale and model with other professionals we work with.
*connecting the team - having a shared language.
* Implementation of using the thinking together strategy in supervision and in team meetings.
* Implement in reflective practice space.
* Active structure in supervision to mentalize positions in the network, including young people and ourselves.
* Team around the family or child, keeping in mind the dis-integration grid as a tool to mentalize the different positions in the network.
* Making use of the different perspectives in the referral form.
* Implement the reflective space.
* Individual supervision space and group supervision.
* Holding in mind supporting each other when we are in the 'middle of the pond'.
* How we can create a culture to help and  support each other within our team, utilising and understanding the different roles within the team. 
* Staying connected by maintaining relationships with each other and develop trust. Develop spaces such as a 'tea break' to support each other and catch up. 
* How we can ask for help in bits we don't do as well. 
* Keeping relationships online with people we have not met before in person.
* Having an 'informal' 5-10 minutes at the beginning of the meetings to stay connected and to support our well-being.
* Keeping in mind the practicalities in the different roles and our different backgrounds, feeling more comfortable to share our skills with each other. 
* Share with our team something we recently learnt and/or training courses we have done. Sharing our different experiences in the struggles we feel at work.
* 
* Using the dis-integration grid and sculpting networks, we can bring these tools in supervision to understand what happened in meetings.
* Mentalize positions in the different people in the network to have a different perspective of why your relationship is the way it is.
* Mapping out professionals around the child and who the child can rely on.
* Being clear in an explicit way with other professionals about our role, what we do, and getting a clear understanding of what is their role.
* Keeping in mind what is the role of the whole service. 
* Thinking about different services in Brent and how we connect with them. Also sharing new services in Brent with the rest of the team. 
* 
* Bring in shared language such as 'middle of the pond', 'iceberg', who is at the 'end of the rope' when we discuss cases and with each other in the different spaces we have.
* Keeping in mind the approach of thinking together. 
* Ongoing reflective space and making sure we are using the shared language, we can prompt each other.
* Develop a shared language with clients, not making assumptions. Being more aware of how we can be more transparent about our thinking to the client and family. 
* Notice when we 'bury our heads in the sand' or a 'quick fix' to draw us back.
* Bringing the word 'mentalizing' in discussions, normalize it.
* Our team that values collaborative practice, explaining our values in the right way.
* Sharing ideas of how we are doing the work.
* Manualizing in different spaces. 

! Organisational Induction

* Need to complete AFC induction - check intranet for the checklist

*Brent new starters induction - JP to check with SM

* Mandatory training for AFC (including safeguarding)

*Mandatory training for Brent

* ID and IT equipment

* Training on POD

*Training on how to use the manual

* Training on [[recording systems|Recording systems]]

! Meet key stakeholders

* PF - AFNCCF
* JS - AFNCCF
* SM and JN - Brent
* JP
* Any other relevant partners

! Getting to know Brent

*Travelling around
*Getting to know schools
*Community services
*Local resources

! Induction to clinical work

* Assessment 
* Consultation 
* Goal-setting
* Phone-line
* Record keeping
* GP letters (assessment and discharge?)
* Lone working arrangements
* [[Outcome measures|Outcome measures]]
* Clinical spreadsheet

As needed:

* Intro to CBT
* Intro to positive parenting
* Intro to behavioural approaches
* Risk assessment 
* Safety planning
* Working in a multi-agency context
* Working in schools

! Induction to team working

* Team values and ways of working
* Building and maintaining relationships within the team
* Team meetings
* Referral processes within the team
* Joint working
* Supervision 
* Caseload
! Organisational Induction

* Need to complete AFC induction - check intranet for the checklist

*Brent new starters induction - JP to check with SM

* Mandatory training for AFC (including safeguarding)

*Mandatory training for Brent

* ID and IT equipment

* Training on POD

*Training on how to use the manual

* Training on [[recording systems|Recording systems]]

! Meet key stakeholders

* PF - AFNCCF
* JS - AFNCCF
* SM and JN - Brent
* JP
* Any other relevant partners

! Getting to know Brent

*Travelling around
*Getting to know schools
*Community services
*Local resources

! Induction to clinical work

* EMHP and CYP-IAPT manuals
* Goal-setting
* How to introduce yourself; confidentiality
* Engagement skills and building relationships (including toolkit)
* Assessment skills and process
* Intro to CBT
* Intro to positive parenting
* Intro to behavioural approaches
* Risk assessment 
* Safety planning
* Working in a multi-agency context
* Working in schools
* Record keeping
* GP letters (assessment and discharge?)
* Lone working arrangements
* [[Outcome measures|Outcome Measures]]
* Clinical spreadsheet

! Induction to team working

* Team values and ways of working
* Building and maintaining relationships within the team
* Team meetings
* Referral processes within the team
* Joint working
* Supervision - what is it and how to use it
* Caseload






! What is the purpose of an initial meeting with parents?

*To explain our role and what our team offers help with
*To build a relationship with the parent/s
*To understand what the parent wants help with
*To understand what's difficult and what's working well
*To work out who's already involved (the network) and if there's a role for WEST

! Mentalizing the moment

*How might parents be feeling about an initial meeting?
**Unsure of what to expect
**Relieved that someone might be able to help
**Wanting to offload about the difficulties
**Wanting solutions
**Wanting someone to "fix" the CYP

*What might help?
**Us broadcasting our intentions clearly, in terms of our role, what WEST is and the process of how we will work out together if and how WEST can help
**Explaining the structure of the meeting 
**Our stance - validating, showing empathy, trying to tune in to where the parent is at, trying to understand, checking out our understanding with the parent, being clear about what our next steps will be. 

*How might we be feeling?
**Nervous, anxious - not sure what to expect
**Worried about being asked things/pressured into things we are not sure about
**Under pressure to get all the information we need
**Worried about parents thinking we won't be able to help them, as we don't have children or we look young. 

*What might help?
**Preparing as best we can - on our own, as well as preparing with colleagues
**Practicing anything we need to practice before the session
**Being clear on our session plan!
**Setting an agenda to help structure the meeting
**Being clear about what we can and can't offer
**Being able to name the importance of partnership - the parent knows the child the best; the worker has some ideas that they have learned about things that can help families; together we can work out what fits and what doesn't. 

! ''Areas to explore''

Outlining to the parent that you would like to cover these areas in the initial meeting/s is helpful and asking where they would like to start. Some parents may find it hard to start with what is going well, as problems might be at the forefront. Offer them the choice. 

If there is a specific problem, you ''can'' ask more exploratory questions related to that problem (i.e. that we will have covered in other training sessions e.g. how to explore anger, anxiety, low mood, school difficulties, behaviour problems etc in more detail). 

The responses to these questions can be captured using [[mapping|Mapping]]. 

* What's going well? 
* What's not going so well/ What are the challenges?
* Who else is around in their lives and how do they help?
* What would the parents like help with?

! ''Mapping networks with parents''

See [[mapping networks with parents 
|Mapping networks with parents]]



''Preparation''

*Familiarise self with referral.  What's your understanding of what is being asked for? What is missing that you might like to find out?

''Making contact''

*Introduce self, role, team and reason for contact
*Set up initial meeting - be clear about who needs to be there from school (check in with school if unsure). Are parents/YP going to be included in this initial meeting or is a separate meeting more helpful?

''Planning for session''

*Think about what you would like to find out. 
*Using [[mapping|Mapping]] to gather information is helpful. Maps (i.e. spider diagrams) that are useful can be:
**What are the problems/needs/concerns?
**What is going well?
**What help is being asked for from WEST? What would a good outcome look like?
**Mapping out the existing network around the family, in school and including any other professionals. What's the school's understanding of these people's roles?

''Mentalizing the moment''

*What might initial meetings be like for us as ''workers''?
**unsure about what to expect
**anxious about getting all the information
**being pressured to come up with solutions/quick-fixes
**being asked to provide certainty about what the problem is or what we will offer
**worried about meeting senior people from schools and feeling new to the service, without much experience behind us of doing WEST work. 

*What will help us?
**Sharing how we are feeling in the team - with a peer, colleague or supervisor
**Planning as best we can so that we are prepared. 
**Practicing any mapping/activities/conversations with a peer in advance

*What might initial meetings be like for ''schools''?
**Stressed, frustrated, hopeless, anxious about the situation
**Wanting to know what will be done to help- perhaps they have waited a long time
**Anxious to get everything across to us
**Worried about us "rejecting" the referral, so feeling like they need to persuade us
**Not necessarily able to be in a reflective space because of high emotion
**Relieved that there are people who might be able to help
**Worried about impact of ongoing situation on other pupils and staff - wanting someone to fix the CYP or family. 
**Wanting strategies/solutions straight away because of their desperation
**Feeling that they have already tried everything, so might be mixed about whether interventions need to involve them

*What might help?
**Us remembering to validate the school's feelings. Try to tune in as much as possible to what they might be thinking/feeling (ask if unsure), rather than to assume or make statements which might sound bland. 
**Naming some of the above (if relevant) - acknowledge that many schools are at end of their tether, feeling that they have tried things, that they probably want to get answers about what is going to happen next
**Broadcasting your intentions - we want to help; we want to understand a bit more about the situation first to help us make the best plan; I'll be able to be clearer about next steps when I've heard a bit more from you and spoken to the team. 

''Facilitating the session''

*Be prepared to set an agenda and take a lead, in order to help structure the meeting. Remember the [[active planning|Active Planning]] stance - what is the "plan" for the session and why is this the structure that you will follow. Check this out with the attendees. For example

//"Thank you for inviting me, I'm x from the WEST team and we are meeting about the referral you made about [CYP]. We help CYP and families with wellbeing needs, so the purpose of today is for me to hear a bit more from you about the current situation, to help us make a plan together about next steps, which might include me taking this back to the team to discuss in more detail. I would like to cover 4 main areas; what the problems are; what is going well; who is currently in the network; what help you feel is needed. How does that sound? Would that cover everything you were hoping to? If so, where would you like to start - which order would you like to do those in?"//


''Broadcasting intentions'' is helpful in anticipation of how you will behave during the meeting. Explain that it can be helpful to work through one section at a time. There's a lot to cover, so you'll try to help keep everyone on track, which might mean interrupting occasionally - not to be rude, just to help make sure we cover all the important things. 

''Closing the meeting''

*Summarise what you've understood - check for accuracy
*Thank people for participation and attendance
*Summarise your next steps and when people can expect to hear back from you
!!Child Anxiety:
Cathy Creswell therapist guide based on the [[book|Cathy Creswell's Book for Child Anxiety]] by Cathy Creswell and colleagues. 
''The most recent version'' of the Cathy Creswell's therapist guide 'Helping Your Child with Fears and Worries: A self-help guide for parents Treatment Manual for Therapists'. The therapist manual is free to download, just click the following link and click on the box labelled ‘Request copy from Reading author’ and follow the instructions. 
[[Treatment Manual for Therapists|http://centaur.reading.ac.uk/87041/]]

!!Adolescent Anxiety:
The manual called 'getting to grips with anxiety' by Helen Barker and colleagues 

<<link-doc "Getting to grips with anxiety" "https://drive.google.com/file/d/1CFJ4RymiV2RIlE4qksaUYgGz1DQntLLp/view?usp=sharing">>

!!!Supplement Manuals for Adolescent Anxiety:
 The Kings College London CYP-IAPT teaching team have also developed some excellent manuals ''to be used alongside the 'Getting to Grips with Anxiety' manual'', for more detailed guidance with the specified areas below.

!!!Injection, blood and injury fears supplement:

<<link-doc "Supplement: Injection, blood and injury fears" "https://drive.google.com/file/d/1lo1i82kvpvOkBo3vae4Cp5SfC5-TXENX/view?usp=sharing">>

!!!Managing Panic supplement:

<<link-doc "Supplement: Managing Panic" "https://drive.google.com/file/d/1WiMJb7d_alt10kAXjynrtPraihqVcbGj/view?usp=sharing">>

!!!Managing Worry supplement:

<<link-doc "Supplement: Managing Worry" "https://drive.google.com/file/d/1TctSV_1LM4SldrMqj7O8OrOS1Gte2kWr/view?usp=sharing">>

!!!What to do when our thoughts get in the way supplement:

<<link-doc "Supplement: What to do when our thoughts get in the way" "https://drive.google.com/file/d/1Yzf2FE62B95fdgleePm88HA8GxMTdmjt/view?usp=sharing">>


!!Low Mood:
The manual used to guide practice is the 'Guided Self-Help for Low Mood'. 

 <<link-doc "Guided Self-Help for Low Mood: Full Manual" "https://drive.google.com/file/d/1Ua1L-0BUmNMBTJi2AkYQhdlmnWpKwl0g/view?usp=sharing">>  

!!Behaviour Problems:

The brief guided self-help parenting intervention, the manual for this intervention can be found here:

<<link-doc "Guided self-help for behaviour problems" "https://drive.google.com/file/d/1vBNYY-hZtqIKHZucyZmbxZmfjTvYYoRZ/view?usp=sharing">>

ALL behaviour problems handouts: 

<<link-doc "Behaviour Manual ALL handouts" "https://drive.google.com/file/d/1DdoY9H4Hpvp6nlKIPRSBckbTYpMx5Ld7/view?usp=sharing">>


!!!Related pages:

<<list-links "[tag[Intervention Manuals]]">>
! Introductions exercise

We worked in pairs (with the person we knew the least well so far in the team) and reflected on two questions:

#What do you enjoy the most about working with young people?

#What do you think you are worst at when working with young people?

After each question, we fed back our //partner's// responses to the questions to the group (rather than our own). 

When reflected together on what it had been like to complete this exercise, both in terms of what it had been like to hear someone else feeding back our own perspective and what it had been like to represent someone else's perspective. 

__''How does this relate to our work? Reflections from the exercise''__

* Felt under pressure to make sure we represented the other person's perspective accurately - "wanting to get it right" 
* It wasn't always easy to work out which parts might have been the most important aspects to share - "wanting to make sure I've summarised/picked up on the right bits"
* Noticed that it was easier to answer the first question concisely (focused on a strength/interest) but harder to answer the second, which was problem-focused - 
**found myself wandering into other topics
**harder to express myself as clearly
**became a bit avoidant of focusing on what //I// found hard - moved the conversation to a more general discussion about "what people might find hard about..."
* 
<center>[img[https://lh4.googleusercontent.com/-LsLA8EGpIJ0/URYYBCsRgJI/AAAAAAAAGyY/D4GSq5YI-M4/s512/Stance-Relationship.JPG]]</center>

A central idea underpinning the AMBIT approach is that therapeutic change is achieved through engagement of the client in an ''individual therapeutic relationship''. 

In order for a client to be open to new learning, they will need an experience of feeling understood  ([[Mentalized|Mentalization]]) within this relationship. 

Theory and research tells us that this experience can generate [[Epistemic Trust]] i.e. the kind of trust that is key to "//opening the doors to learning//" from another human being.


We know that mentalizing happens in relationships, and that mentalizing is most likely to happen in contexts where people feel contained, calmer and not overly anxious.

''So, therapeutic change, if it is to occur, is most likely to spring from a trusting, and safe relationship.''  

For this reason much of AMBIT is devoted to how a key-worker can be supported by their colleagues to create and sustain the conditions for that kind of relationship to develop.


In order to support this aim, there are some principles that we apply to individual key-worker relationships. These are adapted in different ways across different AMBIT influenced services, but in general terms they include:

*The team works to reduce the burden on the client of multiple therapeutic relationships all happening at the same time

*We actively search out and prioritising pre-existing relationships which offer the potential to be supportive or helpful


* There is an explicit focus on supporting those workers who are in 'the key-relationship'. How this support happens, and what the key-worker will require to do the face to face client work will vary depending on the context. This principle is known as the team around the worker.

<html><object width="425" height="344"><param name="movie" value="https://youtube.com/v/r4jDfttxClk?hl=en&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="https://youtube.com/v/r4jDfttxClk?hl=en&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></html>

!!Supporting the 'individual key-worker' relationship

 ''AMBIT is not individual therapeutic work, but about using a team to support individual helping relationships.''

So for the worker who is in the position of being 'key' to the client, the workers' energy must be balanced between developing that crucial relationship, and at the same time, ensuring that they are a [[Keyworker well-connected to wider team]]. 

This balance is highlighted by the pair of AMBIT stance points in the outer-ring of 'Working With Your Team'. The stance points highlight the balance between both needing close and trusting individual relationships with a client, for change to happen. But, at the same time it is critical that the worker is ''well connected to their team'' (in order that they can work in this client relationship safely and effectively).

!!How does this relate to the 'Team around the Worker' idea?

The team around the worker model describes how key-workers are very actively supported by a team of colleagues, who can provide ongoing supervision and consultation (as well as other forms of support) to do face to face work. The team of colleagues may have different roles and expertise in different areas. The idea is that they use their skills to support the key-worker to do the work that is needed through the relationship in which epistemic trust is present.

We use the idea of a team around the worker as much as the the more conventional idea of the "Team around a child".

So //from the perspective of the client and others involved, the work is carried out by one main person, but they will also be aware that their key-worker is supported by a team that is experienced as being active and present in the background.//  

[img[https://lh6.googleusercontent.com/-Q--oDenShgU/UcD32HjdpVI/AAAAAAAAIlk/tGuG_Ps4QbE/s512/AMBITSpokes_B%252BW.JPG]]


This models to the client the way that we can all use our relationships to support the work that we do - AMBIT works very hard to avoid the dangerous illusion that any one person, //unsupported//, has the resources to  sustain this work successfully.  



!!So who is the 'key worker'?

Here we use the term 'key worker ', however many services do not use a specific 'key worker' system.

The Key-worker, as we use the term, is less about defining a specific organisational role, but it is more about focusing on //"Who, in the mind of the client, is currently key to finding help that is genuinely helpful?"// i.e. who in the network has the potential or a pre-existing relationship where there is some epistemic trust, and the capacity for learning  __ , __from the perspective__ ''OF THE CLIENT''__

We think explicitly about who is in this position currently i.e. which relationship is 'key' in the clients' mind to getting help ( this may change and may be different to the relationship defined by the organisation as the 'primary' one)

!!We always join a pre-existing network of help

When we begin a new piece of client work, it can be tempting to believe that we have something 'more helpful' to offer the client, and to 'jump in' offering our particular skills. (this is not to say that we don't have something helpful to offer !)

However, in AMBIT we stress that there will already be a pre-existing network of help around the client when we join. There may of course be difficulties or factors that have prompted our involvement with the network. But, in joining there is always the potential to disrupt or undermine pre-existing help further, (hence increasing the burden on a client). 

We believe it is therefore essential to recognise this risk and to place emphasis on considering:


* Where in the network are there  pre-existing relationships that may offer support and learning?
* Who in the clients mind is most helpful within the network ? 
*How might I as the new person position myself to scaffold and  develop relationships that have the potential to be helpful?
*How might I position myself so as not to further overwhelm the clients' capacity to mentalize?


''We use some specific tools to help us with these questions. ''

The AMBIT [[Pro-gram|The AMBIT Pro-Gram]] can be used to map out relationships //with// the client and think about these questions directly with them.

We can also use the
[[ Dis-integration Grid|Dis-integration Grid]] and the [[Sculpt|Sculpting a Network]] as tools to address these question in our teams.













<a class="tc-float-right">[img width= 400 [Who has your rope pic.jpg]]</a>


!!What is it and what are the problems it aims to address?

AMBIT emphasises that for change and learning to happen,  a helping-relationship is needed in which a client has the experience of being understood i.e. accurately [[mentalized|Mentalization]].

However when we are working therapeutically with clients, particularly those who are distressed or risky, this work can (//and should// at times) leave us feeling worried or anxious. So, it is inevitable that as a worker we will sometimes experience high stress and high emotion. 

Theory and research on [[Mentalization]] tells us that
these experiences and feelings will constantly challenge the mentalizing capacity of the worker. However, in order for the worker to accurately mentalize their client, themselves, and encourage the clients' own mentalizing, the worker must be in a state in which they themselves can mentalize.  



AMBIT stresses that the worker cannot regain their balance and mentalizing capacity alone. This is because mentalizing is a ''relational'' ability. It is something that we know develops in relationships, it is lost in relationships, and crucially, it is ''re-gained in relationships''.

So, AMBIT stresses that when working in therapeutic relationships, it is critical that this relationship is balanced with connections to trusted others, in order to restore or sustain the mentalizing of the worker. This is the theory that underpins the ''key worker well-connected to the wider team''.

!!Isolated workers

Within this area of complex practice, there is always a risk that we might un-intentionally become isolated in our work with clients. This brings with it a number of potentially serious problems, including: 

*Burn-out 
*Losing valuable perspectives and not seeing 'the whole picture'
*Becoming less able to plan in helpful ways 
*Losing the capacity to think creatively about our practice
*Not seeing the clients' perspective
*Not spotting or evaluating risks

With this in mind we use a number of analogies to highlight the necessity of strong connections to team members (in mentalizing terms).

<a class="tc-float-right">[img width= 500 [https://lh4.googleusercontent.com/-WHgi7Bo5YOQ/US9d72FvokI/AAAAAAAAHEw/oqk3A0DWRac/s646/DiveBoatAnalogy.jpg]]</a>

Here the dive boat is an analogy to explain that [[Mentalization]] is hard to sustain in high-affect //"pressurised"// environments.  Imagine the KeyWorker were a deep sea diver entering the pressurized and challenging world of the client; other team members (or a supervisor in a more formal sense) should see themselves acting (and we emphasise that these are often //pro-active// actions) as a //''support team''// on the dive boat above, pumping an "air supply" down to their colleague.    In the case of AMBIT, that "air" is the capacity to mentalize.




Another metaphor, the mountaineer, is also frequently used - the worker needs to know some skills about what to do when she is out there, alone, but she also needs to know //who is holding her rope// and to feel confident that communications between her team member are reliable, trustworthy and secure.

!!! What does a '''Key worker well-connected to the wider team''' mean in practice?

We think it will look different in different contexts. However, in an AMBIT influenced team the intention is to make the process of seeking and offering help explicit and part of the 'every day routine' of work. i.e. for the team to become 'practiced' in holding an awarenesss of each others' minds (i.e. mentalizing colleagues). That this is recognised as an essential part of 'what we need to do this work'.

In order to do this we apply [[Mentalizing|Mentalization]] skills - but directed  EXPLICITLY, towards one's colleagues within the team.

NB: this doesn't necessarily mean 'having lots of colleagues around'. It is possible to work in a busy environment and not experience strong helping connections. It is also possible to work without frequent close proximity to colleagues, but still have strong helpful connections to them.

We are also not talking about the nature of friendships or social relationships in the team (although of course this can be important in many other ways). 


!![[Thinking Together]]
In AMBIT we have a tool that is designed specifically to support key-workers connections to their team. It is an explicit routine used to support help-seeking and help-offering between colleagues. It directly applies mentalization and focusses on actively helping the worker to regain their mentalizing capacity through connections with colleagues.

It is called [[Thinking Together]]. It is a set of structured "steps" that offer a deliberately ritualised way to talk about casework, so as to mark the fact that we are attending to mental states at that time - especially that of the worker asking for advice, support, or help.

Our experience is that this tool can be adapted and applied across different contexts to increase the chances that help is well attuned and experienced as 'helpful' for a worker when needed.

!!!How else can we work on our connectedness? 

We encourage teams and services to talk and think together around the process of help seeking within their context. 

For example:



*What kind of help do people need to do their work well?
*What kind of factors influence help seeking in the team?
*How do people already help each other, and what works well in our team? 

We believe that this kind of dialogue is useful in encouraging teams to make more explicit what they do that works well, and continue to develop and practice new ideas in this area.

We encourage teams to [[Manualize|Manualization]] what they do well (and what they intend to do more of), in relation to this important area. 

Video of Liz Cracknell teaching on this for a group of AMBIT Local Facilitators - this video goes on to describe the core activity that we use to help supported the "connectedness" that we are promoting, [[Thinking Together]]:
<html><iframe width="640" height="360" src="//www.youtube.com/embed/0e_kGvCtOEw" frameborder="0" allowfullscreen></iframe></html>


!!!Intervening when colleagues are not asking for help

We believe that another aspect of being 'well connected' is the capacity of team members to offer help or, at times, intervene when when people are not explicitly asking for help or have not recognised a problem. The ability to do this in helpful ways is a central part of team working and managing risk. For example, at times, a worker may notice something concerning in the practice or behaviour of a colleague in the team, which does not appear to have been recognised or acknowledged by them. 

Please see here for theory and a framework around how workers of all levels can introduce challenge and inquiry to each other - regardless of relative seniority, etc.
<a class="tc-float-right">[img width= 300 [books pic 1.jpg]]</a>

!!Introduction


''This page is adapted from the core content of the AMBIT manual ''

Learning at Work is the principle of teams and workers becoming actively engaged in learning from their experiences at work. It is one of the Core Features of AMBIT practice. [[Manualization]] is one of the processes designed to help capture and support ongoing learning within teams. 

AMBIT aims to support teams to learn in more ''explicit ways'' about their practice. We believe strongly that explicit learning in teams fosters crucial evaluation of ''what we do'', and ongoing development of ''how we do things''. Mentalization is closely associated with learning, and the development of new understandings. It emphasises holding an //inquisitive stance// towards our current practice and knowledge (rather than being certain that we know everything we need to know), which enables us to be //open to new learning//.

We believe that a mentalizing team is one which is able to ask itself questions such as..."What are our best shared ideas about how to do this work most effectively?"; "Why do we do this in this way?" "Are there other ways we could do this better?"; "Why do we do it like this and not like that?"

It is this kind of explicit and ongoing evaluation of our experience and practice, that we believe encourages genuine improvement. 

!!A respectful balancing act
Learning at work requires a balancing between two elements of the AMBIT stance - Respect for EVIDENCE, and Respect for LOCAL PRACTICE & EXPERTISE:

|! |!Respect for Evidence|!Respect local practice and expertise|
|''What is it?'' |Published trials or meta-analyses, routine outcome monitoring and evaluations, service-user feedback and testimonies, etc |Respect for //existing// competencies & knowledge within team & across other agencies in the network that are attuned to local culture & service ecology |
|''Risk of Overemphasis'' |Teams that do "one size fits all" because they are rigidly applying evidence-based interventions, rather than practicing with attunement to the client and insufficient adaptation to the local service ecology |Team/worker that "makes it up as we go along", over-reliance on own preferred methods/ways of doing things (in the absence of evidence for these) |
<<list-links "[tag[Local Practice]]">>
List of pages about working with looked after children (LAC)

<<list-links "[tag[Looked after children]]">>
The list below are all the pages we have tagged with 'Managing Anger'. All of these pages are linked as they contain information and resources on how we as a team work to support children and young people to manage their anger. The theme of these pages is closely linked to working with behaviour problems. 
<<list-links "[tag[Managing Anger]]">>
!!What do we mean by Risk? 


#Risks for the client e.g. self injury, abuse, health problems...etc
#Risk for other people e.g. criminal acts, harm to pregnancy, violence...etc
#Risks for the worker e.g. burn-out, trauma, complaints, allegations etc


Managing Risk is one of the [[CORE features of AMBIT|Core Features of AMBIT]] and part of ''Working with your Client''.

!!Managing Risk, not Abolishing it

It is important to acknowledge that in this field we can never get rid of all risk. Working with impulsive clients, who have limited ability to plan, predict risk, and consider the consequences of actions, will always hold risks.  

!!Risk and Mentalizing - an Assumption: 

AMBIT takes the position that working with risk is (and should be at times) anxiety provoking and worrying (for all involved). We know that high levels of emotion impact on [[Mentalization]]. Therefore a key part of managing risk involves finding ways to regain and sustain mentalizing in these contexts.

Risk is highest at those times when [[Mentalization]] fails in:

#The client/family
#The worker
#The people (networks) around the client or worker

When any of these people lose the capacity to mentalize, it becomes harder to evaluate and respond to risk in thoughtful and effective ways.

At these times it is more likely that non-mentalizing interactions happen between people. For example Teleological thinking (i.e. 'quick fix'), often arises. Examples of this might be a violent act or using an intervention which has not been well planned or thought through. These kind of 'un-mentalized actions' can  often lead to further unwanted effects - such as more relationship problems, increased vulnerability, side effects from medical interventions, increased dis-integration in a network etc


''With this in mind, we see managing risk as a process which relies heavily on the connections between colleagues and capacity of workers to support each other to think (or to mentalize) in conditions where risk (and hence, worry) is present.''

__Situations in which workers are  attempting to manage risk without strong connections to colleagues would be highly concerning and, we believe, un-sustainable.__

The way in which the keyworker and team work to re-gain their balance and the ability to mentalize, through their ''connections with colleagues'', is therefore essential in order to carry out this work effectively.

 
Please see here for more explanation of this, particularly the notion of a [[key worker-well connected to the wider team |Keyworker well-connected to wider team]] 

 


!!Managing Risk and the AMBIT stance features

Managing Risk is one half of two 'AMBIT stance points' (shown in the outer rim of the wheel in the [[Working with Your Client]] quadrant of AMBIT). The other half, is called [[Scaffolding Existing Relationships]]. We see the worker (and teams') role as attempting to hold a balance between these 2 points below. 

{{Wheel with client highlighted.jpg}}

''Scaffolding relationships'' involves the essential work with clients in which we aim to help them build , strengthen and make use of relationships which are ''already present'' and which may serve an important (longer- term) role in their lives (long after we have gone!). This includes work with the clients' relationship with themselves (i.e. the capacity to mentalize themselves), as well as relationships with family, friends, the social world, employment and others with whom there is potential for ongoing support. Here the worker uses engagement, attunement, and builds understanding of the client and their network.

On the other side of this balance (sometimes in opposition, and pulling in the other direction) is ''Managing Risk''. At times within the work with clients and their networks risks will be present. When a risk is identified there is often a need for some kind of concrete action in order to better understand and reduce risk.

In many ways managing risk can be seen as a helpful use of ''teleological thinking''. There are actions, procedures and protocols that will be required in order to sufficiently reduce the risk (for example, with the disclosure of active abuse, the appropriate response will be clear, timely and decisive action in order to safeguard somebody).  However, although clear actions are often essential, when these happen without mentalizing, there is a high risk that the relationships that the worker has been carefully scaffolding can be damaged (which in the longer-term, if the client or others dis-engage, can lead to greater risks). 

This is the nature of the balance between these 2 stance features- both sides are critical and the worker attempts to balance between the stance points. 

''Mentalizing supports the worker to hold this balance''

!!An example:
A worker has built a strong relationship with a parent and has begun to help the parent learn to manage some of their difficult experiences and strengthen some potentially supportive relationships in their life ''(scaffolding relationships)''. The worker then learns that a member of the network close to the parent and their child has a history of posing serious risks towards young people. At this point the worker is required to take clear steps to make sure that the well-being of the young person (and others) is appropriately safeguarded ''(managing risk)''.
 
Applying mentalizing to this situation might look something like the worker (supported by colleagues) to think through and plan points such as... 

> //What might be the safest way to carry out these safeguarding steps? Who should we talk to first and how should we do it? who best to have these conversations? how might different people in the network experience this and respond? what does this tell us about how we should position ourselves to be most helpful and work safely? What steps can we take to try to limit any harm to protective relationships that have been built ? etc// 

If we move in to action without this kind of thinking (mentalizing those involved) it is much more likely that relationships will be ruptured and it may become more difficult to manage these risks in the future.

!!Assessing and Managing Risk


It is critical that teams have clear ways of assessing risks and have shared explicit protocols for making plans to manage risks e.g. crisis contingency plans. These should be discussed regularly in the team. 

AMBIT does not claim any originality in promoting this. However AMBIT does emphasise the need to develop and adapt these protocols and procedures in relation to new learning within teams' local contexts. We believe that teams making explicit, regularly rehearsing and adapting their approach to risks, in light of new experience, is essential here. We encourage teams to use [[Manualization]] as a tool for learning, recording and sharing their own protocols around risk.  


!!Extended learning - <<tag [[Extended learning]]>>

Different teams will have different protocols and procedures around risk. below we have included some more general guidelines. Within the extended learning tag you can also find further reading around the process of challenge and support in managing risk.






''__Mentalizing our own feelings about ending __''

*sense of avoidance
*a sense of things feeling unfinished 
*feel quite sad
*Frustrating if you have not achieved what you might have hoped 
*thoughts that we may have disappointed 
*feeling guilty 
*feeling you are leaving them 
*feeling you have to take on all the responsibility for them feeling good
*anxiety about their future 
*hopeful/hopeless about their future
*proud of the work you have done and of them 
*relief which might then make us feel guilt
*satisfaction 
*failure (if we feel we haven't done a good job or that the client wishes to no longer continue)

We may be more inclined to feel certain ones due to our own experiences or the way that the work has been conducted/ the reasons and way is ending.
We cant take for granted how if might feel to end work as each ending will be different. need to acknowledge these feelings and communicate it to our team so they can support us,

''__Mentalizing our clients__''

* abandoning them
* leaving for other children 
* feel the same types of feelings we might feel 
*they might be feeling differently to how we feel about the ending. 

''__What can we do to consider the states of mind during an ending__''


*need to consider the separateness of the clients mind, and keep curious. - we might feel anxious they might feel angry
* ask self how am i feeling about this ending have a space with a colleague to unpick this
* ask the client explicitly how they are feeling.
* Unpick how the client is feeling about this 
* need to balance sharing own feelings about ending in a containing way without over-tipping the balance to just talking about yourself.
*be real with each other about how you both feel about the ending 

''__What can we practically do?__''

* Talk to the client and family about endings before it happens
*preparation is key
*might need to have a few sessions which is focused on ending
* try to be explicit
*be clear about what you would like to achieve in the work before you end. 
*be clear about what you might work towards to achieve a good ending:
** sustainability plan
**relapse plan
**safety plan
**what have you learnt? what would you like to continue working towards?
**what could you share with others? - could you make a document together so you can share it with others in your network
**unpick ways that they can share the work with the backup team. how could we share this? what could you say?
**bringing back in the back up team and how the client will continue to be supported  
**Review the goals - what is there left to do? what else would you like to do? where would you like to get to?
**reminiscing about work 
**reflect of big future goals 
**like a mechanic- its ok it all of this work doesn't stick and you might need some maintenance later on down the line.
*ending sessions may take a few weeks
*how could we accurately sum up the story of the piece of work? - might not have had as much chance to practice things because of x,y,z but we could still make a plan of what you can do going forward (might be a summary of what we have done that helped or about what do we need to scaffold to support for the future.)

''__Troubleshooting__''

*we may not know when the ending is due to the current change in working- this can cause us uncertainty and the client.
**we could make sure we are clear about this in supervision.
*endings might be hard for many reasons such as: client needing more support, client not having a supportive back up team, client not being ready for the end.
*goals may not have been met as they were school based and have not be achievable during the current climate.
**create a realistic picture of the work that you have done together, acknowledge the goals that are still outstanding and plan what can be done to support this process.
*might be hard as you may only have just feel like you have been beginning to know each other or get down to the issues 
*might be hard as you might be the 'only one they have to talk to' 
** need to consider who else can check in, might have others who could that they are overlooking. really important they have found this helpful so its important that we find someone else who can do that. - could consider mapping networks
''Assessment Session''

__''Getting started / Broadcasting intentions''__

*Set boundaries in order to contain the conversation and make it secure
*So it would be great to talk about x, y and z
*Where would you like to start?
*Would be good to hear from everyone, and I'll do my best to make sure I do
*I might interrupt a bit, not to be rude, but just to make sure I’m getting what you’re telling me
*I want to just make sure I’m doing a good job of hearing from everyone, so I might interrupt a bit or bring in other people
*Who wants to start?

__''Getting multiple perspectives''__

*So I’ve heard from……what do other people think?
*Does anyone else have a different view?
*Do people see that in the same way or in a different way?
*What do you think about what your Mum/Dad/sister is saying?
*Is that how it seems for you too? Or is it different from your point of view?
*Is your Mum/Dad/family member right about that? Did they miss anything out? Is there anything you’d add to it?
*X, are you ok just listening or is there something that you want to add?
*X, I know you’ve been a bit quieter, how are you doing? Is this ok for you? I don’t mind if you just want to be a bit quieter, but don’t want to leave you out either. 
*Look out for situational cues on how agreeable or not everyone is

__''Managing multiple perspectives''__

*People usually have different views and that’s ok – let’s just try and work out how everyone sees it
*You don’t have to tell me everything today, you’re just getting to know me
*This might be an easier conversation to have just with x, rather than everyone together
*It not about necessarily agreeing on one view of it for now, its just helpful for hear how different people see it
*So this is something you’ve all got quite different ideas about – you think this; while for you, its more like that
*Useful to hear how different people see it

''__Moving the topic on__''

*So I’ve heard a lot about…..what isn’t working; why it started; your ideas about what’s going on, but I was also wondering about
*That’s really helpful, so I’ve got a bit of an idea about x now, so could we move on to...
*Name the processes for them

''__Managing too many people talking at once__''

*Sorry I’m just going to interrupt as I don’t want to lose track of what people are saying! Let me just try and see if I’ve got it. Let me summarise. 
*I can see you’re desperate to say something, I’ll come to you in a second – let me just finishing hearing from x
*Sorry I’ll have to slow you down a bit because I can’t keep up! So you were saying this; but then you were saying……?
*Can I just stop you for a second?
 
''__Managing conflict / raised emotions__''

*Is this usually how things get when you talk about this kind of stuff?
*It looks quite tricky/it kind of takes you into a bit of a disagreement/it gets a bit heated/you’re both trying to get your point of view across and feel like the other one’s not getting it?
*I obviously want to see a bit of how it is, but I don’t want it to feel like an unhelpful conversation either or let things get too heated/full on for today 
*Shall we rewind a bit? Can I try to summarise? You think x, you think y – is that right?
*I’ll just try to help us keep on track if I can…


!!!What might make the transition hard? 
!!!What may be some of the issues that CYP could face at the moment?

We discussed possible barriers or factors that may need to be considered that might influence the transition back

*Making the transition to a different school, 

*Having new rules about Covid19
*Adapting to new routines re COVID, 
*Worries around Covid19 and safety
*Loss and bereavement
 *Difficulties separating from family re anxiety, closeness over lockdown, above worries
*Feeling behind in terms of academic work and feeling pressure to catch up
*Reconnecting with peers,
 *Additional pressures for children with ASD, 
* Children where higher risk to get excluded due to not following the Covid19 rules e.g. behaviour problems become amplified if harder to 'sit and follow rules',
*Parents' anxiety about health and school staff anxiety about how to plan the day while keeping the children safe

!!!We thought about how anxiety around the transition might show itself in CYP at different developmental stages

*Withdrawn and timid being around others 
*An increase in challenging behaviours, testing boundaries, 
*clinging to teachers needing proximity, separation anxiety with parents, the night before getting many worries about what is bad about school, 
*school refusal, 
*struggling to fall asleep the night before worrying about the next day,
  *Feeling unwell unable to attend, physical symptoms such as headaches, stomach aches and dizyness, unable to eat, 
*Friendship problems such as struggling to re-integrate into groups or pushing people away, resorting to social media and not physically connected to other children (quite withdrawn), sense of uncertainty and being on edge. 
* When we try to share our understanding of behaviour of a child to a teacher: first, mentalize how is it like for them to be in the teacher's situation, have a sense of that such as so many guidelines they need to follow and feel stressed. September is overall a very stressful month where everything starts again, planning out everything, getting to know new class, etc.

* Research and evidence around the transition back to school (see Anna Freud Centre EBPU research bites )

Key points to consider: 

* Being able to identify and have an idea of the young people who already are struggling with difficulties, they might be at risk. For example children with additional needs, children with pre-existing MH problems and who are already at social disadvantage
 *Think about planning early particularly for these groups re what they might need to help support the transition (before they come in)
* Encourage schools to prioritise well being rather than only academic work: children need to be in a calm state to learn and do their work. Sometimes it can be difficult for parents and teachers to understand this as there are many external pressures to crack on with things.

* How the brain works - Links between the need for stability, calmness, well being-connections with adults- these are basis for learning. Could draw on theory about mentalizing and pre-frontal cortex to help explain

* The importance of recognising the well being of teachers is crucial too.

!!! We thought about how as EW's we might be able to play a helpful role

*First trying to understand the individual factors and context. 
*Mentalizing the CYP and parents
*Can parents and teachers mentalize the child- what are their hypothesis and guesses of what may be going on for the child in transition? how might this guide what we do to support them? how can we find out of we are on the right track?

* Thinking together with the child-Getting to know them first, understanding more about what is going well too to start with e.g. their interests then explore what are their worries?

What are some of the ideas and tools we have to help explore worries and anxiety with younger children?

* Using different characters in a story to help play out situations to understand a CYP worries, expectations, ideas - using creative ways to bring characters to life...playing out 'transitions' stories...askig about what they think might happen, who would do/say what, how might the characters feel, what might help them in the story?  Finding a creative way to explore it by linking it to what they are interested in. How we connect it to characters in Stars Wars for example? This could also detach a bit the problem from them, starting by being emotionally more distant and slowly figuring out a way to talk about them. 
Story stems: You can start the story about the 'ninja who is starting to go to school this morning' and ask 'what do you think that happens next? What are they feeling?'
Using metaphors and scenarios that are slightly distanced from them which allows them to think about things.
*Making up vignettes about what the person would do if they were in that situation, the person not being them

* Keeping things visual by doing sentence completion: 'One thing I like best about school is: x'
'The thing most scary about going back to school: x' and 'What i like most in my school:x'

* How can we help? (Case example)
Research evidence says that having exposure and practice of going back to school should be a key part of the plan- rather than just talking about it. 

i.e. It may not be enough to just talk about worries, but actually going to the school taking some steps there is key in the intervention (Not just in context of covid)

But to help with this exposure and steps back we need a plan !
* Graded steps back or faster move to re-integration?

P!!!Points to consider in planning
 
* What to do when things get difficult at school? Have a structured plan of this before going in
* Relationship Mapping who is important at school. How can we use their help?
*where might you go if it gets hard (a safe place in school?)
* Who will be the adult that meets the CYP on arrival if this is needed
* A child with social anxiety: Go before starting school to meet teachers. Also arranging with friends to meet before class starts.
*What info needs to be shared with staff and who with?
*Identified place to go if needed in school
*Do we need check in times with trusted adult?
* Mentalizing the staff first and then helping staff mentalizing the young person - sharing your understanding of the young person with staff- but first need to mentalize staff!

Staying in contact with CYP when the therapy sessions have to stop for a while e.g. during transition back to school and when therapy times have to be changed 

What could we do in this situation?

*Message to CYP to show we have them in mind and tell them as much as we can about when sessions will start again, what our plan is, that they will not be lost

* Talk to parents and share ideas/plan, such as by sending emails or text messages or brief letters of what is happening at the moment
* Calling a parent to check how it has been going, ask to speak to CYP to update them and check in. Ask parent to let the child know you have called
Note: mentalizing how it might be like for you going back which can feel quite stressful, although it is hard to talk now the sessions are still there, for example 'I will be talking with your mum to see how to work best with you when things settle down'






[img width=100% [patrick-tomasso-Oaqk7qqNh_c-unsplash.jpg]]

!!''What is Manualization?''
'Manualization' is the process of recording what we do (in text or through video recording) in ways that would help others to do the same thing (and get the same results.) It is really another way of addressing the idea of ''team learning'' - and in this way it relates to ideas about developing learning organisations by Peter Senge.


Manualization is one of the [[Core Features of AMBIT]] - AMBIT workers don't just read their treatment manual, they are expected to //co-author// it.  

Above all, Manualization is about promoting [[Learning at Work]] - particularly ''learning from mistakes'', or ''recognising a piece of local expertise''.  Recording it (especially so in a public facing website) creates a kind of ''"ratchet effect"'' so that learning in a team is less likely to slip backwards and get lost (//because workers forget those team discussions when 'all came clear', or they leave the team to take up other posts, taking all their expertise with them... //).

!!! Using Wiki-Manualization in an AMBIT Team

<center><iframe width="640" height="360" src="//www.youtube.com/embed/tcE8k8REnzY" frameborder="0" allowfullscreen></iframe></center>

!!! Building a [[Community of Practice]] using the Wiki-Manuals
<center><html><object width="480" height="360"><param name="movie" value="https://youtube.com/v/wT-3b227ZXE?hl=en_GB&amp;version=3"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="https://youtube.com/v/wT-3b227ZXE?hl=en_GB&amp;version=3" type="application/x-shockwave-flash" width="480" height="360" allowscriptaccess="always" allowfullscreen="true"></embed></object></html></center>

!!Balancing Act
What you are reading now is a Wiki Manual, which is a different kind of manual from books or conventional websites.  In keeping with two other [[Core Features of AMBIT]] ([[Respect for Evidence]] and to [[Respect Local Practice and Expertise]]) it is concerned with the difficult (but as we see it, crucial) task of balancing two potentially contradictory principles: 

* ''Systematic Evidence-based Practice''
*''Locally-derived Practitioner-based Expertise''


...The approach to "manualizing" practice in a Wiki Manual allows for a marriage of 'top-down' evidence-based information and instruction, alongside 'bottom up' local expertise in ''//how we apply these techniques and methods here, with these particular young people...//'' or ''//what we learned from a recent near miss/mess/serious incident that would minimise the likelihood of this happening again//''. 

!!''How to do it? ''
You will experience manualizing as part of your AMBIT training, one person will act as the 'scribe' recording the discussion and another person will act as the 'chair', making sure the team stays on topic. Below are some guidelines to getting started:

#Allocate some time in a team meeting for manualizing (some teams do this once a week, others once a month)
#Allocate two key roles: a chair & a scribe
#Make sure you are logged into your Manual
#Start by creating a list of topics that you as a team could manualize- a good place to start might be things that you as a team do well or topics which are live issues for you as a team
#Choose a topic to manualize first
#Break the topic down into smaller sections using the 'Slice & Dice Method'- ordering the sub headings before you begin
#You might discuss how individuals in the team have experienced this topic or why it has been chosen- you should then use an [[Active Planning]] approach whereby you make a plan about where you, as a team, want to get to, whilst recognising that things may change in the course of trying the agreed approach. 
#You might revisit a topic if you do not complete it in one session - this is fine!!
#You might also revisit a topic if something hasn't worked or the situation has changed.


----
!!''Benefits of Manualization?''
There are a number of key benefits to having teams engage in manualizing their own practice:

!!!(a) Promoting Service Development

#Engaging in continual, small, iterative and incremental "tweaks" and changes to ensure that there is [[Learning at Work]] 

!!!(b) Fostering a distinct LOCAL team culture
#A local team develops "our own unique manual" that is: 
##//"Bespoke"// to our own local needs - attuned to the local population and geographical constraints (transport, culture, common clinical problems, etc) 
##A record of the ongoing [[Mentalization]] efforts (the [[Learning at Work]]) of our team, //about our team// as a whole (why we behave in the ways we do)
##A powerful tool for inducting new team members
#We sustain a practice that is both //integrative// and //multimodal//, according to our [[Core Features of AMBIT]].
#It is hoped that the implicit sense that this method of working constantly tries to [[Respect Local Practice and Expertise]] will also support positive team morale.
!!!(c) Comparing and sharing our work with other teams
In AMBIT there are already multiple teams beginning to adapt their own local versions, which you can see from the dropdown list on the manuals signposting page (manuals.anafreud.org). 

* An explanation of how the manual supports the development of AMBIT as a [[Community of Practice]]
* The ability to see what other teams have been writing about is a function that is still in development. You can, however, openly look in other teams manuals- an easy way to see what they have written is to click on the 'Recent Changes' tab (below the search engine) and then click 'Local'. Additionally, you can ask one of the ambit project team to point you towards other teams who manualize!  

!!!(d) Research 
There is as yet little research into the use of wikis in learning organisations, but a helpful paper exists for those who are interested: Cole, M (2009) Using Wiki technology to support student engagement: Lessons from the trenches

----

<center><<image-link "How to edit your teams manual" "luciano-de-sa-ObwMZBdEWdI-unsplash (1).jpg" "How to edit your teams manual" "250">>

Here are some topics that we would like to write some pages about:

[[How to use outcome measures in a collaborative way]]

[[How to work with young people who might feel ambivalent about including their network in the work|How to work with young people who might feel ambivalent about their network being included in the work]]

[[Exploring and understanding families' cultures]]

[[What's the best approach to planning our work?|Planning our work]]

Boundaries in our work

Using agendas

OARS - motivational interviewing skills
!What is Mapping?

<<list-links "[tag[Mapping]]">> 


Mapping is a visual tool that can help us to gather, record and reflect on information that we are gathering from a person in a session. 

A map is a spider diagram. In the centre of the diagram is the thing we are trying to understand. Round the edge, we gather the different points/ideas that relate to this.

We draw them out as we are talking to people. We can show them the map or refer to the map and summarise what is written on there, if we are not together or they can't read it (e.g. language/literacry barriers)

!What kinds of things might we map?

Mapping is a tool that can be used at any stage of our work. 

!!Assessment stage - gathering information

*What are the problems/needs?
*What are the strengths?
*What is going well?
*Who is in the network? What are their roles?
*What are your desired outcomes? What help would you like?
*What does "helpful help" look like to you? What does "unhelpful help" look like to you?

!!Formulation - developing understanding

*What does [the problem] look like when it is happening?
*What do we know about what triggers [the problem]?
*What makes it better; what makes it worse?

*What do we know about *Why might x be happening? e.g. 
**What might be making this YP feel angry? 
**What is making it difficult to listen in class? **What is driving low mood? What's making you feel low?
**What might [x person] be thinking? What might be going on for them?

!!Developing interventions

*What has already been tried in the past?
*What seems to help at the moment?
*What makes it worse that we could avoid?
*What are your ideas about what could be tried? 
*What could you do? What could other people do?
*If we were going to try [new approach/strategy], what would that look like?

!! Reviewing progress

*What's gone well this week?
*What improvements have you noticed towards [goal?]
* What have you/others been doing that's helped?
*What barriers came up when you tried to do [task]?
*What got in the way of you trying [task]?
*What else would you still like to work on in relation to [goal?]

!! Planning endings

*What's helped about the work we have done together?
*What progress have we made towards each goal?
*What needs to continue to maintain the progress?
*What barriers might come up? How could we overcome them?
*Who else can help to keep the progress going?

! How can maps help?

Maps help us to be thorough when we are gathering information. A map is a way of reflecting that there are lots of different ideas that might be relevant to a particular question, whatever that might be. 

The process of jotting down notes in this way as we go is very visual and easy to read. It can help us to organise and keep track of the information we are gathering, without having to write in prose or long notes (or not at all!)

It helps with the pacing, as we can invite the other person to slow down to help us keep up with what they are saying. This can help them and us to move into a more reflective stance.

It helps us with reflecting back and summarising, which helps us to check out with the person whether we are understanding them accurately. Doing this frequently will help to build and strengthen the relationship. 

We can draw out the maps we want to do in advance, to help remind us of the structure of the session. It can also help to prompt us (and the other person) to notice if the conversation is becoming unbalanced, i.e. if we are mainly focusing/being focused in on one particular area. 

For example, sometimes we might notice that someone is very detailed with regards to problems and finding it harder to focus on strengths etc. Perhaps they are wanting to tell us what help is needed, without helping us to understand what the problem is. Mapping can help us build a picture of this more clearly and give us ways of bringing these reflections into the conversation we are having, both to validate the person's experience:

//"I'm just looking at our maps - you're feeling that there's a lot that's not working here; it's hard to see past all these needs; this sounds very tough going - things are hard in lots of areas"//

as well as to hold the balance in the conversations 

//"We've talked a lot about the difficulties; would it be ok to hear a bit about the strengths? I know they might feel harder to reflect on when there's so much going on, but shall we see where we can get to with that?"//


! What is a network map?

A network map is a drawing, using concentric circles. The parent/YP are in the innermost circle. Invite parents to tell you about the other people they have in their life and plot these in the outer circles, according to how near/far the parent feels this person is to them. 

! Why use a network map?

It's helpful to explore a parents' network with them. This is because we want to design sustainable forms of help, through [[scaffolding existing relationships. |Scaffolding Existing Relationships]]. This is an AMBIT principle which reminds us of the importance of using the relationships that already exist in a family's life to support them with the changes that they want to see. There may already been things that people around the family are doing to help. Understanding what these things are or drawing a parent's attention to this may be useful, so that these resources can be made use of in the intervention. It is not always the case that a new professional is needed to meet every need that is identified. 

!!Introducing the map

Explain to the parent that it would be helpful for you to get a picture of who else is around and important in their life. It might be that some of these people already help in some way or could help with the things that are difficult. Genograms (family tree) can also be used for this, but they tend to privilege the exploration of family relationships. A network map can include anyone, regardless of the type of connection. 

It is important to be mindful that some parents might not be feeling isolated. Do not make assumptions about people having partners, being in contact with extended family, having friends etc. Try to follow the parents lead by asking open questions such as "Who do you have around you?" and suggesting some categories, rather than specific people ("e.g. What about your parents?")

!! Who might feature on a parent's map?

* Their parents
* Their siblings
* Any other professionals
* Friends of theirs
* Friends with children of a similar age
* School professionals
* Aunts, Uncles, etc
* Their own workers (e.g. therapist)
* GP
* Community groups/supports
* Religious groups
* Neighbours
* Colleagues

!! Questions to explore:

* Where would you place this person on your map? How close or far away?
* What kind of things do you do with this person?
* How does this person help already?
*Is there anything this person could help with?
* Is there anyone from this map that you'd like to include in our work? 

!! Using the network map in the work

The network map can be referred back to in subsequent sessions, as a way of thinking about how the network could be included. For example:

*Who could you ask for some ideas about x?
* Who could you talk to about y?
*Who from your network map could help?
* Who would notice this had got better?
* Do you think anyone from this map would have any ideas about why z might be happening?
!!What is it?
This is the first step in a four-step 'ritual' called [[Thinking Together]] that is designed to help improve the quality of //communication about our work//, and thus to improve the //quality// of that work. 

It is the "short-term" version of one of the [[Core Features of AMBIT]] practice, which is [[Active Planning]].  

!!Why do it?
Most clinical discussions (we argue) start with [[Stating the Case]] and move straight into generating solutions ([[Return to Purpose]] in our language) - missing out two key elements (''Marking the Task'' and ''Mentalizing the Moment'').  Investing some time in developing a plan - either for something as 'simple' as a conversation with my team-mate, or for something as complex as trying to help a young person, is associated with better outcomes than relying on chance, 'inspiration', or intuition on the part of the helper in determining what would really be helpful to her colleague. 

More than this, Marking the Task involves a deliberate attempt to ''//kick start mentalizing in the worker//'' who is asking for help - emphasising that //in these conversations we ritually insist on mentalized explanations for behaviours - our own, as much as our clients'//.
!!Using chat usefully
As practitioners, we all talk about our clients in all kinds of ways and in all kinds of places.  Stories are often what draws us into this work, and this is both a positive and potentially a negative, as we can get lost in the stories, especially if they are very compelling or anxiety provoking.

Marking the task is about making the best use of these conversations - that are generally happening anyway.  

There is a risk that one practitioner's capacity to mentalize about what his or her colleague is //actually requesting// may not always be accurate.  One team member may be keen to "pass the time of day" whilst the other is actually requesting a very serious discussion about important clinical material.  

!!!KICK-STARTING MENTALIZING

As mentioned above, in insisting that my colleague stops and asks //their self// ([[mentalizes|Mentalization]] their self):<br><br> //''Why am I coming for help? What do I want out of this "help"? How would I know that I had been helped?''//<br><br>we are ''setting the tone'' in a conversation that insists quite explicitly on mentalized explanations by all participants.  By insisting that our colleague does not rush headlong into [[Stating the Case]] we invite them into a mentalizing frame of mind - ''//"Help me understand what you think you need out of this conversation"//''

!!What is "Marking"?
We draw on the theory of Marked mirroring]] and Ostensive communication, that explains how mentalization develops through infancy, and which is also a helpful technique that practitioners can use in working with clients who are in distress.  In "Marking" the KeyWorker takes responsibility for the clarity of his of her communication, and minimises the likelihood of misunderstanding about what is being asked for.

By explicitly MARKING a discussion we mean saying something that //explicitly// marks out what you want out of this conversation - that it is NOT just "passing the time of day" (although one could mark out that as the task, just as easily!): 

>"I want to talk about THIS client, in THIS particular way, for THIS amount of time..."  

A core team task in AMBIT is to foster and sustain [[Mentalizing|Mentalization]] in team members. By using language very explicitly in this way this function is supported.

!!''How to do it''
These are simple steps, and the key is for team members to find their way into using these as one of the rituals and disciplines that define the team's culture.

!!!''1. Ritualised language''
Some shared "marker" that all team members will recognise is required.  We have called these disciplines "[[Thinking Together]]", or "Passed-outwards Discussions", and any of these phrases might be enough to signal that a very specific kind of communicating is being requested right here, right now.  Teams may wish to agree in their //own// rituals to mark the introduction of this disciplined way of communicating - a simple form of words that carry a shared meaning as part of the team culture.  What is important is that these Rituals are EXPLICITLY agreed, rather than IMPLICITLY //assumed// to be in place.

!!!''2. Set boundaries''
Agree ''how long we both have'', and ''what is the outcome we want''.  This has been described as "turning the conversation upside down" and starting by defining what the ending might look like. The KeyWorker requesting this should have in mind:

>//"what would a satisfactory outcome of this discussion look like?"//

Is there a key issue that needs a decision? 
Is there an area of confusion that needs a better framework for understanding it?  
Is there a crisis that needs an emergency management plan to ensure safety for the next few hours?
Is there a wish for some "ventilation" of feelings?
Is the task... to work out what the task is?
Etc...

!!!''3. A contract''
By agreeing to take part in a ''Marked'' discussion of this particular type, the colleague is effectively "contracting" to maintain the boundaries in the next steps - to //keep the staff member on task// and to help keep to these particular boundaries.
Mentalization is one of the [[Core Features of AMBIT]] and underpins the AMBIT approach. This page describes Mentalization in general and ''Mentalization in AMBIT''. 

!!''What is Mentalization ?''

''Mentalization is...''

>>//'The imaginative activity of making sense of the actions of oneself and others on the basis of intentional mental states such as desires feelings and beliefs'//


>>//'So, mentalizing is what we do when we are imagining what might be going on in the mind of someone,  //underneath// the behaviour that we see on the outside'// 


''We can mentalize ourselves...''
"Why do I keep getting into this same fix?..what am I thinking or feeling that means I keep ending up here?’’

''We can mentalize each other....'' “My mum doesn’t seem herself tonight…I wonder if it’s because she’s worrying about… or maybe she’s been thinking about…’’

''Mentalizing is a uniquely human process.'' It is something that we do automatically, often without conscious thought, in our every-day interactions. This is known as implicit mentalization.

Almost all aspects of social interaction involve the capacity to mentalize: //to understand the other person's behaviour in terms of the activity that has taken place inside their minds//…

//''Imagine if we never had any sense of other people’s feelings, beliefs or intentions..''//

We can also mentalize in a more conscious and verbal way.  For example, in a therapeutic context with a client, we may try to understand with them, their mental states or the mental states of others, that underly certain actions. This is known as Explicit Mentalization.

Below are some video teaching sessions of varying length and detail explaining mentalization in slightly different ways.

For those who prefer to read, there is more explanation and links to related theory and concepts throughout this page too.


!!''Video teaching''

!!!Training videos

For most teams (short version - 10 mins):
<html><iframe width="560" height="315" src="https://www.youtube.com/embed/sq61A5wGC8o" frameborder="0" allowfullscreen></iframe></html>




!!!''A brief conversation about Mentalizing ''
Wih Dr Jon Allen, Menninger Clinic, USA
<html><object width="560" height="315"><param name="movie" value="//www.youtube.com/v/NLT7ieO3hTk?hl=en_GB&amp;version=3"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="//www.youtube.com/v/NLT7ieO3hTk?hl=en_GB&amp;version=3" type="application/x-shockwave-flash" width="560" height="315" allowscriptaccess="always" allowfullscreen="true"></embed></object></html>



!!!''Prof Peter Fonagy - interview: What is Mentalization?''
Peter Fonagy here describes mentalizing and its applications in a 20 minute interview made at the Anna Freud Centre.
<html><iframe width="640" height="360" src="https://www.youtube.com/embed/OHw2QumRPrQ?rel=0" frameborder="0" allowfullscreen></iframe></html>



!! Where does the theory come from and why does it matter?

Mentalization (or Mentalizing as many practitioners prefer), originates as a hybrid, and not essentially novel, idea from: Philosophy of Mind, Attachment studies, Systems Theory and Neuroscience.

It has been proposed by a group of psychologists working in the United States and Europe. It combines the framework of Psychoanalytic theory, Attachment theory and aspects of research on social-cognitive development.

It is proposed that mentalization is one of the core processes that effective therapies have in common. And in some ways the study of mentalization attempts to create a shared language between different therapeutic models.  It explores how these shared factors play an important role in creating change.

''Mentalizing is central to understanding, regulating and communicating emotions,'' since emotions relate very directly to our beliefs, hopes and intentions, and whether they are being met, or frustrated or threatened. 

Reflecting on one’s own beliefs, desires, and feelings is also important for maintaining a healthy inner life. For example, if we feel anxious but have no way of understanding this experience, or why it is happening, it might be pretty overwhelming ! 

''A broad range of psychopathology can be seen as involving one or another form of specific mentalizing dysfunction''.
See Specific diagnoses and their corresponding Mentalizing failures.

''Mentalizing is closely connected to the development of a particular type of trust, known as'' [[Epistemic trust|Epistemic Trust]]. Epistemic trust is thought to play a central role in creating the conditions for the learning of socially and culturally relevant information through relationships. The links between mentalizing and epistemic trust are highly relevant in AMBIT, particularly as AMBIT was developed for clients who often have a relationship to help in which it is difficult to trust in the value of information passed through relationships.

!!''What is Mentalizing, and why does it matter? ''
A 70 minute illustrated talk describing Mentalizing, its origins, its value and what happens when it goes "offline":

<html><iframe width="640" height="360" src="//www.youtube.com/embed/xUdZaISunFU" frameborder="0" allowfullscreen></iframe></html>


!!Mentalizing and face to face work

Making sense of behaviour in this way is the cornerstone of clinical practice.

 The [[Therapist's Mentalizing Stance|The Therapist's Mentalizing Stance]] is a core part of all of the growing family of mentalization-based approaches to therapeutic work.

Therefore, the ability of the clinician to mentalize (to make sense of the behaviour in mental state terms) is particularly important, especially when the behaviour of our clients does not make sense in obvious ways, or seems inexplicable. 

Our Theory tells us that mentalizing is fragile, though – particularly in contexts of high emotion- and not just for clients, but for therapists too (in this sense it is a great "leveller" in the power dynamics of the patient-therapist relationship.) This explains the strong emphasis on Supervisory Structures in AMBIT - so that stimulating and sustaining our colleagues' mentalizing is as important as the work we do face to face with our clients.


!!''Pre-mentalistic stances:'' (or Non-mentalizing stances)
Three key concepts help to describe the states of mind (Pre-mentalistic stances) that are adopted when mentalizing becomes imbalanced.  These are:

*Psychic equivalence 
*Pretend mode
*Teleological thinking 

----
!!''Complexities in Mentalizing:''

''Mentalizing is a complex and uncertain process for a variety of reasons including:''

*A person can act according to a belief that is wrong.
*Beliefs arise through a complicated interaction between sensory perceptions, memory, and motivation and so may change for many reasons, perhaps because the environment has changed, or because some hidden mental process has occurred.
*Because beliefs are just representations of reality, people can have very different beliefs and feel very different emotions about apparently similar things.
*Mentalizing emphasises the uniqueness and specificity of the human's subjective experience. Therefore making sense of this in each other (or indeed at times within ourselves) is a complicated task at which we are only ever partially successful.


!!!''More videos''
See below a brief video of the famous scientist (and extraordinary communicator) Richard Feynman - describing how he came to understand that even the most basic mental functions (like counting, or reading) that we might take for granted as being the same for all of us, may in fact be conducted in extremely different ways:
<html><object width="480" height="360"><param name="movie" value="https://youtube.com/v/lr8sVailoLw?version=3&amp;hl=en_GB&amp;rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="https://youtube.com/v/lr8sVailoLw?version=3&amp;hl=en_GB&amp;rel=0" type="application/x-shockwave-flash" width="480" height="360" allowscriptaccess="always" allowfullscreen="true"></embed></object></html>

Another way of making sense of Mentalizing, courtesy of Pixar:
<html><iframe width="853" height="480" src="https://www.youtube.com/embed/_MC3XuMvsDI?rel=0" frameborder="0" allowfullscreen></iframe></html>


!!A Developmental Concept:


The capacity to grasp mental states becomes evident in the second year of life. It continues to be refined over the whole course of our lives as the nature of mental states are understood with increasing sophistication.


!!''Further material:''
*There are many helpful Mentalizing Quotes that help to define this very old concept.
*There is a hierarchical series of Mentalizing Levels that can be observed, and which the therapist tries to build on.
*There are Features of Successful Mentalizing that can be useful 'checklists' for therapists (and clients!)
*There are Features of UNsuccessful Mentalizing that can be useful 'checklists' for therapists (and clients!)
*There is The Therapist's Mentalizing Stance which is how we translate //theory// into //practice//, and is a core feature of all the mentalizing practices.
 

!!''Powerpoint Slides''
You can access teaching slides about mentalization.  Remember these slides are all released for sharing under a [[Creative Commons Licence]] - you just need to not pretend they are yours, and share them on similar non-commercial terms!
!!Reflections on the 8 team learning situations
* The team does not have an awareness of what works and what might need improvement - we have this in mind but we ideally would like more time to focus on this 
* We are curious about our work and its impact - we take outcome measures - we reflect on our work and how interventions are going 
* We need to reflect more to discover 'blind spots' or bias
* Busy doing sessions and meetings that we do not have time to plan and reflect 
* Difficulty being evaluated - as a team we feel that we are quite happy to be evaluated, we do want to know 

!!Two we would like to improve upon - what needs to happen to achieve the change?
1: The team are busy reacting, and not reflecting

* Have a learning space 
* We feel like we don't have the time for the reflection 
* Relationships with other people need to be comfortable and strong in order to be able to reflect with each other

2: The team considers different explanations and perspectives

* Would be good to learn more from Scotty's experience and knowledge within Brent - we do not utilise this enough
* We don't have a learning space - to learn from each other as a team 
* Do more 'thinking together' 
!!Reflections on the 8 team learning situations
*in light of COVID - we have had to be reactive both as a team and individually - did reflect but perhaps not as much as we would have liked
*we are very reflective as a team - we have had service development afternoon to discuss covid adaptions 
*do have learning spaces but so much learning needs to be done as a new team - need to consider altering/ increasing these spaces 
* evaluation of a new service- we have had to change to the requests made by commissioners  - around the report time 
*would like to be more curious - about the work and its impact - in a more live and continuous way not just around the report
*blind spots- had to adapt quickly due to covid so maybe didnt see all the 'blint spots' in hind sight- linked to being reactive

!!Two we would like to improve upon - what needs to happen to achieve the change?
1:Being less reactive and more reflective

*manualizing of reflections during the proposed new team reflective space  
*having a helpful reflective space in team meeting about cases- taking the case allocation to a separate space to allow time for this
*need to ''continuously'' reflect and discuss adaptations as a team 

2: Being curious/ evaluation 

*bring outcome measures into our conversations so that we can continue to be curious about our impact.
*be continuously curious and reflecting about our outcomes/ impact/ feedback and 'data' and not just doing it for the report.
*weekly 'spotlight'? to create a space for some of the things that are going well as well somethings that haven't 
!!Reflections on the 8 team learning situations
*
*
*
*

!!Two we would like to improve upon - what needs to happen to achieve the change?
1:

*
*
*

2:

*
*
*
!!Reflections on the 8 team learning situations
*
*
*
*

!!Two we would like to improve upon - what needs to happen to achieve the change?
1:

*
*
*

2:

*
*
*
!!A Special Interval
In a real sense the other three steps in <<tag [[Thinking Together]]>> (this being the third) are all designed deliberately to hold open this space - in which the worker who is [[Stating the Case]] is //steadied// enough by the mentalizing presence of their partner that they can mentalize more accurately.  This is key to the value in [[Thinking Together]] - the FIRST task is ''to restore the mentalizing of the worker'', rather than to leap straight in to working out a plan for the young person or family.

!!Cabin Decompression!
It is like the advice in the safety message before a flight:

>//"In the event of a sudden loss of air pressure, oxygen masks will drop automatically from above your head.  If you are with a child BE SURE TO PLACE YOUR OWN MASK FIRST, BEFORE ATTENDING TO THE CHILD."//

This is not about selfishness, it is about ensuring that our best intentions to help are supported by intact thinking! 

''We can't support mentalizing in our clients if we are not first able to regain this state of mind as the worker!''

<center>{{MtM.PNG}}</center>

The ritualised, marked, and boundaried "dance" that these steps provide gives //permission// to the worker to  discuss  their emotional reactions, and reflect on their thinking, alongside those reported by the young person or family. 

The intention here is to allow and foster a more curious and exploratory kind of thinking; one that does not shut down real thinking (on the grounds that the professionals "already know the answer", or that further thinking would somehow be //indulgent// when //it is action that is now required// - this last version would be a good example of Teleological thinking.)  

Too often, clinical discussion is //"un"//marked, and telling of the story (or rather purposeless and over-wordy "storytelling") leads straight into action.


Note the strong similarities between this and Mentalizing the Moment (in the Mentalizing Loop) that we use in mentalizing approaches to therapy/exploration with families and individuals.  Effectively this is exactly the same process, but applied in a therapy case discussion.

!!Why do it?

This interval is an important space from which more accurate [[Mentalization]], and thus more accurate assessments of the changing risk assessment as well as therapeutic opportunities may emerge.  Our hypothesis is that with more accurate mentalizing in the system, risks are reduced.

!!How to do it
1. The colleague who is offering help may firstly summarise back to the worker their understanding of the dilemma they have just heard. This gives the chance for the worker to hear their dilemma from a slightly different position, or from "closer to the bank" rather than being "right in the middle of the chaos"(if we use the Ripples in a Pond analogy).

 
2. Continuing this analogy, the helper here is momentarily trying to put themselves in the "middle of the pond", attempting to think about (and briefly communicate) what this dilemma may "//feel//" like for the worker. e.g.

>// "It seems like this is really tough for you at the moment with this young person..from what I understand, if I've got this right, it seems like the work has been going very well together over the last few months, and that this is a young person and family that you've got to know very well and really care about...This event seemed to come kind of out of the blue for you...I think if it were me I'd feel quite frustrated and a bit pushed away.."//
If successful the worker will be given a sense that their dilemma is understandable, that it makes sense to the helper.

3. The worker is then invited to join in acknowledging, clarifying and naming their ''own'' feeling states that may or may not be a reaction to the young person's dilemma - //but the keyworker will always try to MARK these as ''MINE'':// e.g.

>//"Thinking about it now, I guess my own emotional reaction is despair; I find myself thinking that giving up is the only option..."//

So although "feeling" in the present tense is a potential //barrier// to "thinking" ...in AWARENESS, it may also provide INFORMATION for the practitioner, and his or her [[Supervisory Structures]].

4. After this initial focus on the workers' state of mind it may be then helpful (and more possible) to mentalize the clients behaviour, looking for new understanding that might have been missed from being in the high emotion or chaos of the situation.e.g.

>// "Ok shall we just spend a minute trying to understand X's behaviour, because it does seem different and a bit unexpected..."//

!!And afterwards?

Only with the fourth and final step of [[Thinking Together]] ([[Return to Purpose]]) is this important "mentalizing hiatus" brought to a close.
!What might this time be like for families?

The outside world is rapidly changing in relation to coronavirus. This is an unprecedented situation for everyone and will be affecting people in a range of both similar and different ways. 

Families who were already experiencing stressful circumstances may now be faced with additional challenges related to the current situation:

*family pressures (managing relationships and increased conflict that might be occurring through having to be at home together)
*financial pressures
*challenges accessing basic provisions (e.g. food)
*educational pressures (managing home-schooling; deciding whether to send CYP to school if they have been offered a place)
* lowered physical well-being (through illness)
*lowered mental well-being (feelings of anxiety, worry, uncertainty, boredom, frustration, hopelessness and helplessness, as well as many other feelings will be very common for many at these times)
* how to explain the situation to children
*how to ensure that family members follow government advice, where their may be different perspectives about the need to do so

People's emotional state is likely to be fluctuating as their own circumstances and the situation in the outside world continue to change.

! How might we best check in with families about this?

Families will vary in terms of how much they want to be in touch with the service at this time. If contact is being made with families, it will be important to check in with them about how they are doing as a starting point, rather than to assume that sessions will run according to their usual structure in the first instance. 

* Ask family members how they are doing. 
* Give space for letting them talk about their own situations and circumstances if this is helpful. 
*Acknowledge and validate their thoughts and feelings. 
* Acknowledge how much of a difficult time this is for many people and that everyone is having to adjust and find new ways of managing, without much time to have planned this out (NB. be sensitive in framing this - aim is to help normalise some of the experiences, rather than to appear to be dismissing or minimising them). 
*Marking the task- helpful skill that our team would like to do more of in team meeting.
*
*
*
*
*
[[Look at reflections!|Reflections on module 3]]


Below is our current to do list. Any pages tagged with 'ToDoList' will automatically be added to the list below.


!!Checklist
<$list filter="[!has[draft.of]tag[ToDoList]!tag[done]sort[created]]">

<$checkbox tag="done"> <$link to={{!!title}}><$view field="title"/></$link></$checkbox>

</$list>

!!Completed tasks

<$list filter="[!has[draft.of]tag[ToDoList]tag[done]sort[created]]">

<$checkbox tag="Completed"> ~~<$link to={{!!title}}><$view field="title"/></$link>~~</$checkbox>

</$list>
Possible ideas

*[[RCADS|https://www.corc.uk.net/outcome-experience-measures/revised-childrens-anxiety-and-depression-scale-and-subscales/]]
*[[Goal-based outcomes|https://www.corc.uk.net/outcome-experience-measures/goal-based-outcomes/]]
*[[Session Rating Scale|https://www.corc.uk.net/outcome-experience-measures/session-rating-scale/]]
* [[Current view|https://www.annafreud.org/media/3196/current-view-2015.pdf]]

Here is a list of all pages tagged with Outcome Measures 

<<list-links "[tag[Outcome Measures]]">>
We would like to write a page about how to make sure we are balanced in the way that we make plans about our work. 

*We think it will be important to use goals and follow manualized approaches

*But we also think it will be important to tune into what young people want, follow their lead and be collaborative - we liked the idea of the [[AIM Cards]] and can explore whether we adapt a version for our wellbeing offer

*If we focus too much on the manualized approach, we may lose the young person

*If we focus too much on the young person, we might lose the plan!

We agreed to come back to exporing this, as it relates to a concept called [[Active Planning]] in AMBIT. 
!!!We would like to think about some dilemma's and questions around the following points:

1. We are called Well Being Practitioners but we have not carried out the formal qualification for this. In the formation of WEST the idea had been to train the WP's through practice 'on the job' rather than taking up a formal qualification as a WP before beginning the post 

There are 2 qualifications for WP's
(a) Educational health and Wellbeing Practitioners - this is a post graduate cert and has an extra module more than...

(b) Child WP - for this you may not need a degree (check this)

The training is very similar/overlapping

Both are carried out by UCL and the AFNCCF-) 

The WP's in WEST did not do this due to the above

2. The WP's in WEST have done a large amount of training and supervision with AFNCCF trainers/workers. Training has mapped onto the CWP/EHWP training curriculum (particularly in the early stages)

!!!The dilemmas for us are: 

*How do we show and validate our experience and training?
*How do we show/prove our training to others (e.g. jobs sometimes ask for 'qualified well being practitioners)
*If there is a meaningful difference between what we do and what others WP's do should we have a different title?

The WP's have said that they would like to do have the formal qualification/accreditation.

We are wondering if it would be possible to do a conversion to the formal diploma? If so what would be needed?

If this is not possible, a recognition/validation of the amount of training that we have had in the role would be important (both for our sense of what we have achieved but also to show for future qualification/jobs)


!What is this page about?

We would like to include parents/carers in our work as much as possible. A common need can be to support parents and young people to reach a point of agreement with each other about things like rules, routines and how they will behave/communicate towards each other. 

We wanted to put down some ideas about how we might approach these kinds of conversations.

!What's the problem?

It can be difficult to reach shared agreement between parents and young people, particularly for young people who are teenagers. There are lots of reasons for this, including the fact that the developmental stage of adolescence brings with it a lot of change, which might mean that rules, boundaries, routines and relationships start to look quite different from how they did when the young person was a child. Some parents and teens might be coming for help explicitly around their relationship, within which we might more naturally expect that collaborating on these matters will be hard. At other times, a point of difference/disagreement might come up as part of working on something else, which would benefit from some problem solving. 

We tried to come up with an approach to structuring conversations around these types of difficulty. This framework could be used to approach any kind of point of disagreement/difference/issue. We are proposing that separate conversations take place between worker and parent and worker and YP before a joint conversation happens to bring these points of view together. 

!Mentalizing the moment

What is it like when parents/YP are finding it difficult to agree with each other about how something should be? There can be a lot of strong feelings about, including frustration on both sides, feelings of not being listened to, being disrespected, different ideas about authority and whether it should be respected, feelings of powerlessness, helplessness and not wanting to be controlled etc. All of these could be being experienced on both sides, which might be making it difficult to think clearly about the best way forward or equally could be pushing parents/YP into very certain positions about what needs to happen, which could be leading to some inflexibility or a wish for a "quick-fix" (action) rather than a process of collaboration. 

If parents/YP do not have very clear ideas in their head about what they think/what they want, having some time to work this through could also be helpful. Generally, if its hard to reach agreement, having a separate space where each person has an opportunity to work through their thoughts about what they might want and talk through any strong feelings, can be helpful before bringing people together. Doing so prematurely may mean that the differences and feelings play out in the session in a way that makes collaborative thinking much harder! It also leaves the worker in a position of having to think on their feet as they start to see the points of difference unfold in front of them, rather than being able to build an understanding of these prior to the session and coming with more of plan about what might help. 

Giving people separate spaces could be thought of as having a ''mentalizing'' way of approaching the situation - giving each person a chance to have their own thoughts clarified and feelings validated before expecting them to get into a position of taking on the perspective of the other person. This separate opportunity to think things through with the worker gives each person the best chance to be in their thinking brain when the session to work out the "compromise" takes place. The worker may achieve this by supporting the parent or YP in any number of ways in order to achieve this (e.g. exploring their thoughts and feelings, offering the acknowledging/validating these, offering some scaffolding to help them think things through if they haven't done any thinking on the issue themselves or are finding it overwhelming to do this etc.)

!Introducing the rationale

Following an [[active planning|Active Planning]] stance, it's helpful for workers to broadcast their intentions about why they might be approaching the conversation like this - i.e. 

//"The (e.g. bedtime/sleep routine) is important to you both, but you're got quite different ideas at the moment about what it should looks like. I know that agreeing on this has been hard, so I want to try to help you find something you can both agree on, but its probably going to involve a compromise! I'm happy to think with you both to see if we can work this out - we can do it separately to start with, so you've each got a chance to tell me what you think and what your ideas are, then we can bring those together and see where you agree, where you disagree and work out what the middle ground is".//

! What to include in the conversations

Some questions might include: 

*Asking each person what they feel their ideal would look like, in terms of the (e.g.) sleep/bedtime routine?
*What would it best look like if they could design it?
*How close is that to what is happening at the moment?
*If its not close to what's happening at the moment, what would be realistic?
*Where would they be prepared to move to? What would their compromise be? (supposing the other person had a different view)
*What do they think the other person (their child/ their parent) would think about their ideas?

Can ask parent/carer to write down their ideas/routine/rules around (e.g.) sleep routine and then ask them to give each part a priority rating (low, medium, high) and a realism/achievability rating. This can help the parent to refine their expectations in line with what is achievable and developmentally appropriate, if needed. 

Similarly, the young person could write down their ideas about what their ideal rules would look like or the worker could show them the parent/carers' ideas and ask them to rate them according to things they already do/could do/would be prepared to do (green), things that are a bit ok/achievable and things in red that they think are unreasonable and would be too hard. 

When discussing rules with parents/carers and young people, it can be helpful to acknowledge the "purpose" of having rules - helps people to know what to expect from each other; most families do have some rules, even if they don't get called "rules" - like just how we do things/things we don't do. The purpose here is to make these a bit clearer, even though that might seem a bit formal, but with the aim that them being explicit and clearer helps people to know what to expect. For teenagers, mentalizing their experience of having to have rules might be helpful! Rules can feel annoying, but equally how does learn to deal with rules help prepare them for life?! Worker could acknowledge some rules that they have to follow as an adult that they would rather not!

!Increasing motivation/compliance with the proposed changes that parent might be suggesting 

It can be helpful to address low motivation/ambivalence on part of YP to engage with parental wishes

*Explore what the pros and cons would be of trying it out
*Seeing if they would be willing to experiment with trying it and let you know how it was - then talk through if there were any pros and cons
* Would complying with it help in other ways (to get parents off their back; reduce arguments etc!)?
* Following the parents' expectation might be worthwhile - e.g. if you show you can go to bed at this time, maybe they will let you stay up a bit later - is there anything in it for them?

!Explore with parents how they will positively reinforce compliance with routine/rules

Share ideas with parent about how they do this already in general and therefore what might work here. 

*What kinds of things do they feel might encourage the young person to stick to it?
*What works in general with this kind of thing? Do they like praise/encouragement? Would it be best verbally or sending a text or leaving a note?
*Who else might be able to help with supporting this to happen? Can other family members be involved in encouraging in a way that would be motivating?

**praise, positive feedback, encouragement
**reward system (e.g. earning something they don't already get; linking something they do already get to this new behaviour of following sleep routine)
**consequences for not following. 

[[Rewards/consequence programmes]] need careful thought and planning. 



__''What to include on the referral form''__

(CPFT example CAMHS referral form)

!Referrer details

*Self 
*Parent
*Professional (details)
*Including phone number, email address

! Demographic information
*Name
*Address
*DOB
*Ethnicity
*Gender
*School year
*School
*GP
* Parent/carer (address, phone number, resident)
*Siblings and schools
* Other professionals (current)
*Tick box - CIN, CP, LAC, EHCP, SEN, Disability, Young Carer, known to CAMHS

! Reason for referral

*What are the well-being or mental health concerns?

*What's going well? (at home, school, other settings)

*What help is needed/wanted?

! Current risks/contextual factors?

Checklist - adapt inclusion form checklist

! Consent (if not self-referral)

Consent from young person
Consent from parent












__Being clear on the different spaces in our team__

*reflective space (separate space on a wed): reflecting on how we feel about the work 
*service development space (at the end of the team meetings) : how our work is being implemented practically 
*Using our time in a more structured way- team discussions 
*really important to create these so that once we are back to face to face and things are busier we value these as a priority and treat them as such.


__How do we make use of manualizing __

* manualize during the last half an hour of team meetings during our discussion around practice development.
*we just need to do it! 
*Allow us to be more focused in our conversations 
*would someone be able to look at our wiki and learn what we do from it?
*to share the writing responsibility of writing in the manual during manualizing as a team 
*learning to share our thoughts and manualize at the same time 
*manualize the proposed reflective space 
*manualizing pracitical non-identifiable points 
*CH and JP to manualize conversations about the teams/ outcomes/ data/ reports etc.
*manualize how we write the report - to help us continuously evaluate our service in a transparent way

__What to hold in mind in the reflective space__

* changes/ adaptations that we have made and bring these back - example: changes we have made due to COVID and reflect on if these are working- what went well/ didn't 
*points brought to the team meeting by members of the team that require more discussion rather than just 'business points' this might cross over from the team meeting service development space 
* the thinking together tool - use it! using 'the chair' person 
*how the work is effecting us, how are we feeling about the work 
*how we communicate as a team 
*how the current circumstances/ context may be impacting our work and how we are working as a team and individually - this may change once we go back to working face to face (currently may have more time/ easier to 'fit it in' and give it priority)



__How do we make use of local experts__

*We often wait until we have a relevant case - how can we preempt who the required experts are
*We have developed a directory- how we can use this to build relationships with these services.
*Could speak to services/ ask them to speak to the team on the phone/ teams to better understand what they do on a personal level. 
*Could structure this by giving a member of the team a service to contact per month.
*when we have cases that we talk to external teams and services having a space to share  this information- agenda on the team meeting 
*using links/ connection made to services through case notes to ask about other wider services that are available 
*reshuffling in Brent- could allow opportunity to make new connections 
*need to make less assumptions that everyone in the team has the same knowledge of services as we do. - bring back to space in team meeting
*once back working in person this might be easier
*picking services that we will be working with often to start getting an in depth knowledge of what they do/ relationship build.
*connecting more with 'young champions' 
*Brent induction- yet to receive this - could we spend some time understanding the Brent LA services.
*helpful structure for our team meetings and case discussions.
*Helps us have an expectation of what help seeking in our team might look like which might make us more likely to seek it.
*interrupting is ok! which is helpful to know for all members of our team as we will all know why we are doing it and it wont be misconstrued as rude
*help me be more aware to think about what i am looking for when i ask for help
*that help seeking is a two way process and you have to help them help you- being more specific about what you need/ want help with when help seeking
*The help seeking process can be awkward and make us feel vulnerable- this is how our families may feel and we need to keep this in mind when offering help
*having a space within the team to discuss help seeking that we can continue to consider and tap into this space in our work with families.
*might make us feel more contained knowing we have a team space that has had these discussions.
*Sculpting exercise helpful at point of referral to see if our support would be beneficial
*Sculpting in team meeting will help us inform our work with professionals and the next steps 
*Sculpting exercise will help us to mould the TAC to be most helpful to the CYP 
*Chair exercise - help us to 'team think' and use different minds to solve challenges that come up in our cases
*Chair exercise to use in team meeting and case discussions as well as consultations to help professionals think about the appropriateness of our involvement and what other professionals are already doing.
*adopting language from AMBIT in our practice when we are speaking with external agencies
*
* To be mindful of informing the client of your thoughts; sharing our plan and our thoughts, why we might be quieter some times
* To check in about what the client wants to bring and talk about how to make space for it in the session
* Leave time to reflect on the session together
* Thinking about each session as a "standalone" piece of work - what we might be wanting to achieve in each one. 
* ensuring the client is also a participant; you're both hearing each other
* sharing the plan with the client and making sure you know what they think about it before you proceed
* remembering that the plan can be changed, as long as it happens in an agreed way - the plan can be dynamic, as long as you are both sharing your states of mind about it so that you can both be aware that the goal has changed so that you are still travelling in the same direction
* aware of how many people can influence the plans that we might have with YP. Are the plans that are generated always made on the basis of what the client and worker thinks or too heavily influenced by other people's thoughts and ideas?
__''Key reflections''__

We reflected together on key themes from today, in relation to the four different areas of our work. These were themes that arose from the discussion we have had. 

__Client__

*Feel excited about making resources/portfolios for young people that are adapted to their needs
* Feel like we will need to balance being tuned into young people and following their lead, with ensuring we are doing the goal-focused work. We need to make sure we get shared ideas about what to focus on, so its not just about following their agenda vs. our agenda. 

__Team__

* It was helpful to share experiences with each other - learned things about each other that we didn't know
* Feel like we will be working as a team and helping each other with our work and that this is important
*Feel that we will have a 'team behind us' when we are doing our work, even though we might be carrying out the work on our own
*Feels important to liaising with each other to share ideas about how to do the work - we can help each other out. 
* Its good that we could talk to each other about what we are already good at, but also what we find hard and need to develop

__Network__

*How we can be thinking about involving the network around the young person from the beginning of our work? Its not something to leave until the end, but to be done throughout. 
* We could think about creative ways to include people from the network - it's not just about bringing others in to focus only on problems, but also to share successes (this might feel like a more comfortable place for the young person to start)

__Learning__

Getting the balance right between: 

* Learning from each other: It was reassuring to hear others sharing their experience about something that I didn't have much experience of (e.g. outcome measures) because it helped me get some ideas about it. I was less worried that I didn't know it, because I know there's others in the team who I can ask. 
* Learning from evidence: its important to know the manualized approaches well (e.g. CWP manual), because it might be that we need to apply it creatively or adapt it to meet the needs of individual young people, which we will be better able to do if we have a good understanding of the material. 

See [[LEARNING at work]]

* We can make templates of resources that we can share within the team

__What was helpful from today that we'd like to carry forward?__

*Having examples to make the ideas concrete
*Varying formats for activities/discussion

* Helpful to think about our general values about well-being and mental health
* Good to start thinking about this together
* Helpful to think about how we might adapt our explanations to fit with what they are bringing, rather than using a very fixed way each time
*
* Importance of highlighting that we are working together on your wellbeing and getting YOUR ideas about
* Helpful to think about the links between wellbeing and context
*Patchwork exercise helpful as a creative way to think about wellbeing

__''ACTIONS''__

*How would you introduce the idea of wellbeing 
**To a younger child
**To an adolescent
**To a parent
*Think of analogies that might work that could link 
*Get clear on your 3-5 bullet points that would help you describe what you mean by wellbeing in the context of being a wellbeing practitioner. 
*Avoid jargon, being too long or doing a speech! Simple points are better - you can always elaborate if needed
#Introducing the cards - explaining the purpose of them seems ok; difference between saying "getting to know each other vs. getting to know you". These cards can help us work out what to work on together, so might feel like there are more cards in here that are to do with problems.

# Young person sorts the cards: helpful to comment a bit on the process when they are doing it
** You did that really quick!
** You were really thinking about that one
**That one seemed a bit harder to work out where it went

# Exploring strengths/what's going well:

Reflections:
YP - nice to speak about the good things that were written down. Liked being able to talk about the good stuff and how the worker linked the good things together; made me stop and think and work. 

Workers - felt a bit more natural to gravitate towards the things that were a problem; important to go through these first. Hearing about the good things might help us out with some of the things that are going well. 

Importance of asking OPEN QUESTIONS (vs.closed questions) to help explore and build an understanding of the strengths:

Examples of questions that could be asked about the card ''Getting on with my family'':

*What do you do with your family?
* Tell me a bit about why you picked that card?
*Who is in your family?
* Who do you get on with the most?
* What does getting on well with your family look like?
* What did you have in mind when you picked that card?
* Does everyone in the family get on with each other? vs. How does everyone else get on with each other? Who gets on with who? 

''Exploring the the difficulties pile ''-

YP - nice that the worker asked things and also then gave bits back to me with her reflections to check she was understanding what was going on

//"So let me just check that what I've understood is correct..."//

Worker - felt easier to ask about the difficulties, felt as though there was more to explore. Trying to get the balance between YP express themselves and also helping out with that where it got hard. Was trying to normalise without being invalidating. 
We watched the 4 videos below and reflected afterwards on what we liked/what was helpful about them

__''We all have mental health''__

https://www.youtube.com/watch?v=DxIDKZHW3-E 


*Normalising - we can have good feelings, negative feelings and going through ups and downs is normal
**Feels important to be mindful of not invalidating how a CYP might be feeling by over-emphasising normalising)
*Could be a helpful video to take key points from to help us explain what we mean by wellbeing
*Different strategies were helpful for different people - e.g. distraction worked for one person, activities for another. 
*"Emotions popping up and not going away" - helpful language
*Liked the emphasis on psycho-education - talking about it and learning about it together
*Seems more suited to younger children - could imagine showing it to a child to stimulate discussion

__''Talking mental health''__

https://www.youtube.com/watch?v=nCrjevx3-Js

* Good to hear the focus on the importance of CYP having people to talk to about how they are feeling - although they might be coming to see us, it will be important for us to help them to connect with the people in their existing networks to do this too
*Some of ideas might apply more in a group setting - i.e. 'how you could help someone else who is struggling?' could be a good question to ask in a group
**its also an example of a question that could be asked to help a young person come up with ideas for useful strategies that they could then apply to their own situation; sometimes this is an easier starting place than focusing "what might help me?", which might feel more difficult to think about
* Could be useful as a way of explaining some of the core ideas (e.g. showing a video in a school). 
* Wellbeing work being preventative - when the problem has just started. Feels like this language/framing would work well for this aspect of our work

__''What does wellbeing mean to you?'' - Nuffield__

https://www.youtube.com/watch?v=oSIWo5nxF2A 

* Helpful to have the adolescents' ideas 
*More focused on physical health and less on emotional health explicitly, but physical health is an important contributor to good emotional health
* Liked the terms that were used "taking care of yourself"; being healthy outside and in. 


__''Mental health: In Our Own Words''__

https://www.youtube.com/watch?v=_y97VF5UJcc 

*Although older young people with more significant difficulties, there was a sense of hopefulness: people talking about how they have coped
* Emphasis on how talking and sharing it had helped - importance of networks and relationships
* Becoming aware - of how the problem started, what they can do to cope, a sense of knowing how they are now. Having an understanding of these things seemed helpful?
* How different the experience can be for everybody - people defined and described different experiences that had contributed to poor mental health
* Did describe how difficult the hardest moments can be - not trying to gloss over these with an idea that everything can be made better. Helpful to be able to sit with this
* Some of the things that they described as helpful were still some of the 'everyday' things about how they looked after themselves, their relationships, doing activities, as well as things like having therapy/seeking professional help - important to remember the balance between these

__Other videos that you could watch and comment on:__

*''Five ways to wellbeing'' - a video made in collaboration with adolescents

https://www.youtube.com/watch?v=yF7Ou43Vj6c 

!!Key points of theory
* AMBIT is an approach which emphasises //the importance of relationships in promoting positive change//, so engagement is a primary task for the worker (and the young person!)
* It makes use of attachment theory (especially the idea of internal working models) and [[Mentalization]] (especially the related topic of [[Epistemic Trust]]) to provide the theoretical basis for this; help-seeking behaviour lies at the heart of attachment theory and research.
* There is also a fit here with ideas about hidden, private or implicit theory drawn from the implicit psychoanalytic model]] that can be seen as contributing to the [[Mentalization]]-based approaches.

!!How this fits with AMBIT
* Within this general framework, there is also interest in the specific processes and experiences of people seeking professional help for their difficulties:
** One of the assumptions of the AMBIT model is that many of the young people will have had negative previous experiences with professional helping systems and/or will have negative beliefs and feelings about such help. 
** Many AMBIT practices are designed to find ways of working with clients who may have many reasons for not wanting to work with professional services.
!!!A universal 'Primary Outcome' for ~AMBIT-influenced teams?
* There are few if any generalisable treatment Aims and Goals in AMBIT-influenced teams - but ''"developing a more adaptive relationship to help" is probably one of them''.

!!Mentalizing the relationship to help
There are many ways that clients might //perceive// the help that we offer, and these may be influenced by early experiences for an Attachment-based explanation of this.)
Our perception of what help is will trigger emotional reactions to this, and these will influence our behaviour.  AMBIT takes a view that there are many different ways in which our clients might experience our help (however authentically //we// might feel we are offering it).  The point is that ''understanding how young people see our help'' might in itself help us with [[broadcasting our intentions|Broadcasting Intentions]] in a clearer way //for this young person// - to enable them to accept (or "enter") help, despite their concerns or objections.  In this way we are offering opportunities for them to develop new perspectives on help.

!!Diagram
<<image [[RelatToHelpDiagram]] width:600 height:480>>

This  diagram (animated below) is ''not an attempt to define reality'' (which would be Psychic equivalence on our part!) but is more a "thought experiment" that tries to describe some of the commonest barriers to help that may be worth considering.  

A young person may (mis)perceive help in different ways at different times.  Getting to be helped requires a "Therapeutic Bargain" - in which the client "takes a chance" and "enters anyway".  Although she may enter through many different "doors", she may leave understanding rather more accurately the perspectives of a helper that may have been misunderstood from "outside the door".  There may commonly be "comings and goings" in and out of relationship with help, rather than a "coming to stay".

*Consider ''"//different kinds of Help//"'' as being available "inside" the diagrammatic "house".  
* There are four doors in and out of this house (though in reality of course there are many more)
* The three "Blocks" that stand in each doorway are as follows (from the outside going in):

#The ''Response to Help'' in terms of the ''//affective/behavioural response//'' to what they "see" standing between them and real help ...e.g. hopeless, fearful, denying, angry. 
# The ''Response to Help'' in terms of the young person’s own ''//perception/construction/imagination//'' of the ''state of mind of the worker'' who stands between them and help ...e.g. helpless, useless, refusing, accusing. 
#The ''Offer of Help'': A selection of potential ''states of mind that the worker might actually offer the young person''  e.g. interested and committed, holding hope that things will change over time even though ways forwards now are difficult to see, authentic and truthful (expressing confidence in the young person's self-agency, unafraid to "tell it as it is" in terms of diagnoses or reflections. 

If the worker can properly mentalize the young person's authentic feelings and beliefs, right here, right now, and can //show// (in her eyes, and her manner of speech, etc) that this has been sensitively understood, then [[Epistemic Trust]] may be established, and help or learning may quite suddenly be accessible - like a door opening.  There may be learning, that //"help may look unhelpful sometimes, and this can be explored..."//

The point of this thought experiment is that ''if we, as workers can more accurately mentalize our clients' experience of (or relationship to) this "Help" we are offering, then we may be more successful at __adapting the way that we are offering it__'', in order to make it less indigestible than unfortunately our well-intentioned offers of help too often appear. Of course, the shift towards greater mutual understanding is the work of engagement, and a key skill is how the worker can find ways of [[Broadcasting Intentions]]. 

!!!Animation:
<html><object width="640" height="480"><param name="movie" value="https://youtube.com/v/SGBZt1W1TnE?version=3&amp;hl=en_US&amp;rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="https://youtube.com/v/SGBZt1W1TnE?version=3&amp;hl=en_US&amp;rel=0" type="application/x-shockwave-flash" width="640" height="480" allowscriptaccess="always" allowfullscreen="true"></embed></object></html>

!!Welcome the Coming and Speed the Going
(With thanks to Dr Paul Caviston for this quote)
Note that the end point is not the young person "__taking up residence__" in the help centre, but taking what is on offer there to set off on the next stage of her journey.  This echoes the ancient "code of conduct" described in Homer's //Odyssey// which all dwellers in the Greek islands held:

>''"Welcome the coming, speed the going"''

This code dictated how islanders were obliged to behave towards sailors who were shipwrecked on their shores (which must have been a pretty commonplace event back then.)  The duty was to provide hospitality, repairs, and to stock the ship for the onwards journey.  
__Reports__

* Report on the specific KPI’s directly
* Excel spreadsheet – how we are achieving the specified targets – all KPI’s at a glance
* Borough priority to provide services to boys of Black Caribbean heritage- need to include how many are involved in the service
* Within each ethnic group – need to be specific about gender and age too i.e. the number of boys of black Caribbean heritage that are aged 14 involved with our service
* Be specific about how many CYP’s have an EHCP, how many are at risk of exclusion etc.
* Also breakdown according to the vulnerable groups – children on CP, edge of care, gang affiliation
* Template to be shared of report and state what key characteristics need to be reported on specifically
* Spreadsheet of those cases that are too complex or severe for our service – add these in to signposting section rather than rejected referrals

__Reporting__

Reports to be sent out two working days prior to contract management meeting

Next meeting dates:

* Q2 - Thursday 23rd April
* Q3 - Thursday 23rd July
* Q4 - Thursday 22nd October
-	SDQ shows level of need rather than improvement
-	The question is whether we have reduced the impact of the MH problem – not whether we have cured the MH problem – the problem might be less
-	Reduce the chronicity or intensity of the distress rather than cure
-	Improved functioning 
o	Engagement in education
o	Achievement of goals
o	Improved sense of agency – feel like they can do something about their problems
-	How much do we target more vulnerable groups?
-	How does the demographic of our service compare to the demographic of Brent overall? E.g. ethnicity of the CYP seen in the service compared ot the ethnicity mix in the borough – are we seeing a presentative population?
-	Is our service helpful to our population? Organise our report around this question?
-	How much recovery happens independently of therapy?

Look at our service spec – page 12 – outcomes
JP - Look at Helen and Emma’s original outcomes plan – logic diagram – does this till fit? Organise the report around this?

<<list-links "[tag[Resources for work]]">>
Here are some websites that may have useful resources that could be adapted for families, or if used, their source fully acknowledged. Please discuss the appropriateness of the resources with your supervisor before sharing with families. Get familiar yourself with any of the resources that you share and be able to offer a rationale for why you are sharing them, so that you are able to answer families' questions about them. 

''A wide range of CAMHS resources''


[[CAMHS Resources- Downloads|https://www.camhs-resources.co.uk/other-links]] contains their list of helpful booklets and resources for children, young people and parents which may be particularly relevant during the COVID-19 lock-down.

Managing COIVD-19 related anxiety [[resource|https://www.christie.nhs.uk/media/8758/1386-managing-anxiety-about-covid-19.pdf]]

[[Health Young Minds|https://healthyyoungmindspennine.nhs.uk/resource-centre/guides/ ]] contains resources un specific to COVID-19 but that cover MH concerns that might arise during home isolation 

[[NHS Lothian website|https://services.nhslothian.scot/camhs/Resources/Pages/ResourcePacks.aspx?fbclid=IwAR0lN_o4l3r0Omib6daX43Ji2XlX51W4x5ra9MrggqHM6VqUuQceVhvFONs ]] contains a plethora of resources regarding COIVD-19 for parents and children and young people. It also contains specific supporting resources for people with neurodevelopmental disorders, as well as activities, social stories and visual aids.

''A range of additional resources in a open access dropbox''

https://www.dropbox.com/sh/x7p6mqpknblwgbe/AAC8yjkvj4PpmrnsXda1M9DXa?dl=0

''Self-care ideas''
The Anna Freud Centre have developed a variety of [[self care ideas|https://www.annafreud.org/on-my-mind/self-care/]] on their website

''CBT App for 10-18 year olds''

[[An app|https://www.healios.org.uk/services/thinkninja1]] 
 that has added a lot of Cognitive Behavioural Therapy resources that has been opened up to be ''free'' for 10-18 year olds

''Supporting CYP with autism''

[[The National Autistic Society|https://www.autism.org.uk/services/helplines/coronavirus/resources/helpful-resources.aspx ]] have collated a series of useful resources that autistic people and their families can use during this time of changes 

''Bereavement support for CYP''

[[Winston's Wish|https://www.winstonswish.org/coronavirus/ ]], are a bereavement support service. Our Freephone National Helpline, along with our ASK email, Crisis Messenger and online chat services remain available to support bereaved families and professionals caring for them. 

[[They are the Future|https://theyarethefuture.co.uk/ ]] - Loss and Grief in children and adolescents related to Coronavirus and Worry and Anxiety about Coronavirus.

''Online counselling service for CYP''

[[Kooth|https://www.kooth.com/]]
 are a counselling service that run their services online

''Peer support (online) for CYP with MH needs''

[[Hearts and Minds|https://heartsandminds.org.uk/]]


''Talking to children about Coronavirus'' 

Story book for young children who are worried about conronavirus:

<<link-doc "Dave the Dog is worried about Coronavirus" "https://drive.google.com/file/d/1D7pN6gHSfVT-tRL2REzkdgPVZOTLKEqZ/view?usp=sharing">>

A fantastic book by Elizabeth Jenner, Kate Wilson & Nia Roberts Consultant: Professor Graham Medley Professor of Infectious Disease Modelling, London School of Hygiene & Tropical Medicine and Illustrated by Axel Scheffler

<<link-doc "Coronavirus: a book for children" "https://drive.google.com/file/d/1-EdhVyWeXrd0Dvc5OYS3KPQa3PlXaRjG/view?usp=sharing">>

Another lovely book called 'There's Something in the Air' Written by Anjali Bhat. About a bee trying to cope with lockdown due to the pandemic.

<<link-doc "There's Something in the Air" "https://drive.google.com/file/d/1lo1yIHR1PLWDhQWN7sHT6um40Ta47BvB/view?usp=sharing">>



''Talking to children about illness'' 

<<link-doc "Talking to Children about illness" "https://www.bps.org.uk/sites/www.bps.org.uk/files/Policy/Policy%20%20Files/Talking%20to%20children%20about%20illness.pdf">>


Children's Commissioner's have developed a helpful guide for children regarding coronavirus. The have also got a plethora of [[resources and support for school staff and parents|https://www.childrenscommissioner.gov.uk/coronavirus/]]

<<link-doc "Childrens guide to coronavirus" "https://drive.google.com/file/d/1k4QQUgnC3SVRLlcPUVSs_BqG0u2hD77i/view?usp=sharing">>


''Supporting parents/ carers''

School closures:

<<link-doc "Support regarding school closures" "https://www.bps.org.uk/sites/www.bps.org.uk/files/Policy/Policy%20%20Files/Coronavirus%20and%20UK%20schools%20closures%20-%20support%20and%20advice.pdf ">>

WHO have developed [[Parenting Tips|https://www.who.int/emergencies/diseases/novel-coronavirus-2019/advice-for-public/healthy-parenting]]

''Supporting children and young people with worries about COVID-19''

A handout called Supporting children and young people with worries about COVID-19 from Emerging Minds.

<<link-doc "Supporting children and young people with worries about COVID-19" "https://drive.google.com/file/d/1qzuSSCz0NNwvDGayqHoFoV7VRbQgo11N/view?usp=sharing">>

''Other helpful websites'' 

A great website [[Safe hands thinking minds|http://www.safehandsthinkingminds.co.uk/covid-anxiety-stress-resources-links/]] containing  Covid, Anxiety, Stress-  Some resources to support children and adults around anxiety, worry, stress, and fears; including specific Covid (this page will be updated on a very regular basis. 

Mind – [[Coronavirus and wellbeing|https://www.mind.org.uk/information-support/coronavirus/coronavirus-and-your-wellbeing/ ]]

AFC – [[Advice for young people, parents and carers and schools and colleges and self- care ideas|https://www.annafreud.org/what-we-do/anna-freud-learning-network/coronavirus/]]






''Self-care ideas''

The AFC have produced tiles for Self-care on their [[website|https://www.annafreud.org/on-my-mind/self-care/]] these can be used by staff or shared with Young people and families.

[["It's okay not to be okay"|https://www.ics.ac.uk/ICS/Education/Wellbeing/ICS/Wellbeing.aspx?hkey=92348f51-a875-4d87-8ae4-245707878a5c]] A page of resources from the Intensive Care Society about supporting staff wellbeing.

''Talking to children about Coronavirus''

The BPS have developed some advice for pracititoners on how to talk to children about coronavirus. 

<<link-doc "BPS advice: how to talk to children about Coronavirus" "https://drive.google.com/file/d/1mbO1aNp2kgg9AfojVUMrTpuCcW8RfNtX/view?usp=sharing
">>

''Talking to People about Dying during the Pandemic:''

<<link-doc "Talking to People about Dying during the Pandemic" "https://drive.google.com/file/d/13_pSm_4UrsNj3sC3EdBY57XJ5OOCnw68/view?usp=sharing">>

''Supporting children and young people with worries about COVID-19''

A handout called Supporting children and young people with worries about COVID-19 from Emerging Minds.

<<link-doc "Supporting children and young people with worries about COVID-19" "https://drive.google.com/file/d/1qzuSSCz0NNwvDGayqHoFoV7VRbQgo11N/view?usp=sharing">>

A policy document from the UN's IASC summarizing key mental health and psychosocial support (MHPSS) considerations in relation to the 2019 novel coronavirus.

<<link-doc "ADDRESSING
MENTAL HEALTH AND
PSYCHOSOCIAL
ASPECTS OF
COVID-19 OUTBREAK" "https://drive.google.com/file/d/1LZZlc4Lqy64obof8XbEoJ95q1MR_v8ce/view?usp=sharing">>



A brilliant blog post from an psychological wellbeing practitioner in the UK with a wealth of practical advice about how to conduct psychological work effectively over the telephone.

A short fact sheet of guidance from the Oxford CADAT about how to conduct effective memory work in cognitive therapy for PTSD remotely.
A stance of respect for local practice and expertise is one of the [[Core Features of AMBIT]], and there are [[Training Exercises for Respect local practice and expertise]] in this manual.  

<html><object width="425" height="344"><param name="movie" value="https://www.youtube.com/v/mNUJg4LMEkU?hl=en&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="https://www.youtube.com/v/mNUJg4LMEkU?hl=en&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></html>

Consistent with a [[Mentalizing]] stance, AMBIT adopts an explicit sensitivity and respect towards the local service ecology; for instance, local Social Work departments, Youth Offending Services, Medical services, Education, Housing departments, etc.

The aim is to build on strengths and existing local expertise ([[Scaffolding existing relationships]] as it were) and this is reflected in the process of [[Manualization]], which asserts the value which existing local expertise in a team will add value in terms of //how to implement// other evidence-based ways of working, or AMBIT-influenced practices //here, in this specific locality, amongst these specific organisational constraints//.

Much of what a successful team is already deploying locally with success will be expertise that offers value for other teams working in similar settings, or with similar target groups.  This explains to some extent the high value that AMBIT places on its [[Community of Practice]].  AMBIT's TiddlyManual format allows for a "__co-construction__" of evidence-based practice and practice-based evidence, and moves away from the monolithic 'one-size-fits-all' approach that has characterised many manualized approaches before.

What this means is that AMBIT workers deploy their [[mentalizing|Mentalization]] skills ''not only'' towards:

* Young people and families
* Their team colleagues (the [[Keyworker well-connected to wider team]] is another of the [[Core Features of AMBIT]])
''But also'' in relation to:

* The local service ecology (other agencies and professionals working with the same client group.)

This means making a positive and explicit efforts (adopting this as a deliberate staff culture) to avoid 'polemic positions' (//"Social workers are ALWAYS doing this to my clients...!"//, or //"Typical GP!"//), instead [[Addressing Dis-integration]], for instance by using the [[Dis-integration grid]] to clarify one's own ('mentalized') understandings of local practitioners' positions.

!!AMBIT is never a stick to beat other practices with...
A huge amount of investment goes into training and developing models of practice, and developing the outcomes evidence that supports these.  For a new model or approach to arrive in a locality and unintentionally (or, worse, intentionally) undermine or damage an existing model of practice that is working well, would be a serious "side-effect" of the training intervention.  
AMBIT is expressly designed to //avoid// such unintended consequences.  Indeed, any active attempt to use AMBIT as a "stick" to beat other methods and practices in a kind of "treatment models turf war" would be an extremely non-mentalizing use of these materials and theories.

!!Training
The training of [[AMBIT]] increasingly tries to recruit LOCAL specialists to deliver training on specific interventions during team trainings, or to deliver AMBIT training. There are [[Training Exercises for Respect local practice and expertise]] in this manual which we encourage [[AMBIT Lead]]s and others to practice.

!!Experts by Experience
Another area of Local Expertise, is of course that of the Service users - who are "experts by experience".  The constant harvesting, learning from, and adaptation of a service in relation to service user feedback is thus a key part of the practice that flows from this principled stance.
<center>{{Stance-RespectEvidence.JPG}}</center>

One of the [[Core Features of AMBIT]] is ''respect for the fact that //there is such a thing as __evidence__//'', on the basis that to ignore this would be to show great disrespect towards those whose future may depend upon the outcomes of our decisions.

<html><object width="425" height="344"><param name="movie" value="https://www.youtube.com/v/zHWXq1CctxQ?hl=en&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="https://www.youtube.com/v/zHWXq1CctxQ?hl=en&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></html>

As the phrase suggests, AMBIT strives to orient itself to reality, and to facts that are proven, rather than a particular clinician's opinions or wishes.  This is entirely consonant with [[Mentalizing|Mentalization]] practice, which promotes a curious inquisitive //tentative// stance - open to learning and avoiding the assumption of knowledge without evidence (Pretend mode functioning.)  

Evidence can take a variety of forms; different pieces of evidence are different not only in how much respect they command, but also in their applicability to a specific situation at a specific time.  This work is an inexact science, but [[Evaluating outcomes|Outcome Measures]] lays out the rationale for integrating the day-to-day therapeutic tasks with regular, robust outcomes measurement.  Of course, in the hierarchy of evidence applicable to the developing content of the AMBIT manual, properly conducted trials and systematic reviews are at the top.  Outcomes evaluations from teams working in the field constitute a valid and important step towards developing and conducting such trials.

Respect for evidence is applied in AMBIT in three ways:

!!(a) Manualization
Firstly, the approach takes seriously the need for [[Manualization]].  The AMBIT approach is manualized, using highly innovative web-based documentation (see [[User Guide]]), in recognition of the fact that evidence points to improved outcomes for interventions that are manualized, as opposed to 'reactive' or eclectic approaches (Huey et al, 2000), and where fidelity to the model is high.

!!(b) Evidence-based interventions 
Wherever possible we use [[Working in Multiple Domains]] to deliver interventions which are ''evidence-based'', or adaptations of these to fit them for the non-standard settings they are delivered in.  The AIM Formembedded in this manual will generate a range of AIM suggested interventions from the scorings you enter into it about a particular young person, and there is advice on how to think about Which Intervention When (please note this function of the manual is currently under development).

It is accepted that in some such settings (home-based, street-level), there is not yet sufficient trial evidence to assert effectiveness, so that the phrase 'evidence-oriented' is rather more fitting at this early stage than the rather over-used 'evidence-based'. 

As regards the evidence for home-based, multimodal, assertive models of practice, we acknowledge the huge role played by MST (Multisystemic Therapy) in developing a rich literature on this area of work.  It is helpful to consider some of the differences between MST and AMBIT.

!!(c) Regular, systematic Outcomes measurement
See [[Evaluating outcomes|Outcome Measures]].

!!And finally...
Making sense of evidence is helped by an understanding of the skills of critical appraisal - how to read a scientific paper, so as to understand its reliability and validity, and in particular its relevance to one's own clinical practice.  We don't explain these skills here, but why not sing about it... with thanks to James ~McCormack (and Prof Peter Fonagy who pointed this little gem out):

<html><object width="420" height="315"><param name="movie" value="//www.youtube.com/v/QUW0Q8tXVUc?hl=en_GB&amp;version=3&amp;rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="//www.youtube.com/v/QUW0Q8tXVUc?hl=en_GB&amp;version=3&amp;rel=0" type="application/x-shockwave-flash" width="420" height="315" allowscriptaccess="always" allowfullscreen="true"></embed></object></html>
At the end of the [[Thinking Together]] exercise, there must be a return to the overarching Task...

!!START Boundaries.
In this respect is is helpful to remember the ''START boundaries'' of around any task (these are described at keeping your bearings).  

*Space
*Time
*Authority
*Responsibility
*Task

!!The Task in Thinking Together	
All Thinking Together has a task that relates back to the search for some kind of product (a ''decision'', an ''intervention'', an ''understanding'', etc) that ''offers promise as help'' for the client/family.

!!The previous stages are a DELIBERATE SUSPENSION of this task-focus..

To enable what we refer to as //"the curious exploratory play of ideas..."//. So to end the exercise there must be a return to this purpose. 
 

!!If no progress is made...

If a decision cannot be made, or an understanding is not reached, etc, then the practitioners will decide if the risk assessment is at a level that leaves them "quorate" (see reflective quorum) to make decisions about postponing this decision, or if widening the Quorum is required right now, and who else might be required to advance the management of this problem.  They may need to resort to formal [[Supervisory Structures]] and/or emergency procedures, or they may be able to agree a process to carry forwards their thinking to, say, one of the next team meetings.
!! Things to consider – 
* Hygiene procedures/different procedures across different schools
* What type of mask to wear
* Travelling to Brent
* Our own anxieties around returning to work 

!!! Hygiene procedures – 
* Each school has a different risk assessment and different procedures
* Our AFC risk assessment will ask whether each school has considered different risks
* If we bring our own equipment/resources we should bring wipes to sanitise afterwards

!!! Different types of mask to wear – 
* Visors might be better to create a rapport with the child
* Face masks with a clear mouthpiece to show our mouth expressions

!!! Travelling to Brent – 
* Best to take cars if possible
* Possibility of taking a bike on the tube to get to Brent and then cycling around Brent
* We can type our notes on our phone in between sessions and it links with our notes on our emails 
* Possibility of getting screen protectors so that public cannot see our laptops whilst working in public place such as café
* We may need to rearrange our schedules to fit in a whole day or Brent work to avoid having to go in on two days
<center>{{Stance-Scaffolding.JPG}}</center>

''Pictured above:'' the repair of the famous Mostar bridge that was all but destroyed in the war that accompanied the break-up of former Yugoslavia.

Scaffolding existing relationships is one of the [[Core Features of AMBIT]].  

There is constant effort to support, or add scaffolding to, key //existing relationships//:

* The young person's relationship to him or herself
* Relationships within the family
* Relationships between the family and other professionals in the network
* Relationships with key professionals in the network that may be of significant value, or likely to be longer lasting than ours
...rather than a drive necessarily to //replace// these.  Other ways of looking at this include:

* The necessity of identifying any (rudimentary, or frail) Strengths Resiliencies that might easily be overlooked, and building on these
* The need for a practitioner to hold in mind the risk that out of good intentions (to become an important, helpful figure in a young person's life) I might inadvertently undermine a relationship that - although fragile, and perhaps even apparently //unhelpful//, actually holds a greater ambit for influencing positive change over the coming year(s) than I - or my team - do.

Wherever possible, security in existing attachment relationships is supported as being in the long term interests of the young person’s psychological development, even in settings that may conventionally be seen as high risk.

<html><iframe width="480" height="360" src="https://youtube.com/embed/CrJV2SRcLxI?rel=0" frameborder="0" allowfullscreen></iframe></html>

AMBIT stresses the importance of Social Ecology, and Systems Theory, and supports an unwillingness to be drawn into Teleological thinking that attempts automatically to //replace// existing supportive structures.  The focus in AMBIT is always on //scaffolding what is there//, so that fundamental structures (relationship to self, to family, close friends, School, Social Services, a Youth worker, etc) can be strengthened in ways more likely to sustain the task of maintaining an integrative context.  

>>"Scaffolding is a major word we use - as in intensive treatment service, our CPNs see themselves as a temporary part of a young persons life and talk of scaffolding other workers in the network."
>>>Ambit-influenced team, 2014

!!But...
This is unless, of course, the level of Safeguarding or Child Protection concerns make this option inevitable - and it is not at all uncommon that a high degree of uncertainty surrounds such questions.

!!Keeping a Balance
Of course scaffolding relationships //that may be far from ideal// requires attention to [[Managing Risk]]...  It is important to work with what is //there//, but not to lose sight of the need for careful governance so that risks are managed and client, worker, and others are protected as much as possible.

...this is why [[Managing Risk]] is the stance item in the [[Core Features of AMBIT]] that is paired with ''Scaffolding existing relationships''. See the AMBIT Wheel.

At times we overbalance into too-rigid protocol-driven (Teleological thinking) risk management interventions that in the long term threaten our relationship with a young person, or their relationship with others who might actually still be in their lives long after we have left the scene. At other times, a diligent worker's compassion and empathy may lead them to over-identify with the young person, or "up-regulate" their tolerance of risk (//"maybe it's just me being too much of a worrier, or getting old and not understanding how young people live these days - who am I to wade in and tell people they are wrong?"//)

!!What to do?
* An approach to assessing what is there: the Multi-Domain Assessment and in particular the narrative history and Strengths Resiliencies are key.
* Social-Ecological Work for building resiliencies in a young person's life
* Mentalization Based Work for work on a young person's relationship to themself and others
* Family Work for work on family relationships that might be improved 


We will include here information on separation anxiety where this overlaps, as school refusal can be closely related to separation anxiety (particularly in younger children) however they are not always related. Sometimes difficulty in separating from parents/carers is a key underlying factor in school refusal.

In teenagers it is less prevalent , but still may be part of the school refusal e.g. when a young person has concerns about leaving their parent at home alone and worries about what may happen if they are away from them at school.

There are a number of factors that can underlie and lead to school refusal (it is a term which captures many difficulties).

For both separation anxiety and school refusal the starting point for any successful intervention would be to develop a good understanding of the different factors which are influencing and maintaining the difficulty (i.e. a formulation of vulnerabilities and risks, maintaining factors and protective factors as well as any specific triggers).

!!!School refusal:

* Separation anxiety in younger children might look like being unable to settle in school, or crying when separating from parents and being unable to. There may also often be stomach aches/ physical symptoms of illness due to separation anxiety that 

* Separation anxiety may come from parents concerns about their children, particularly at the moment and in the current context of coronavirus. Some parents may not be agreeing with school policies or that CYPs should be in school, making it more difficult 

* Difficulty of not wanting to reassure parents too much, as we don't know if there is something wrong with their child

!!!Building a formulation of school refusal...


Child/young person factors



Family system factors



Network factors




School factors



!!!Formulation (try one in pairs)

Which are vulnerability factors?
Which may be maintaining factors?
What might be some triggers
What are strengths we can build on?


!!!Intervention
Some key points to include in your thinking:

*Where might you be able to intervene in the maintaining factors?
*What is realistic? What is within your AMBIT?

*Including the network- reducing dis-integration and coordinating network
*Sharing an understanding with family young person and network, of what may be underlying the refusal (how could you do this?) see [[Egg and Triangle|Broadcasting Intentions]] as one simple tool to share our understanding of simple formulation

*Individual work- finding ways to help the child/young person express difficulties/anxiety around school/separation

*CBT for anxiety (including family)
e.g Cathy Cresswell's book in this manual

*Building a plan for return- Break down into steps and rewards for each step

*Not too much time between steps- better to build up quickly if you can


*involving the family and the network to implement this...how could we do this?
We would want to consider....

Who are secure relationship in school?
who will meet them? where will they go when they arrive? where will they go when they are upset or distressed


!CBT approach

!!What might we do?
*Psychoeducation about anxiety - normalising, providing language and thinking about symptoms. Making sense of their experiences
*Developing a '''TOOL KIT'' to cope
* understanding the anxious thoughts/ thinking traps
*Cognitive restructuring
*Working with parents about their worries

!!How might we do this?
__Psychoeducation__

*drawing selves and their symptoms
*cartoon strips - fight of flight
*talking about the psychical symptom changes 
*NORMALIZE - through vignettes/ stories/ cartoons/ videos
*Get parents to map out how they feel their anxiety 
* Draw an outline around the child and draw where the symptoms are (better with a parent present)
*step by step approach to facing fears

__Tool kit ideas__

*Breathing/ relaxation - bring parents into the work so they can practice it at home (Belly breathing, candle, feathers, bubbles)
*tensing muscles 
*shake up snow-globe and then practicing breathing whilst it settles
*5-4-3-2-1 method recognising via senses (alternatives to this to draw them)

__Anxious thoughts__

*''Thinking traps ''
*Putting the anxious lens/ glasses on, we can take these glasses off and ask for help taking them off. when are you most likely to put your glasses on?
*Name traps as people 'catastrophising Cathy' etc.
*''Thought detective'' - spot when your falling into a thinking trap and is the person who is getting the facts from the thoughts- whats factual, how do you know, whats not and what can I do to help
*''Traffic light thoughts'' - red- unhelpful, amber- neutral, green- helpful

__Cognitive restructuring__

*speaking to the worry as separate from the YP taking them out reshaping them and then putting them back in our heads
*using a machine the thought goes in one end and then goes through the machine and out the other end


__How to encourage at home___

*statements/ reminders around the house 
*reassurances
*achievements - memories 
*reminders that the feelings of anxiety will pass/ its always worse in our head
*Coping statements - linked to characters they connect with (Ninjago)

__What if the parents are also anxious?__

*Utilising our team to support parents
*do a similar CBT structure with parents


__Facing fears __

*Fear ladder- using this to rate how scary these things feel
*use achievable steps 
*utilize the tool box 
*rewards! stickers, praise form mum and dad, their favorite meal, more time on laptop 
*drawing the steps out in a nice way 
*using a graph to map where they are each week. 

[[The Schools Outreach service's wiki|https://manuals.annafreud.org/schools-outreach-service/]] 
!!Introduction
This is a "low impact" form of roleplay - minimal dramatic skills are required.  A paper based version of the exercise is the [[The AMBIT Pro-Gram]], and a more directly clinical tool that addresses the same topic of [[Dis-integration|Addressing Dis-integration]] is the [[Dis-integration Grid]].

A Sculpt is one of the training exercises AMBIT uses, and is designed to help teams to:

* Visualise the large and complex networks around young people
* Take multiple perspectives from the positions of various protagonists (note positioning theory)
* Map out ''Dis-integration'' in physical space that might otherwise be mapped via the [[Dis-integration Grid]]

!!What you need
* Space to move people around, chairs 
!!Example
<html><iframe width="640" height="360" src="//www.youtube.com/embed/jBPDG5byExA" frameborder="0" allowfullscreen></iframe></html>

!!Activity

* Invite one person (or a small group) to describe a clinical scenario from their experience
** Brief history of the case
* Start with the index client, and arrange other figures in ways that reflect their relationship with each other
** Close relationship - sit them close together, looking at each other
** Distant relationship - sit them far apart
** Consider whether you want them seated in a "face-off", or turned away from each other, etc, etc
* Add all members of the immediate family first
** Then extended family, peers, friends
** Then significant others (Pastor, Imam, Coach, etc..)
* Then complete the Professional network
** with each professional, consider the 3 levels of dis-integration that the [[Dis-integration Grid]] uses
*** What is their EXPLANATION for why they are involved: "What's the problem?"
*** What is their intended INTERVENTION: "What to do?"
*** What is their understanding of systemic RESPONSIBILITIES: "Who does what?"

* Once the network is sculpted "as it is", ask key "players" to talk about how it might feel for their character to be in this Positioning Theory.
* Try to ''re-organise the network''
** Re-arrange characters in ways that the main protagonists might start to experience them as more accessible, helpful, etc.
** What are the barriers to such systemic change?
** What are the most glaring ''Dis-integrations'' in the network?

<<list-links "[tag[Self-Esteem]]">>

Where does low self-esteem come from?

*Things out of their control, e.g. safeguarding
*Negative thoughts, e.g. thinking traps

Strategies we could use:

*Worry time
*Thought challenging: pros and cons, identifying thinking traps

* Role model activities and my strengths activities.

Thinking about self-esteem: 

* Self esteem is not separate from other experiences and emotions. It is linked to anxiety and making sense in ourselves. You build self-esteem by how you are perceived by other people and how you interact with other people.

* Social interaction plays a big part in self-esteem. Have you experienced high level of judgement.

* For children to make sense of self esteem is important. For instance the hot cross bun can be helpful to understand thoughts, behaviour and feelings better. Gives more confidence to control your thoughts.

* Strategies:

* Role models: who do you aspire to be and look up to and why. This creates different explicit conversations, like drawing attention to the people the child sees important and what he really values. There is a connection between what the child thinks it is important in people and how to link that to the child.

* Balance thinking: asking yourself questions to thoughts you might have.

* The importance of talking with the child about what can be shared with the network. 'How would it feel to share this with your parents? What bits you do not want me to share?' Suggest parents and teachers to praise their child.

* Do a strengths list and make family members and friends contribute to that list and validate those strengths, achievements, skills and hobbies. 

* A visual representation of who I am to think different aspects of life, think what are you good at in each of the areas, Eg. How is school important and how do you contribute to that. Have areas to prompt them with. Try to stimulate who am I, what is important and what I do in my life. You can have visual prompts to scaffold the conversation.

* Have different values and the young person has to say whether it is important for them or not. It opens up interesting conversations about 'why' they see themselves in certain ways. This also helps to work and construct on their identity.

* Emphasize their negative thoughts is a belief and an opinion, is not a fact. These thoughts may be due to experiences you had but may not be true. Have a shared understanding about why they have certain thoughts.

* Self-compassion: Talk to yourself with kind comments, the same way you would talk towards a friend. This is for young people who are very critical and harsh to themselves.

* Making sense and name it when thinking styles are dominating, what is actually happening through their mind. There can be an internal bully that is very critical and explore how can you respond to that.

* Comic book with different characters.

* Name the internal bully as a different name, like 'starving gremlin' and talk about what makes it take over, makes it bigger and smaller. In a way you separate it. 

* How do you get a teenager who was low self esteem? With teenagers it may be more related to the thoughts and thinking patterns. It is important to acknowledge the down talk and understanding it better. In some cases, when you work with other areas alongside self-esteem things can become better. Being lead by the young person and what is important to them.

* Being able to control the negative thinking and feeling empowered makes a big difference for their self-esteem. They can view situations differently this way. By the time sessions have finished, they may be able to quiet that voice or have tools to manage it better.







#Self-Help Videos
#Self-Help Apps
#Self-Help Books
#Self-Help Websites
We looked at the self-care ideas that had been generated as part of the On My Mind project at the Anna Freud Centre

https://www.annafreud.org/on-my-mind/self-care/

__''Ideas''__

To make some card based resources to look through with young people

Questions that could be asked to explore these:

* Which of these have you tried before?
* Which do you regularly use?
* Which are the most helpful?
* Which haven't you tried, but might like to give a go?
* Are there any that were helpful in the past that it might be worth trying again?

__''ACTION''__

These might be more suitable for an adolescent - are there cards you could make for younger children or an adapted version? Doesn't necessarily have to be called "self-care"; could be "things that make me feel good"
Some key themes for the following 4/5 sessions will include

* Making sense of self-harm.
* What is it like being a practitioner working with self harm?
* What does the evidence tell us about self harm?
* How to set up a context that feels ok to talk about self harm. Explore pros and cons of self harm and ways of talking about self harm with CYP and parents
* Motivational interviewing review
* Making safety plans, assessing risks and involving parents/carers
* DBT and MBT: core ideas that we can apply in our work with CYP

!!!What is self harm and its behaviour?
* Formal definition of self harm is where there is an intention to harm yourself e.g. self injury or self poisoning, for example injury using something sharp, self- poisoning, self burning.

*Although the above definition is more narrow, we need to recognise that there are a very wide range of behaviours which could be understood as 'self harm' or harmful to ourselves. These may also be used in ways to help cope with feelings/situations/experiences e.g. restricting food, drug abuse, very high levels of exercise or work also putting yourself in a risky position, putting yourself around people that can cause high level of risk. 


!!!What feelings does self harm it evoke in us as workers?

* It can evoke a feeling in practitioners that we need to stop this behaviour immediately, feeling responsible for this happening, feeling helpless, feeling that we have to get them to stop.
* It can bring up a lots of powerful feelings in workers, such as sadness and feeling panic, feeling the need for action and wanting a quick fix
* We might feel revulsion
* We might feel 'cut off from it'

These feelings may influence how the worker reacts, for example trying to stop it and moving into 'quick fix' before really understanding well what is 'underneath' the self harm for this CYP and what might be maintaining it for this person

!!! There are some Myths about self harm
(see youtube video from Pooky Knightsmith on self harm myths)
It can be useful to discuss these myths with CYP and parents carers...Could show video and discuss afterwards e.g.
which of these myths have they heard? this can begin conversations about new ways of understanding self harm and curiosity about what may be going on underneath for the CYP.

!!!Some common Myths: 
*The more someone cuts the more severe is their problem
*Just teenagers that self harm
*It's 'fashionable'
*Self harm is about getting attention

!!! Some responses to myths

* Re-framing/challenging idea of attention seeking....Self harm can be related to attachment needs, seeking care/support, seeking something which is not present at the moment or that they need more of... what kind of attention would they most need? have missed out on?

* Shifting people to try to think about What else might be going underneath for this young person instead of focusing only in self-harm? What might influence this behaviour? when does it happen, in which contexts?
* Rephrase/reframe if they use words such as 'naughty' or attention seeking or other labelling terms...how could you re-frame this....e.g. showing need for care? showing distress...showing pain? punishing self....
Sometimes it might be appropriate to explain more generally about what we know about some of the varied reasons for self harm... That it can be very different for different people....it is usually helping someone to manage something (even though that may be hard to understand)

e.g. managing intense emotions, needing to feel real, needing to feel present, using it to block out other very painful experiences or memories/thoughts, using it to punish self, using it to express anger or stuck ness...can be a way of bringing people closer...

Sometimes more general psycho-ed about 'other young people' who self harm and 'some of the reasons i've learned through my work with other CYP' can allow people to think more about their own family/children with a bit more freedom..


This links with....

!!!Talking to parents carers about self harm:

See also youtube video by Pooky Knightsmith on 'what not to do for parents, and can be helpful and not helpful'

* Pooky video: look together with parents and ask what they make of that. It is not telling them what to do, you are proposing to think and evaluate the video together. This shifts you out of the expert position

Some key points and principles to try to help parents/carers to hold in mind:

*Listening and being curious about feelings rather than trying to stop self harm/move to quick fix (this is a completely understandable reaction but may inadvertently cause more upset, feelings of being coerced/intruded upon etc which can increase difficulties
*Caring response, e.g. offer to tend wounds, offer to check in on self harm, need for physical care of these
*balance between managing risks e.g. removing risk items and keeping an eye out/checking in vs becoming overly intrusive and punitive- discuss this balance with parents/carers- it is difficult to get this right, will constantly need to re-adjust  !
*Showing concern and worry but trying to control feelings of anxiety, frustration helplessness , panic etc (Mentalize the parent- they may well feel this !)
*Opportunities and showing openness to talk and listen but not pressure to talk
*An important goal would be to help contain parents' emotions (i.e. mentalize them) so that they are in a better position to mentalize the CYP rather than respond in lots of non MZ ways e.g. who else is supporting parents/carers? who has their rope? who is in 'their back up team?'
* Self harm can and does improve when we can better understand what is underlying it for a CYP and when we can help change those underlying difficulties
*Challenging myths/certainty about self harm (e.g. myths above)


!!!Creating a context in which the young person may feel able to talk about Self Harm

*For some this may happen quickly and feel ok once they see that you the worker are open to talking/thinking about this. For others, even saying that they have intentionally hurt themself may be a huge step and take time (see more on this below around ''warming the context'')



!!Evidence base and treatment approaches

* NICE Guidelines are clear that building a good understanding of the young person's individual context and life - what might be the range if factors for them that relate to the self harm- is central to helping

''This means an individual understanding/formulation of the different factors in someones' life that might contribute- then using this to help guide what might need to change/what is possible and realistic to change/what does the CYP want to be different ?''


!!!What causes self harm?

*explore the many aspects of a YP's life that might cause a YP to show their distress through self harm (our hypotheses): 
**''societal'' pressures
**''cultural'' expectations not being met
**parental/ cultural pressures regarding academic achievement leading to linking this with self-worth - GCSE's, Alevels etc.
**access to help/ support- 
**wider societal stresses - global climate change, BLM
**socially acceptable way to show distress due to the culture and time era
**parental conflict - causing anger or a need to bring people closer to them and care for them.
**''family'' -rejection, trauma, neglect
**learnt behaviour from family - expressing emotions/ help seeking/receiving
**''peers'': bullying, relationship breakdown, isolation, others distress causing distress, competitiveness between peers 
**identity formation - based on the feedback from others determine our self worth - this can be negative or 'positive' but may cause a link to thing aspect of life to their self worth that is unachievable 
*Low self worth/ not liking self
*using self harm to 'bringing yourself back' from disassociation caused by trauma or distress 
*the 'alien self'/ the internal bully - can be developed from a mismatch between personal experience and external response from caregivers 

!!!What do we know about what works/ doesnt work when working with YP who self harm

*''Focusing on the whole person rather than focusing on the self harm''  - it is often better to focus on the things that are happening that feel hard for the YP in their life and understand them. Often this can then reduce self harm in the longer term.
*Can we model how the whole family seek help and talk about their emotions 
*there is no 'one treatment' that is the best way to work - indicates we need to look at this concern holistically
*we need to consider risk - although it may not necessarily mean suicidal but this needs to be checked 
*NICE guidance: person needs consistent support for 3 months

!!!how can we set up a conversation about self harm during an assessment?
*if its in the referral form then its a good opportunity to talk about it explicitly
*would it be alright if i ask you a bit about that?
*''warming the context''- how can we make the person feel more comfortable and safe to talk about difficult things
**broadcasting intentions 
**explicitly stating that the topic might feel a bit uncomfortable.
**invite them to help you understand
**general talk about 'other young people' finding it a bit awkward to talk about self harm etc. there are some people that are a it worried about it so it feels a bit important but that i know lots of people find it a bit difficult. 
**how you you feel if I were to ask you about it? i wonder if there is anything that could make it easier? would it feel ok for you to tell me a bit about it. 
**talking about it is reducing the stigma- it would be more unhelpful to not talk about it or avoid it as this can increase the stigma.
**using psychoeducation - i know there are lots of myths and stigmas around self harm - i have a video about it if we aren't quite ready to talk about it.
**there is something i have been thinking about but m not sure how you might feel about it but i really wanted to have a think with you about ... do you think it would be ok to talk to you about this? 
**if it did become too difficult/ too much how would you let me know? what could we do in the session if it did become too much?
**what might make you fell most safe if we talk about this?
**Ensure that confidentiality and sharing information is covered at the beginning again.

''Interventions for self-harm''

* Build on what you've already learned together about when self-harm has been avoided? What helped? How can we make this part of the plan?

* Grounding - using any sense to bring you back to the hear and now. May be dissociated, in a memory that's very traumatic.
Can use to test in sessions and see what smells they find.
'Feet to floor; bum to chair'
Breathing exercises - relaxation (e.g. breathing in through mouth and out through nose)
Belly-breathing or getting them to trace round their fingers slowly (up and down)
Using a candle - aim to make it 'dance' rather than blow out , or making a feather move on the out breath
Imagery - dampen down fight/ flight. Imagine a safe-space

* Alternative strategies: behind the self-harm; e.g. its role is soothing = hugging instead, or pain = ice instead

* Emotion regulation - using thermometer (what do you notice (thoughts, feelings actions) when you're at each level). You can try and use that in conversations regularly and then use different strategies at different temperature levels
<<list-links "[tag[Separation Anxiety]]">>
''Exploring sequences with parents''

__Broadcasting Intentions__

* Would it be okay to go through in a bit more detail exactly what happened? Just to help me understand it and then it might give us some better ideas about what to try

__Get the detail, like a movie script of who did what when.__

*So how did it start? Take me back to the beginning bit, when everyone was calm
*What happened next?
*At what point did it start becoming difficult
*Can you remember exactly what he/you said?

__Speak in the present tense to help recall__

*So imagine I'm there, what would it have looked like?
*So you're here, he's there...you're getting pretty angry - what happens next?
*How does it end up going from// x // to// y//?

__Get specific__

*When you say he was being disrespectful, what was he doing?

__Get internal processes as well as behaviour__

*"It just shows that he can't just rule the roost" - so was that something you remember thinking at the time? How did it make you feel when you thought that?

''Reviewing sequences with parents''

*Let’s look back through and work out where did it start getting difficult? 
*What were you thinking and feeling at that point? What do you think the other person might have been thinking or feeling?
*Where did the emotional temperature start getting high for you both?
*Which are the points at which it could have gone a bit differently? What could your options have been at that point? 
*Is there anything in here that you would have ideally preferred not to have done/said?
*How would you have wanted this to end? What would you have liked to have seen go differently? Let’s work out how we could have got that to happen. 
*What could have happened differently that might have prevented this situation from happening all together?
*How could this situation have been exited more quickly?

__Broadcasting Intentions__

*Emphasise how helpful it is to have heard the detail – really grateful for the explanation. 
*Clearly its much easier to do this in hindsight; we are slowing this down a lot. 
*There’s things we would want him to do differently too, but we are just going to focus on you here because we’re in this conversation now! I will do the same process with him etc. 

''Intervention areas to hold in mind when reviewing sequences with parents''

*''Re-stating the rules/expectations'' - being clear about what you want to see right now
*Pre-empting difficulties by giving ''reminders/warnings'' - e.g. in 10 minutes it will be time to finish on the Playstation or go to bed
*Reminders about ''rewards/consequences -'' //Remember if you do x [desired behaviour], you will get [reward]". / "Remember if you continue to do x [undesired behaviour], then y will happen [consequence]."//
*Modelling ''staying regulated'' - exit the situation when you need to //We'll come back to this when you're calm"// 

''Practising new skills/strategies with parents''

*Getting ''specific'' about what they might actually say or do
*Some parent will be okay with the idea of roleplay, others less so. (//How do you think you would actually say that? Pretend I'm the YP - how would you put it? Give an example of the kind of thing the parent might say and then ask them to put in their own words//)
*''Re-run the sequence'' with the new part built in - "//So let's go back to the beginning, you come in and see YP doing x - you say your new bit and then I'll be the YP//
*Use you ''MI skills'' to build motivation to change! //How do you think it might pan out if you're able to try that? It's so much easier with hindsight but what would have gone differently last time if you’d been able to take the approach that we’re just talking about? What do you think it might be like to try it for the first few times? What do you think will happen after they’ve seen you do this a few times?//

''Reviewing sequences with YP''

*''Establish that “a difficult thing happened that we would want to avoid happening again” – these things are usually not nice for everyone in some way''
*Link to their goal?
*Link to something psychoeducational about family life? //All families have disagreements sometimes; helpful to talk about ways to manage at those times so that they don’t get out of control; important that people show each other respect in families through their words and behaviour; of course people have disagreements, but we want to work out ways to have these as safely and calmly as possible.//

*''Broadcast your intentions'': want to hear from them about how it went and then work out what people in the situation could have done differently to change the outcome. 
 
''Get their story''

*Ask the young person for the sequence
*“Take me through it step by step. I want all the detail! I might slow you down to ask more questions so that I can check I’m getting it all” 
*Consider if you need to address any feelings of shame that the YP might have about telling you the details
*Use your OARS - empathise and summarise. This is tough – wow, this really did get a bit out of hand! etc.

''Explore motivation to change''

*Try to establish a ''shared understanding'' of whether or not the young person wants to avoid a similar situation happening again and if not, why not. //How did that situation leave you feeling?, How would you have ideally liked it to end?, If these kind of situations were happening a bit less, would that make a difference to you, How would you prefer it to be?''

__Service development:  Day 1 __

 

What does telephone/online support/therapy mean for us, our children young people and their families and the professional networks around them? 

 

''Things to consider ''

*The technology requirements and the pros and cons of online contact  

*Establishing a safe space 

*Safeguarding issues 

*Boundaries and time management (forms of contact and frequency) 

*Non- verbal communication when working online 

''What we need to keep in mind for this type of provision: ''

*We are experiencing this uncertainty too. 

*It is a novel and stressful time for everyone 

 

''The technology requirements and the pros and cons of online contact'' 

Pros: 

*We can still do our work 

*Some CYP may prefer phone support and may be more comfortable being in their home. They might like to show you their rooms, which can help support alliance and they have access to all their things.  

*The CYP does not have to explain to their peers where they go for an hour a week 

*Being online gives them a bit more control over their sessions – whether they want to attend or not in contrast to feeling like they have to attend in school. 

*Not seeing us could make them feel more open to talk - could be beneficial for some CYP 

*Saving time on travel – are we able to support more people/do we have more time to plan? 

*Lockdown is something that everyone is experiencing – this might make our YP feel closer to us and improve therapeutic relationship. 

Cons: 

*It is challenging to build a relationship with someone you have not met in person 

*For some CYP it could make us seem more intimidating 

*There is a lack of body language which can make it difficult to read how they are feeling and how engaged the person is at the other end of the phone. 

*We discuss difficult things, and this can be hard when you can't see the person or know how they are reacting. 

*People may only feel comfortable with phone only- no video is trick due to lack of body language 

*It is easier to miss/cancel a phone call - so CYP more likely to disengage/sporadically engage 

*Technology issues like wifi connections  

*Financial deprivation may cause issues with access to support   

*Anxiety around not being able to see colleagues and how this affects us being able to engage with CYP and families 

*Not being able to use resources to support engagement – like the AIM cards 

*It can be harder to maintain boundaries- we seem like a 'friend' FaceTiming them. 

*It can feel invasive/ intrusive on both sides - we are in their room and they are in ours- are they expecting our call? 

*Collecting outcomes is more difficult as it can feel 'clunky' and not inviting to read out measures over the phone, which can break up the flow.   

''This raises the question - Could we think of a better way to do this? Could we use the Aim card online space? Could YP log in to POD? ''

*There is a lack of sensory experience - not getting this information. 

*Being in same room that you offer support to other and relax/ need to try to create separateness and boundaries  

*The journey allows thinking time 

*We are now in contact with more people around the child- takes up spare time  

 

''Establishing a safe space ''

__Our own safe space -  __

*We may not have confidential space in our own homes 

*Where we are working and what can CYP and families see in the background 

*Where we are having particular conversations (perhaps distressing) and what impact our professional conversations have on our personal spaces 

__For CYP__  

*Some CYP may not have a space away from their family to talk like they would in school 

*We usually automatically offer a safe space by just being in a room with them- no longer able to do this 

*The home can be a safe space for some CYP, but for others it will be a place that is not safe.  

 

__How can we help to establish a safe space within the home?__  

*CYP using earphones so that the therapist is not heard. Other family members putting on headphones so that they cannot hear 

*Make contact when the person exercises outside of the family home 

*It is helpful when parents are encouraging of the space and support the CYP to have a space on their own to do their work 

 

''Safeguarding issues ''

*How are we communicating effectively as professionals whilst we are working remotely – and who holds the safeguarding risk (Social Care) 

*We are holding more risk - school aren't seeing them, SC might not be visiting- CYP may be more vulnerable and we may be the only ones in contact.  

*Most CYP are not getting school contact which makes them harder to reach by professionals - causing worry from schools and other professionals  

*It is harder to identify neglect, self-harm etc. when working online. Seeing them in schools gives a better sense of the person – seeing what they are like in school – low mood, lethargic, behavioural issues etc.  

*Can young people disclose more easily when we are on the telephone? Is it helpful that it is more impersonal? 

*CYP more or less likely to disclose things depending on if they feel their parents can hear them 

*The risk might be from their parents - domestic violence has gone up so likelihood or risk is higher. 

*Protecting ourselves in situations where we feel the YP is at risk - managing our anxiety and stress. 

 

''Boundaries and time management (forms of contact and frequency) ''

*We need to remember to protect ourselves in situations where we feel the YP is at risk. 

*Boundaries harder to hold – we are working in our personal space and could lose some control of the space 

*We are easier to contact as phone working, finding ourselves calling more people more often - school, parents etc. to manage risk 

*Being in higher level of contact could put us in a place of holding more risk. 

*Power balance of maintaining boundaries- This requires us to be stricter/firmer with boundaries and how we communicate this to the families we support in a clear way. 

*CYP can ignore calls or put the phone down, which might feel easier than not physically turning up or leaving 

*Emotional boundaries- we are all experiencing the lock-down and this will affect us all. We are trying to support others when we are trying to support ourselves and loved ones as well. 

__For CYP__ 

*WhatsApp has made the work easier and more accessible. Facetime is only compatible with apple devices. Using the platforms that our young people use is helpful 

*We must maintain professionalism when working via WhatsApp and WhatsApp video to make sure it does not feel too informal/social 

__For us as a team__ 

*We must consider how we dress when we are working from home compared to when we are at work. Do we look like professionals going in to school? How might CYP view us? 

*Receiving messages outside of our working days/hours and holding a boundary around only responding during our working hours – who should they contact when we are not working? 

*How can we maintain a boundary around our work when we are working at home? Doing things such as shutting all our work things away and not checking our phone and laptop outside of working hours. 

*Where we are working and what can CYP and families see in the background 

*Where we are having particular conversations and what impact our professional conversations have on our personal spaces 


__Non-verbal communication when working online __

*A lack of body language makes it difficult to read how CYP are feeling and how engaged the person is at the other end of the phone 

*The option of not having to give eye contact or think about the non-verbal communication might be a positive for some CYP, but could also be a negative as some CYP have never had good eye contact from family etc. 

*Silence in the therapy room is often more possible, but silence over the phone is less possible as you need to make sure they are still there and visa-versa. The silence might feel more awkward. 

*We discuss difficult things, and this can be hard when you can't see the person or know how they are reacting 

*Physical interventions (breathing techniques etc.) could help to break down barriers of online working, making people feel more connected. 

*CYP will have to describe how they were feeling in their body which may be a challenge if they do not have this language. 

 

__Main points to consider after discussion - __ 

*Contracting’ at the beginning how the work will happen – safe space, boundaries, room in the house what the child needs and what the family needs at the same time 

*Risk assessment during COVID-19 requires another level of thinking. Family background and issues of family, such as who might drop into sessions 

*Ensuring we look after and protect ourselves first before thinking about your children and families in order to provide an effective service 

  

__Service Development Day 2__  

Our service when we return to work- what will the CYP and families that we work with want help with once life returns to ‘normal’ following the lock-down? Issues such as loss, trauma, fear and transition to be considered... 

__Overall issues - __

*We might feel uncomfortable about going back to work (commuting, getting into contact with so many others etc.) 

*We hadn't been able to do that much work within schools before the lock-down - may bring about challenges for us 

*It will be another adjustment  

*There could be a spike in referrals 

*How to be emotionally present as professionals when we may be experiencing the same things at the same time as our children and families 

 

''What concerns might arise for CYP and families from lock-down? ''

__CYP__ 

*Exacerbation of existing fears - germs, social anxiety, school/home behaviours, agoraphobia 

*Children may be more aware if family members have experienced the virus – hyper aware of the symptoms 

*Original difficulties (e.g. low mood, challenging behaviour, anxiety) may be highlighted or exacerbated during this period of lock-down - potentially development of coping methods that might be unhelpful to CYP 

*Conflicting ideas from family about returning to normal life/ school  

*Some CYP may be enjoying lockdown without the pressure of the school environment. Teenagers could enjoy that they can sleep later and they are still quite able to keep in contact with all of their friends  

*Some CYP may have got very behind on academic work and will therefore struggle to catch-up to peers if they were already struggling at school 

*CYP and families have become used to technology – will this present more risk for YP in post lockdown because of the communication on technology – differentiation between freedom and not being free and their exposure world – over reliance on technology exacerbating risk 

*May have become quite isolated 

 

__Schools__ 

*What will social distancing look like in schools? 

*There may be a reluctance to go back to school/normal routine from CYP and parents 

*School reluctance could influence parental/school relationships – their age may make a difference to CYP's readiness to go back to school 

*Many of our referrals come from school for school related behaviours- these may not be relevant anymore, but there may also be a surge in these referrals when going back to school (particularly as CYP may be very out of routine or used to individual attention, not having to do schoolwork etc.) 

*Many may have missed milestones at school (GCSE, leaving year six etc.) - loss; dealing with this 

*School staff may need our support more with the transition back- school may not be as confident at managing the behaviours we often get referred into help with - we may get more referrals or need to increase the support offered to school staff 

*School staff themselves may have experienced difficulties during this time and their return to work may be difficult  

*We will be dealing more with bereavement and might need to offer some more systemic support 

*Support schools to support CYP with 'core issues' that we might be able to predict for when others go back - e.g. relationship breakdown, germ phobia etc. 

*School stress over managing CYP all being at the same academic level; there will be an impact of being behind in terms of academic work 

*The new academic year will bring new teachers who may be less able to support CYP who may have previously had lots of understanding and strong relationships with their teachers 

__Friendships __

*Friendships may have been affected/changed during lockdown 

*There may be tensions due to technology reliance during lock-down - CYP may have differing access to technology to communicate 

*Some may have less access to technology so less access to friends, or may not like communicating in this way 

*Potential of cyber-related issues (e.g. cyber-bullying; access to inappropriate content if lack of parental supervision) 

*Separation anxiety, reliance on family instead of friends, and fear of things happening to family or self may cause CYP or even parents to have lots of anxiety about CYP returning to school 

__Parents__ 

*Parental mental health may be affected, which could have a knock-on effect on CYP and their ability to partake in interventions 

*Potential violence in the home exacerbated  

*Potential job loss and economic strain 

 

__Family life __

*Home may have a different meaning to lots of families now, as lots of things from the outside (e.g. work) have now been brought into the home 

*There will be very differing experiences of lock-down for different children and families, such as sharing bedrooms and having a lack of personal space  

*Being ‘stuck’ with your parents – without input and support from school and seeing their friends 

*Losing loved ones suddenly and not being able to conduct family, cultural, religious rituals 

 

''What will the new normal be? ''

For schools? For professionals? 

*There is a lot of uncertainty around the future 

*Questions over whether children should be sent to school, with parents perhaps feeling ambivalent towards governmental guidance 

*Potentially lots of parents being out of work resulting in economic difficulties within families 

*Safeguarding and risk – will there be increase substance misuse in families and in CYP? 

*Social distancing will mean unfamiliar settings for CYP even when things return to ‘normal’ 

*It will be a slow return, learning as we go along; it is hard to plan and prepare for it 

*Will it be a staggered return to school/work? How long will that last? 


''How will our service respond to these needs? ''

*Will we have to be more flexible in terms of eligibility criteria? 

*Will our service model still fit once lockdown is over?  

*How do we support our children and families to re-engage with their local communities? Such as extended families, sports communities, religious communities, music communities  

*How do we make the Brent community more aware of what is available in relation to emotional wellbeing both in relation to WEST and other services 

*Will we see an increase in self-harm?  

*Should we be publicising self-referrals more?  

*We could offer some summer training, pre-empting some of the effects that CV19 may have had on CYP - or we could create resources about this and how we might be able to best respond. 

*We might be positioned to offer groups in schools around these specific issues– so that we can reach a wider number 

*There will be an impact on the whole generation 

*We may have to do more work with social care as they might be overwhelmed once schools return 

*It might be helpful to think about some of the questions around what things will be like when we go back with the CYP we work with now to help involve them and bring the 'external world' back into their 'internal world' 

*Normalising the difficulties/ challenges in balancing wanting to be at home and returning to normal 

*We will need to be more aware of safeguarding issues - problems at home may have been exacerbated during this home, which could have an impact on CYP's own safety/ safety of others at home 

*People may get used to feeling isolated, stressed, anxious – will people therefore be less able to seek help, or will stigma around their mental health reduce and access to services increase? 

 
Topics to think about in this space:

# What happens when risk escalates
# 8-10 session model
# participation group (may need two weeks)
#Data and record keeping - how to make our case notes more concise 
#how can we have conversations with school around providing us a space virtually
# consultations - what we need to gather and what the team needs to know 
#When to close cases if there is lack of engagement?
#how to write a supporting report - proformas etc. 
# working with different cultures engagement etc. 
# Outcomes focus (Monthly - last Wednesday once every month)
# discussion once report has been finished (half an hour after commissioning meeting)
#how we can better connect to Brent and Brent services now we are working from home - consider service directory 
# how we can work from home effectively and promoting staff well-being - considering physical space, practical management, team connectedness etc.
#how we can use the AMBIT framework as a team 

''Good news story at the end of each week ''


 ---
!11/11/2020


!!What is this space?
* Service development: we have discussed outcomes, consultations, participation, POD, referral pathway, good practice and what isn't working.
* We discuss waiting lists and certain cases that need discussion with whole team
* 
!!Do we need this space?
* Thinking together and Service development can feel very similar - need to be clearer in how we use this space. 
* What separates this space from the 'Thinking Together' space?
* We need to have an agenda for each week 

!!How often do we need this space?
* Weekly OR monthly?
* Feels weekly needed as there are things that the team doesn't get time to consider and discuss elsewhere.
!__''Sharing our experience and skills''__

''Purpose'': to work in pairs to reflect on our individual experience and skills in relation to the below areas. It is helpful to develop an explicit awareness of the experience and skills that we each bring, so that we can draw on these in our own practice, but also so that we can skill-share within the team. We want to get a good balance between ''learning from evidence'', as well as ''learning from our experience'' (key to [[Learning at Work in AMBIT]])

''Method'': to map this out in a visual and creative way, as a way of practicing a method that we might be using when working and thinking with CYP (colours, stickers and post-its!)

!__''Areas we reflected on''__

What have we done between us?

__With CYP/settings__

*Working in a school for children with ASC

*Young people affected by CSE

*Enabling Service - working with a YP to support them to access resources in the community e.g. after school clubs; holiday clubs (e.g. young people with additional needs; socially disadvantaged)

* CAMHS work - outreach team, intensive home treatment team

* Adolescent inpatient unit

* Home based support for families where a young person has ASC

__With parents/families__

* Thinking with parents about their relationship with the child to promote his independence and be more socially involved with peers

* Mentalizing with parents to help them understand why their child's behaviour - help them think about what could be driving behaviour. 

* Home-based support for a YP with ASC - helping parents to develop a shared approach to parenting her. 

*Exploring the impact of culture/religion on parenting, their expectations for their child/adolescent, the way that they understand child's needs (i.e. cultural differences in understanding ASC) and how this influences what they think might be helpful to try. 

*How to think with parents about child development

We reflected on the importance on working through parents and seeing them as a resource who can help with the work. Its less helpful to work with CYP in isolation, as it may limit the sustainability of the work. 

__What needs have you helped with?__

*Supporting a young person with an individualised timetable and helping the teachers to individualise the curriculum to suit his needs, build a relationship with him and adapt their approach

* Working with a young person who is withdrawn and showing behaviour problems

* Young people who self-harm - supporting alternative ways of coping

*Child Sexual Exploitation - exploring healthy relationships and relationship skills

__What approaches have you used?__

*Some CBT work
*Parenting work
* Coping skills for self-harm (e.g. soothing boxes, sensory ideas, safe people/places)
* Understanding healthy relationships and reviewing current relationships to see how safe/healthy they are
* Healthy living skills
*Supporting the system around the young person
**Adapting the school environment for a young person with ASC
**Adapting the home environment for a young person with ASC
*Psycho-education
**to help parents to understand what ASC is
** to help parents understand eating disorders

__Using outcome measures__

* Using outcome measures at the beginning and throughout the work to monitor the impact of the work
* Supporting teams to use outcome measures in their practice e.g. focusing on the importance of using outcome measures in a way that promotes learning (i.e. how can the scores inform the work with the young person; how can they help a young people understand themselves better; how can it help the team learn about the impact of it's practice - (e.g. not just seeing them as something that we do because the commissioners want them or using them to prove our impact - rather, we should use them to //better understand// what our impact is
* We have some awareness of what the barriers might be to using outcome measures, which will be helpful in working out ways of using them sustainably in our practice

!__What was it like to do this together?__

*Useful to learn from others -found out some things that I didn't know
* Good practice to share experience in this way - will be important for our work going forward
* Useful to reflect on own experience - struggled at first, but gradually realised I had done more than I had at first thought
* Useful to keep adding to these - learning is constant!
* It is a way to do an assessment with young people and families.
* It is to think about how to carry a child intervention in our work. The application of the approach and a range of tools.
* Working relationships are fundamental: disintegration in networks is kept in mind, keeping links with professionals.
* Keeping in mind the relationships that are maintained by different perspectives of professionals.
* Sometimes when we think about families, we can hypothesise many different things instead of actually thinking what is going on and what we actually need from them.
* It is based on 4 key questions:
1. What is working well for the family from your perspective? Identify strengths. (Eg. the resources does the family hold in the community, family networks). This helps us think what are we actually worried about.
2. Identify what are we worried about? (Draw a house of worries with the child: house of worries, house of hopes, house about what we need help for. These houses encourages the child to think what would their relationships with parents/foster carers be if they were good, visualise them and express the wishes of the child.) This is a simplistic tool to use for assessment with children. Shows the protective factors too.
3. How safe is the child and possible risks (eg. self-harming, exploitation, vulnerability).
4. What needs to happen next? This will inform how the intervention is planned and how professionals will work.
* Make sure we are using a consistent framework when we speak to social care in Brent


It is important for the practitioner to clarify in his or her mind what are the ''SIMPLE BONES'' of the story or problem that they wish for help in thinking about.  In conversation with a colleague about this problem I must ask myself:
>//what information does my colleague need in order to help me decide on actions that will address my concerns?//

There is never time to tell the //whole// story, so the KeyWorker must act as a faithful editor, trying to represent to the best of his ability the account that has been given, but in an abbreviated form.  Over-long "STORYTELLING" is in fact a version of Pretend mode thinking.

There is a balance to be struck between:
#Providing sufficient data and information to convey the richness and complexity of the story, and...
#Applying sufficient discernment to provide practical knowledge rather than an overwhelming "sea of facts." 
!!''Adding links''
We do this to create narrative coherence.  At times, in telling the stories of our clients, we are drawn into //adding// detail - that connects facts and which adds to the overall //coherence// of the narrative.  This is tempting, and to some extent inevitable if we are to help our colleagues form "three dimensional" pictures of young people.  It is important that if we do find ourselves doing this we MARK the fact explicitly: //"Now this is my assumption, rather than anything Jane has directly said to me, but it seems that after her difficult experience with her father she went on to suffer a series of other difficult relationships with older men..."//
!!''The listener is contracted''
The colleague who has //agreed// to hold a conversation that is //''Marked''// as 'Thinking Together' has effectively //contracted// to hold the speaker to these boundaries - of task, time etc.  It may be necessary to point out:

>//"Hey, we need to keep the SIMPLE BONES here... is this is getting into story-telling?//

...Equally the worker giving the account needs to hold onto this shared understanding of the task, so that such prompts are not taken as //criticisms//.   [[Thinking Together]] requires a degree of trust, and allows for conversations that might be seen as blunt, or fast outside of this environment.  (Remember that the theory of [[Mentalization]] places //error// right at the centre of communication; rather than it being something that is a surprising disappointment, it is to be //expected//.)
''In our work with families:''

__General__

*Creating POD logins for YP to complete outcome measures virtually 
*Using online Aim cards/our adapted young child AIM cards in our assessment/ to help us get to know what the CYP would like help with 
*To try and create as confidential a space as possible for the client and ourselves- preferably in a room with the door shut 
*Making work much more visual by creating worksheets / tasks for the session on a visual sheet that you can visually show them.
*Stories / comic strips that describe the concept you’re trying to target, encourage the child and parent to have an active part in writing these. Ensuring they incorporate a special interest.
*Start / end the session with a game -helps to break down a bit of awkwardness with talking over the phone
*Get them to show you something they’ve been doing
*Football kick-up competition. When getting to know a child, each write down 10 questions you want to know about eachother. Then however many kick-ups you do, depends on the number question you ask the other person / answer. 

__Getting feedback__

*Our administrator calls CYP/ families and professionals after we have had a session or conversation to collect an SRS. 
*The SRS can be collected over a phone call or over ~WhatApps/ Text
*Please see below for the document on how we are collecting SRS's over ~WhatsApp/ Text

<<link-doc "Obtaining Feedback via ~WhatsApp (WEST)" "https://drive.google.com/file/d/1p9Vzq9xTGS6fVmraNbm-xbo0L1FBF02t/view?usp=sharing">>

<<link-doc "How to complete an SRS via ~WhatsApp" "https://drive.google.com/file/d/1tqs-nFc1stROGqQysCMwsf3c3GNNh8cP/view?usp=sharing">>


__General phone use__

*For all contact with families to take place via work phones
*sending resources ahead of time over email or ~WhatsApp
*Sending text/~WhatsApp reminders of tasks and session appointments 

__Using ~WhatsApp__

*Whatsapp pictures- for our pictures on our work whats app to be a picture of our work badge. 

__Video calls__

*to ensure that our background is either blurred out or a 'plain'
*To encourage the use of video calls and explain to the client the importance of being able to see each other in helping to communicate better.

__Audio calls__

*To use constant verbal cues such as 'hums' and 'yes' so that we reassure the person we are still on the other end of the phone.
*keep checking the young person can still hear us to ensure connection hasn't dropped.

''To manage our work/ home-life balance:''

*To store our work equipment away from sight when not working
*Having a separate space to work from than you sleep (if possible) and keeping this space organised and tidy
*Having a schedule for each day
*Ensure other people in the house know when your sessions are so you can’t be disturbed
*trying to do distracting things in your evening such as getting outside. 
*Ensuring you still allow yourself breaks in the day
*Keeping in contact with colleagues throughout the day as you would if you were 'in the office' together. 
*Checking in with colleagues
*Reaching out to our team if we are struggling with something
*Being honest with our team if we are feeling overwhelmed (if this feels comfortable)
*schedule in a structured time slot with our loved ones in which we can talk about work and any struggles and then 'putting it to bed' for the day
* Connecting the network together in the absence of the young person's engagement. 
* Not overstepping your role and keep boundaries.
* Really thinking what would be helpful and what will make a difference, learning what is going on and learning what we take from each experience and learning.
* The goals you start with does not mean that they will be achieved but you can still make positive changes, as well as creating relationships in the network, feeling helped and validated makes a big difference.
* What really changes at the end despite goals, if the families feel helped that is still a difference. Acknowledge people's experiences about what happened.
* Engage children virtually online via games to develop a therapeutic relationship.
* Develop shared language, name feelings and helping young people to express themselves.
* 


!!What is this?
This page introduces readers to the the use of ~Peer-to-Peer Supervisory Structures, which is critical for [[Working with Your Team]], one of the [[Core Features of AMBIT]] practice, and in particular this relates to the AMBIT Stance of [[Keyworker well-connected to wider team]].
 
A key point is that //this is work that involves all the protagonists (our clients, and ourselves as workers) in anxious worrying situations.//

AMBIT trainings spend some time emphasising that ''if this work does NOT make you worried at times, then you are probably in the wrong job'', as you are out of touch with the reality of what is at stake.

[[Mentalization]], and its fragility in situations of anxiety, is something that underpins __not only__ much of the therapeutic work with //clients//, __but also__ the //relationships between members of an AMBIT team//.  AMBIT-influenced teams place as high a priority on attending to the mentalizing of their professional peers as they do upon stimulating and sustaining mentalizing in their clients.

!!AMBIT Training
The AMBIT training includes a section on learning about Supervisory Structures.

!!Implications
It is important to note that the kind of peer-to-peer supervision described in AMBIT is not //instead of// ordinary clinical formal supervision arrangements (that governance arrangements in the wider system will determine) but are an //additional feature//; defining the //particular culture// of [[Working with Your Team]] that is deliberately and explicitly developed in an AMBIT-influenced service.

!!Live, responsive, accessible supervision
The team is expected to use appropriate technology to support this (mobile phones, telephone conferencing, mobile email, etc), enabling team members to form a reflective Quorum, flexibly, and at short notice.  Seeing this as //part of the daily work// rather than an 'occasional extra' is central to the AMBIT model. 

This core feature is adopted  because of the considerable potential for individual practitioners to end up working in isolation in a community setting with high risk and potentially adversarial clients. In our view, apart from impact on staff morale that such isolation can cause, clinical effectiveness and decision-making also become compromised as practitioners struggle to ‘think’ ([[Mentalize|Mentlization]]) in such high stress contexts.
 
!!A Team around the Worker
We know that [[Mentalization]] is restored in secure relationships.  Access to immediate phone or face-to-face supervision needs to be positively supported by a whole team approach, which recognises the need for such back-up as essential to such services.  ''Doing this work for each other is seen as a CORE part of a worker's role, not an "added (optional) extra"''!

This is something of a shift from the traditional notion of the "team around a child" (which may still have great value, but can drive dis-integrated interventions), towards an arrangement that is about the ''"TEAM AROUND THE WORKER"''

[img[https://lh6.googleusercontent.com/-Q--oDenShgU/UcD32HjdpVI/AAAAAAAAIlk/tGuG_Ps4QbE/s512/AMBITSpokes_B%252BW.JPG]]

!!Implementing and Sustaining this peer-to-peer supervision
Rituals and disciplines within the team define this culture of mutual support, and an important example is the way in which such consultations are marked out and structured (see [[Thinking Together]] and Passed-outwards Discussion.)   
    
The critical component of this process is to enable a conversation to take place between a front line practitioner who is exposed to the full multi-dimensional aspects of the young person’s difficulties and a member of the clinical team who will know the case but who is not emotionally engaged with the family members. The Ripples in a Pond analogy is used to explain this aspect of the practice. Another metaphor that we routinely use to describe this relationship is to describe the front line practitioner as a deep sea diver in which the meta-team is likened to those in the Dive Boat. 
 

!!Transparency
Such supervisory input is provided in a transparent way with the family and young person so that they are aware that the front line practitioner is supported by a wider team (note one of the [[Core Features of AMBIT]] is the principle of  [[Keyworker well-connected to wider team]].

!!Team Meetings 
The availability of this live supervision needs to be complemented by team meetings which provide weekly group-based formal supervision of the clinical team. Such group supervision could be likened to an in-patient ward round in which the weekly treatment goals are reviewed, risks reassessed etc, but with particular attention to ensuring that the meeting addresses the needs of the workers who attend - which is helped by structuring case discussion along the lines of [[Thinking Together]] conversations.

!!Line Management
[[KeyWorker]]s are under the line-management of a lead clinician who is responsible for ensuring that appropriate supervision is provided for each activity that he or she undertakes.  A psychiatrist provides medical assessments, and is responsible for the prescribing of medication and any other physical treatment. 

!!The Meta Team
The Meta-team may in some situations be those [[KeyWorker]]s who are not working directly with a particular young person, but who make themselves available to the Keyworker who is "in the thick of it" via a Reflective Quorum.  More formally, the Meta Team refers to the team of specialist professionals who may not sit directly //within// the team, as keyworkers with caseloads themselves, but who have given consent to an agreed level of consultation to the team about areas requiring more specific expertise. 
 

!!Experts By Experience
The team should aim to recruit over time a panel of experts by experience, who can be consulted on problems of managing the difficulties of young people and their families. 
Always remain mindful of how difficult the situation is.
Consider drawing on wider networks 
Consider structuring the day. (see [[Supporting families to create routine/structure]]
! What is this page about?

We are writing this page to help us think about how we can support families to create routine and structure, particularly at the current time where people are being asked to stay at home to prevent the spread of coronavirus. Some of these ideas may also apply beyond this period of time. 

! What might this situation be like for families?

We have written a page to summarise our thinking on this - see [[Mentalizing the impact of coronavirus on families]]

We should be mindful of checking out with families how they are doing before approaching any specific pieces of intervention work. 

! What do we mean by routine and structure?

Routine and structure can be generally helpful for children and young people, for a range of reasons. Having a regular routine helps children and young people to know what to expect, which can help them to feel settled and secure. Having a routine which balances attention to the range needs that CYP have, in an age-appropriate way, is important for their well-being. 

Routine and structure does not have to be rigid; some parts of the day might be more similar from one day to the next (e.g. morning routine, mealtimes, bedtime routine etc), but other parts might be more flexible and varied in terms of what happens during them (e.g. what happens during play time, family time, hobbies/activities, exercise, social events on any particular day). 

Some children may enjoy being involved in setting parts of their routine (e.g. what to play, who to spend time with), whereas parents/carers may want to have more ownership over other parts (e.g. getting up routine/bedtimes/mealtimes etc). Naturally, as children get older, the amount of autonomy that they have over parts of their routine may shift in line with their development. This can require an adjustment for parents/carers too, to help ensure that they are retaining appropriate authority alongside this.

! How might focusing on routine/structure help?

At the current time, it might be helpful to think with parents about what the routines/structure look like for their children at the moment. They are likely to be developing and adjusting to new routines and families will have different ideas about what would work for them in their situation. 

If parents are reporting ''struggles to manage children's behaviour'' at this time, routine and structure could be a helpful area to focus on, in order to help create some clear rules and expectations about what the child should be doing at different points during the day and what the rules are within each of those activities. If conflict is occurring between siblings, it could be useful to work out what their respective days look like, in order to try to work out how they can have time apart/time together in a way that is likely to be the most manageable - perhaps working out which parts of the day they are managing well and where points of conflict might be arising. 

If parents are noticing that their ''children are struggling with their emotions'' (e.g. feeling anxious, feeling low, withdrawing), exploring routine and structure could also be a helpful area to explore. For example, it might be relevant because it helps children feel that there is some predictability within their day; to help take their minds off things that might be troubling them; to help encourage them to do activities that might help their mood; to maintain their connections with other people who may be a source of comfort, enjoyment, safety, support or distraction etc. 

This is not exhaustive!

! Exploring routine and structure with families

''Active Planning alert!'' Remember to broadcast your intentions - why are you going to think about this with the family? If it hasn't been raised by them, you will need to introduce the idea, share why you think it could be helpful to do so and check out whether this is ok with them, before launching into anything! 

A helpful starting place is to ''explore'' how things are at the moment in terms of structure/routine:

* What does a typical day look like at the moment?
* Talk me through the day for x (and for other CYP in the house), from when they wake up to when they go to bed?
* What has x been doing during the morning, afternoon, evening?
* What's the arrangements with x's schooling?
*How is that working?
* Which parts of the day feel like they are working well?
* What's helping it to go well?
* Which parts of the day are feeling more difficult?
* What's making it challenging?
* Are there some things that are not happening at the moment that you would like to be seeing more of?
* Are there other things that you'd like to build in?

! Ideas for families to try out
* Creating a 'Timetable'  (potentially together with the CYP that they could decorate and they could display somewhere visible (on wall/ whiteboard) at home. May want to break up the different parts of the day:

** Getting up
** Meal times 
** School/work time 
** Family time (quality time)
**Individual time (free time)

* Having specific times for daily activities that are consistent each day might be helpful.
* Having conversations about what you're going to do the next time

! Specific parts of the day

''The getting up routine:''

It might be helpful to talk through what this part of the day looks like. Are parents wanting the CYP to be up at a certain time or are they happy for them to lie in until they wake (either might be preferable depending on the families' circumstances and the CYP's ages). 

For those that want to keep a regular routine

* Waking up at the same time everyday (a time that is reasonable) 
* keep an alarm, 
* if a child is waking up earlier than the parent would want, are there age appropriate rules they could put in place about staying in their room until a certain time? What could they do to occupy themselves? Pick from a box of toys, read a book etc.  
* Teenagers sleep routines might be affected by the lack of school structure to the day. It might be that its ok for them to sleep in a bit more in the mornings than they might usually (although beware shifting the sleep pattern too far i.e. very late nights and waking up in the afternoon for example)

''School time''

See this page on [[education at home|Education at home]]

''Family Time''

*Being sensitive to the difficult situation and mindful of what is realistic.
*Parents may already feel overwhelmed 
*Avoid phrases like quality time or 'should be doing..'
*encourage YP to ask everyone how they would like to spend time together.
*encouraging YP to problem solve how they would like to interact with parents. - Yp may want some space- need to be considerate of this but also encourage YP to consider mindfulness and problem solving.
*Try not to give the answers/ ideas for activities but rather encourage the person to come up with other options/ solutions.
*Have a set time 
*what is realistic as activities
*Who will be involved
*Take it in turns to pick an activity 

''Free time''
* Think with parents/CYP about ideas of leisure/free time activities that they could do. Again, they could make a poster with ideas on there
* Look on websites for ideas or look out for free streaming activities on social media. Check out local council websites
*Having social media/ Netflix/ TV time

''Boundaries in the house''

Additional consideration might need to be given to helping CYP understand some of the rules/boundaries associated with the new routine

*when x is doing their work, we shouldn't disturb him. This is when you're play time with him is.
* How can we work together? I can help you out with this; you could help me out with that
*Everyone has their own skills to bring
*Encouraging a family ethos - we are going to help each other out; this is a different situation. What kind of things do all the kids think would be helpful for people to do for each other at this time?

''How to help older siblings to help out with younger ones''

*Mentalizing their perspective (e.g. this isn't ideal for anyone; if you do spend a bit of time with younger sib, then it night mean they hassle you less; i know they can be a bit annoying; it would really help  me out as a parent). Making an agreement with the child (if someone plays with him, then it will last this long).

! Reviewing the routine with families

*How is the routine looking, what's going well? Is there anything not going to well? 
*What problem-solving around this could be helpful See resources for problem solving here 
 https://www.talkplus.org.uk/downloads_folder/Problem_Solving.pdf 
* Make sure to click save every time to write a contact.
* Every referral should go on PSS, despite being closed or on hold.
* When we end our interventions, we need to end contact involvement.
* See the 'walk through' that Eleanor sent, written by Nancy.
* Notes have to be brief, such as 'telephonne session with Harry, main themes discussed were his anger in relation to school. Next session is on Friday.'
* If there is a safeguarding issue, you have to put a whole entry of what happened and in detail.
* Be aware that other people in other teams have access to the notes, but the people that have access are people who are involved in the case.
* The notes are reviewed by Ofsted, so be clear when contacts have been made.
* Every session and contact done has to be on Synergy. 
* As soon as you do a session or you have a meeting regarding the young person, you put it directly on Synergy and our record keeping.
* When you signpost a young person, it also has to go on Synergy.
* If text messages is the only contact, then write that text messages is the only type of contact done with the young person.
<a class="tc-float-right">[img width= 400 [complexity pic.jpg]]</a>


!!Networks around clients who have multiple needs

Often, the clients we see are experiencing
multiple problems, in multiple areas of their lives. Mental health problems, histories of abuse & neglect,
substance use, CSE, gang involvement, school
exclusion, physical health problems, poverty, housing
problems, offending behaviour…

These problems interact in multiple directions which makes it difficult to know how best to intervene and in what order.

At times (although not always), the more complex the difficulties, the greater the number of services and professionals that are brought in over time, offering help in different areas of the clients' life. 

Sometimes this can work well. However, this is often not the case. Clients can experience the number of people involved as overwhelming, hard to navigate and make sense of.

''In AMBIT we make the assumption that there will almost always be some kind of helping system in place already in a clients' life. Therefore there is a real risk that when we (and other services) become involved, this further disrupts or undermines existing forms of help.''

!!!Mutiple interventions
An additional level of compexity is added because the various interventions that might be offered to address different areas of life are often drawn from different theories, they may represent different treatment //models// (pharmacological, individual work, family work, cognitive behavioural, psychodynamic, etc etc...), and may be delivered by //different workers// or different //agencies//. 


As professionals, we are then faced with the challenge of working together in these networks, being clear on our roles, and building shared ideas about what we are trying to do, and where we are headed.
However, clinical experience suggests that this ‘team around the client’ may experience difficulties in working together.

!!!Why?

!!!We work in systems where there are:

* separate minds
* different organisational constraints
* different organisational goals
* different theoretical models
* different practical interventions
* different levels of training and different professional groups
* the possibility of misunderstandings...

!!!There may be many different underlying processes at play...

*Conflict (implicit, unrecognised)

*Rivalry

*Policy contradictions

*False beliefs: These are the kinds of 'mythologies' or 'stories' about other agencies in a network that can arise

So ...it is easy for tasks and arrangements ''that are developed out of the best of intentions'' to pull in opposite directions, or inadvertently to undermine each other.

This can be experienced as overwhelming or simply confusing and aversive for clients. It also can raise strong feelings in members of the network all who are trying their best to help.



''In AMBIT we have a way of making sense of this that we call....''

!!Dis-integration

We take the position that no service intends to deliver dis-integrated interventions. But, it is not the job of the client to integrate the various services involved in their lives. We see this as the role that services should take on. 

''In AMBIT we believe that each member of the network has a role to play in this. ''

This is called.......

''Taking Responsibility for Integration''.

//Seeing it as my business to do something helpful about Dis-integration in my professional networks is  central to work in an an AMBIT-influenced team// 

 




Here Liz Cracknell talks about network complexity and Dis-integration

!!! A video on Complexity & Dis-integration
<html><iframe width="640" height="360" src="//www.youtube.com/embed/lRoOYlPwzWo" frameborder="0" allowfullscreen></iframe></html>



!!!What do we do about this?

!!Working in Multiple Domains



When working with complex difficulties it is rarely sufficient to intervene in one area of a clients' life. There are often things happening in multiple parts (domains) of life that contribute to the overall situation. e.g. being out of work, ongoing family conflict, falling out with friends, drug use, thinking style, past trauma etc. We know that for change to happen we need to do more than focus intervention on, for example, thoughts and feelings alone (i.e. one domain).

''We propose there may be more to gain from offering different interventions through a single practitioner who has a good therapeutic relationship (where there is the potential for [[Epistemic Trust|Epistemic Trust]] and learning), rather than a number of professionals offering help simultaneously, increasing the potential for dis-integration and puts emphasis on clients to manage multiple relationships.''



So the AMBIT worker takes a"wide-angled" approach aiming to support or intervene in different areas of someones life.

''We call this........'' [[Working in Multiple Domains]]

At the same time, the AMBIT worker tries to help the client (and network) in integrating the interventions that are offered.

''We call this.....''

''Worker Taking Responsibility for Integration''

Exactly how the worker does this will vary and should depend on what is most useful for the client. For example, it may be the role of the worker is to support, and work through helpful relationships which already exist for the client in their network, rather than attempting to build a new relationship with them. 



Please see [[Addressing Dis-integration|Addressing Dis-integration]] 

This gathers together the tools and practices that AMBIT uses to help workers promote integration and manage dis-integration in their networks.

!!!Workers Taking Responsibility for Integration....

!!!How does it look in practice?

Integration is in the doing as well as the thinking - integration happens between worker and client, and in conversations that take place between worker and teacher, police officer, social worker, etc, etc. 

''Below are some examples'' 

* Developing a shared understanding with a client of the difficulties. Then with their agreement, communicating this understanding with the wider professional network, to help others think about how to approach the work.

*Organising a meeting between key members of the network to find out more about each others roles and understandings of the client.

* A worker helping ''interpret'' to a client information about other parts of the system, what they do and why they are there.

*Leading on from the above, the key worker may physically map out with a client the professional network, helping the client to make sense of the various relationships, how they connect with each other, and their own relationships to each. Please see the  [[AMBIT program|The AMBIT Pro-Gram]] which provides a practical tool to do this.


''Note that the worker attempts to hold and model a mentalizing stance towards other network members at all times.'' We take particular care not to increase dis-integration that may already exist or feed into pre-existing negative experiences the client may have about what can happen between people around them in their life.
 
----

If you would like to read more on the theory and ideas around the '''Domains and levels of dis-integration''' and dis-integrative processes, please see the tag <<tag [[Extended learning]]>>.


Team around the Worker provides an explanation of how AMBIT influenced teams may support and work through a key therapeutic relationship in order to increase the chance that the help offered is useful






!!! What are some of the questions or worries that CYP might have about the pandemic and issues related to it?

...............................



* What is it like as a worker when we are with CYP who are struggling with these issues?


................................



* Mentalizing CYP in the current context during the pandemic

.................................


*What principles are helpful to hold in mind as a worker in these situations?

1. Active Listening and practising a curious mz stance- trying to really understand the worry  (what tools do you have that might help them express these things?)

2. Asking about what the CYP already knows, what things they have learned/been told/heard

3. Asking about whether they have had experiences of these things happening in their lives e.g. do they know of people who have died or been ill...what was this like for them? what did they understand about it?

3. Being honest and as open as we can in answering and when sharing information whilst also balancing this with consideration of the CYP developmental level (what can they make sense of, what would be too much to understand?).

4. Be senisitive to how much they are curious about and what they want to know...what is it that they are asking?

5. Being honest about the things we don't know or the questions we are trying to find out (rather than pretending there is an answer)

6. Doesn't have to be part of a series 'sit down' conversation- could be alongside play/activity, part of a drawing/creative exercise

7. Holding awareness of messages that might promote fear and alarm and protecting children from these


!!!How would you tailor sharing information/talking about these issues in relation to different developmental stages? what tools could you use?

ages 3-6 years?

6-10 years?

11-13 years?

Adolescents?




Focus – Successes/challenges/opportunities
* What do we want to feed back to the commissioner?
* What do we want to learn as a team?

! What has gone well?

!! AMBIT Training
* Learning to think together and apply this in supervision
* Taking in mind the professional network 
* Using our own team spaces better
* Has made us think about the different ways that we work 
* We have learnt to mentalize the network better (e.g. social care frustrations)
* Developing a common language
* Doing more manualising – keep track of our discussions and what we agree and keeps in a consistent place 
* AIM cards 

!! Supervision
* Important to reflect and figure out how to move forward
* We have discussed supervision and what we want to get out of it and we have changed the way we look at supervision and how it is conducted

!! Resilience
* Covid-19 (adjusting to working from home)
* Guy leaving 
* Adapted well to the changes 
* One team member had only just started before lockdown and we have managed to work well as a team and integrate that team member 
* Adaptability
* We adapt our practice with each case and do not stick to the model strictly

!! Connectivity as a team
* Despite having different working days/working from home we are a strong and capable team

!! Laura’s training
* Big success
* Even though we are not doing the work we thought we would, we have adapted the skills we have learnt to work for our team/situation 

!! Groups
* A success and a challenge 

!! Known within other services
* Our service has become known to other members of Brent
* Achieving our aim as a service
* We have managed to do what we set out to do as a service 
* We have managed to engage and give our families a positive experience 
* The complexity Of our cases have been much higher than we thought yet we still have managed to engage most of them
* A lot of families have not engaged well with services in the past but our feedback has shown that families feel that we listen to them, respect them as parents and take their thoughts seriously 
* Covid-19 has allowed for some more flexibility and might allow for more sessions to build up the trust if they are not engaging.
* JP thinks that we would do this anyway even if covid-19 hadn’t happened; we persevere and we do not have such a strict model like CAMHS does 
* We put the family and young person at the centre of the intervention rather than the needs/way the service works – we are flexible and we model the intervention around the child and family 
* We are connecting with their networks so they might feel that we are taking care of them 
 

!! Joint working
* When working on a case together the practitioner has felt supported by the senior practitioner 

!! Schools Forum
* Connecting with schools outreach team and having training on trauma
* Something we found helpful and would like to do again 
 
! Challenges

!! COVID-19
* Working from home has not been an ideal environment for most of us
* Hard to engage the CYP
* Harder to work on referral goals/needs – a lot of them work school based
* CYP being at home has at times increased their risk 
* It has taken us longer to get through cases
* We have not been accessed by so many people because CYP haven’t been at school 
* Work on something not on referral form and then put on hold so that we can do go back to the problems on the referral form when CYP are back at school
* It will bring about more difficulties for school and children
* It will continue to bring about new challenges / we will keep re-adapting
* Schools are more anxious now that they have returned
* There will be more exclusions/behaviour is going to be monitored differently/behaviour policies changing (e.g. leaving your school bubble/coughing on other children)
* Parents will have heightened anxiety about their kids being sent home again (either because of school closure or exclusions)
* We have not got to understand the geography of Brent as we are working from home, do not have such a good understanding of the different areas/schools 
* Motivating ourselves to work at home 
* Can be hard to engage children online, sometimes we have intense periods of work and sometimes little work and hard to motivate 
* Back to back meetings online are very difficult to sit through in one place all day online 

!! Everyone having different working days
* We do not cross over with each other often
* Not having the whole week to talk to other professionals 
* Playing ‘catch up’ for the days we do not work 
* Difficult when discussions happen when one person not there
* Have to squeeze everything in on one day, very mentally draining and exhausting
* When we do go back to working together we need to think about how we manage having meetings together on different days in different buildings – will probably need to move things around 

!! Groups
* It has been a big worry, we have had the referrals for some of the groups since February and it was incredibly difficult to organise them considering the lockdown 

!! Complexity of cases
* Most of our cases are not what we would expect
* Difficult to do standardised work with the types of referrals we get 
* We cannot do the 8 week model when it takes 5 weeks to engage services 

!! A lot of record keeping systems
* Lots of administrative procedures around each case/session
* Lots of different systems – PSS/POD/own record keeping

!! IT systems
* Difficulties with IT systems and doing all this work from home
* Two different emails/calendars – hard to keep track of all of our systems 
 
!! Working for two different organisations
* Two different approaches to returning to work
* Where do we sit between employer/commissioner
* We are not managed from Brent – who is our manager at Brent? To help with the new starters with their equipment etc
* Jyoti needs someone to report to within Brent
* Because we have not been managed by Brent we feel quite disconnected, there should be more support for us to connect with other services that sit under our umbrella of services 

!! The current situation of the world/marches/BLM
* We need to be more aware of the culture of our borough and how recent world events are affecting our clients and work 

! Opportunities 

!! Outcome measures and report
* We should look at the report together as a team once it is in
* We should look at our outcome measures and their improvement 

!! Relationship with CAMHS/Social Care/other services
* To develop relationships with services as service to service not just with individuals 
* Aim to have more consultations rather than just being referred straight to us 
* We need to get to know our partner agencies better and know when to refer on to a better suited service 
* Publicise ourselves more within Early Help services, children centres etc
 
!! Relationships with schools 
* Using the resources from within the schools team with the schools we have relationships with
* Creating stronger relationships with schools 
* We could do more preventative work/early identification
 
!! AFC Schools Team Resources
* There are so many resources from AFC that we do not share enough with schools 
* If we shared our resources/leaflets/training/materials to more groups (Inclusion/schools)

!! Discuss diversity and differences in cultures and bring this into our work more 
* Boys of black Caribbean heritage are one of our target groups but how are we actually helping this group.

!! More group interventions
* 8 session model might be easier to stick to with a group 
* Brent want us to run more groups as part of our enhanced contract
* A lot of parents/cyp feel alone in their difficulties and would benefit from talking to others in the same position (perhaps James can help with the training of this) 
* Social skills groups
* Would need to know what young people want 

!! Involving CYP in the development of our service 
* How can we engage with our CYP more?
* Increase our self-referrals 
* Young Champions in Brent?
* Promote ourselves through schools (newsletters etc) 
* If we had an Instagram/website
* Youth programmes/religious communities 
* Workshops within schools (e.g. during exam time) – commissioner doesn’t want us to do bespoke trainings in schools

!! Group training
* Trauma training
* Reflective fostering training
* Connecting with Schools Outreach Team 
 
!! Scaffolding healthy relationships so families can have smooth transition into other services 
!!A tool for mapping the professional network around a client
This is a paper version of [[Sculpting a Network]].  It is helpful to identify opportunities for [[Scaffolding Existing Relationships]]. [[The AMBIT Pro-Gram: an example]] is an example of the use of the tool.  

!!Video introduction by Peter Fuggle
<html><iframe width="560" height="315" src="https://www.youtube.com/embed/yU3jiKYUJEE" frameborder="0" allowfullscreen></iframe></html>

The AMBIT Pro- gram is the equivalent of a genogram, but for the professional network. The technique is intended to be as simple as possible and can be adapted by a worker to their own style of working. 

The basic idea is to make a drawing or map with the young person in the //centre //of the piece of paper and then to position professionals in the network in relation to the young person. It is the equivalent of a [[sculpt exercise|Sculpting a Network]] on paper. Those positioned closer to the young person have a stronger relationship than those positioned further away.

The aim is to be as inclusive as possible, to include teachers at school, and those who may appear at first sight to be peripheral practitioners.

The diagram can also be used in a developmental sense in that it may highlight previous relationships with professionals which are no longer active. For example, a relationship with a previous social worker that was felt to be helpful may want to be included. A simple method of doing this is to discriminate between live and past relationships by using two different colours to mark these names on the chart. 

The quality of relationships can be indicated - straight lines for positive (thick for more significant ones) and zig-zag lines for negative/conflicted relationships.

!!AMBIT pro-gram, described live by Peter Fuggle during a training for AMBIT Local Facilitators in 2014
<html><iframe width="640" height="360" src="//www.youtube.com/embed/0G_Ub3CsRZw" frameborder="0" allowfullscreen></iframe></html>


!!(Fictional) example:

<center>[img width=600 [Pro-gram picture]]</center> 

Joe is a talented footballer who has stopped playing for his local side since getting into Cannabis use and low level running and dealing to pay for this.  He has been convicted of shoplifting, and has an Order with the Youth Offending Team (YOT) - which he has started to see quite positively because he gets on well with his YOT worker (also a keen footballer).  His low mood had led him to start self injuring (cutting) and he has started to see a therapist about this.  His treatment is overseen by a psychiatrist because of serious threats to kill himself or others by setting fires that were made around the time of his initial arrest.  

Although he initially got on quite well with his therapist, and was positive about this, he has recently been missing appointments, and appears to be drifting away from her.  During the creation of the Pro-gram he reveals that he thinks that the Therapist and YOT worker "don't get on at all well" - though it is unclear how he has decided this, and whether they even actually know each other at all.

He has remained on good terms with his old football coach, but is still not going back to football.

A family support worker is dismissed as "working for my Mum" by Joe, and he denies ay connection between this man and anyone else in his network - describing him in neutral, disconnected terms.

He is annoyed at the fact that his Social Worker has changed recently - his previous one had been "funny" and he had felt that she "really got on with me".  He compares his present one negatively with this.

He is entrenched in his aggressively negative views about the Police who he sees as "out to get me" and (perhaps because he first met her in a Police cell) he is equally negative about his psychiatrist, who he sees as "working for the Police".


It is extremely important to feedback to children, young people and parents what you have learnt form the questionnaires that they have filled in. ''No client should be asked to complete a questionnaire that is not fed back to them.'' Feeding back results from questionnaires will need to be practiced as part of the skills sessions. 
A number of principles need to be borne in mind. 
#recognise the effort that has gone in to doing the questionnaire (//e.g. 'Thanks for doing this. People often find doing these forms a bit of a faff.'//)
#scores form questionnaires are not 'facts' but are a helpful way of making sense of complicated matters. 
#clients should be encouraged to give their views about what you have understood from the questionnaire ('//e.g. it seems that you get most anxious meeting people and less anxious about things like travel or homework. Does this seem right to you?//)
#balance feedback between strengths and difficulties. (//e.g. some people get really bothered about going to bed but this seems to be no problem for you. However, I can see that getting ready for school is a real struggle for you.//)
#be clear(and empathic!) when there is understandable room for concern.(//e.g.'I can see that when you get low, this is not just being a bit miserable but is much more than that. This seems ot be something that i really impacting on your life.'//) 
#always check at the end of your feedback if they have questions about what you have discussed with them. 
!!RATIONALE for a "Mentalizing Stance"

During the assessment and intervention stages of Mentalization-based therapies, specific Mentalizing Therapy Techniques are the primary skills that the therapist needs:

*To flesh out their understanding of the mentalizing capabilities within ones self, or their family
*To assist the client or family members in improving their understanding of mentalizing and the role it plays in all relationships - with family members, with friends, with the self.
*To improve the family members' capacity to mentalize about each other. 
However, ''there is also a "way-of-being-with" our clients'', that is referred to as the ''Mentalizing Stance'', that represents maintaining Mind-mindedness, and which characterises the mentalizing therapist.

There is one of our training exercises to help teams learn about this, at the bottom of the page.

!!The heart of good mentalizing
 
>//Is not so much the capacity to always accurately read one’s own or another’s inner states, but rather a way of approaching relationships that reflects ''an expectation that one’s own thinking and feeling may be enlightened, enriched, and changed by learning about the mental states of other people.'' In this respect, ''mentalizing is as much an attitude as it is a skill'', an attitude which is inquiring and respectful of other people’s mental states, aware of the limits of one’s knowledge of others and reflects a view that understanding the feelings of others is important for maintaining healthy and mutually rewarding relationships.// 
This stance is the ultimate foundation of the approach that the therapist tries to demonstrate and thereby encourage.  Remember that [[Mentalization]] is one of the [[Core Features of AMBIT]], which includes it as the first aspect of its own stance.

!!GENERAL FEATURES of the Mentalizing Stance
A series of general features of a "Mentalizing Stance" have been described, which give a broad flavour of the "way-of-being-with" that the stance represents.  

In addition there are four more specific and practical aspects of worker behaviour that make up the...

!!FOUR "LEGS" OF A MENTALIZING STANCE:
<<image [[Ment_Table_Stance_pic]] width:480 height:320>> 

|''1. ''|The Inquisitive Stance|Consistently modelling the value of mentalizing|
|''2. ''|Holding the Balance|Emphasising //mobile// or //adaptive// qualities|
|''3. ''|Terminating non-mentalizing interactions|Diverse (often playful) methods apply|
|''4. ''|Highlighting and reinforcing Positive Mentalizing|Encouragement of the desired behaviour|

!!Video
The therapist's mentalizing stance - by Liz Cracknell and Dickon Bevington at a training for AMBIT Local Facilitators

<html><iframe width="640" height="360" src="//www.youtube.com/embed/EzSRHiNPHL0" frameborder="0" allowfullscreen></iframe></html>

!!Video - see the first five minutes
A narration to a slide show about the Mentalizing Stance and [[Active Planning]] - the mentalizing stance is covered briefly in the first 5 minutes:

<html><iframe width="560" height="315" src="https://www.youtube.com/embed/GQZ6EIt_aP0?rel=0" frameborder="0" allowfullscreen></iframe></html>

!!Exercise 1: Spot elements of the stance
Client's part played by actor.  
Watch the clip and then in pairs or as a group try to spot the elements of the stance that you notice in this clip.  
Feel free to criticise the therapist, too - the therapist's mentalizing stance has been likened to flying as it is described by the character Buzz Lightyear in the film //Toy Story//: //"it's just falling... with attitude"//.  The critical elements of maintaining inquisitiveness, are to retain awareness of the extent of one's not-knowing, readiness to take responsibility for getting it wrong, and commitment not to get it wrong again in the same way.

<html><object width="480" height="360"><param name="movie" value="//www.youtube.com/v/vhPOC-z-3aw?hl=en_GB&amp;version=3&amp;rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="//www.youtube.com/v/vhPOC-z-3aw?hl=en_GB&amp;version=3&amp;rel=0" type="application/x-shockwave-flash" width="480" height="360" allowscriptaccess="always" allowfullscreen="true"></embed></object></html>

!!Exercise 2: Real time practice
Client's part played by a volunteer.
''Exercise instructions:'' Watch this video, press PAUSE whenever you are directed, and consider these two questions:

#What's the therapist trying to do?
#What would you try next?

<html><iframe width="560" height="315" src="https://www.youtube.com/embed/AIzhoXvbtBQ" frameborder="0" allowfullscreen></iframe></html>
!!Thinking Together in Your Team

[img[https://lh3.googleusercontent.com/-J5GW0cjH2CI/Ubjka0EsxgI/AAAAAAAAIb4/UpMrGfUpVm8/w721-h541-no/ThinkingTogether.jpg]]

This is a key practice relating to the peer-supervision that flows from having a [[Keyworker well-connected to wider team]] and applying [[Active Planning]] in all that we do (both of these are [[Core Features of AMBIT]]).

In terms of [[Active Planning]], Thinking Together is the very shortest-term version of this practice - making a plan (and [[Broadcasting Intentions]] about this) for how to use //this next ten minutes// 'around the water-cooler', or on the phone, in my colleague's car, or in Team Meetings, etc., (see below for "When and Where").

!!''Analogies''
Drawing on the Ripples in a Pond analogy, ''Thinking Together'' is a set of rituals and disciplines that are designed to maximise the amount of ''useful'' information that can be 'Passed-outwards Discussion' from places of greater disturbance towards calmer places or people, where //attuned// and //productive// thinking together (a.k.a. [[Mentalization]]) is more possible.


Mountaineers have worked out over time that having a strictly disciplined approach to the kinds of ritualised call-and-response required to use a rope safely (making absolutely sure you are holding my rope and are tied on when I start to climb) is critical to ensuring safety - especially when they are stressed and tired.  ''Thinking Together'' is a very similar attempt to "get things lined up" in preparation for what is a very common, but often critical operation in the risky word of trying to help very vulnerable young people.

!!''A Video on Thinking Together''

<html><iframe width="560" height="315" src="https://www.youtube.com/embed/nYFxbzL76aI" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></html>

The more that ''accurate'' and ''relevant'' information can be passed-outwards from a very chaotic and overwhelming focus the more it can be digested and acted upon in a timely, effective and therapeutic way.

!!''A "good pass"? Four steps to Thinking Together''
''1.'' ''[[Marking the Task]]'' <br>''2.'' ''[[Stating the Case]]'' <br>''3.'' ''[[Mentalizing the Moment (in Thinking Together)]]'' <br>''4.'' ''[[Return to Purpose]]'' <br><br>What is absolutely critical is that in a team there is a ''shared understanding'' of WHAT these 4 steps are (please have a look at the separate pages for each step) and WHY we choose to use this disciplined way of setting up dialogues to seek help from each other .

!!''When and Where to use it?''
This is for teams to work out as part of the development of their local team culture, but certainly existing AMBIT-influenced teams have reported finding this useful in:

!!!(a) ''1:1 staff conversations''
Here we are trying to replace the "water cooler/kettle chat" or enhancing telephone consultations with workers in the field.

In these situations, if appropriate, the exercise can be done //in front of the young person// with the mobile phone switched to "loudspeaker" - this is very similar to the systemic practice of the "reflecting team", but in addition, we would argue that it is a great way to be [[Broadcasting Intentions]] and to be modelling help-seeking behaviour to the young person. By showing a young person that //"My own ability to think clearly and make the best decisions is affected by my circumstances, and 'phoning a friend' is a helpful thing I do"// I am modelling healthy help-seeking, and there is an implicit invitation for worker and young person to explore later, which is: //"You've seen how I have a bit of a back-up team who help me keep my balance.  Who is in __your__ back-up team, that you could lean on at these kinds of times?  How could we go about getting a few people in place that you could use?"//.  This is a nice way to introduce [[Scaffolding Existing Relationships]].

!!!(b) ''Team Meetings''
There is video of some role-plays in team meetings that shows how this can have a significant impact on how these critical working spaces can be enhanced by a team adopting this approach.

!!''What if my colleague doesn't recognise the concern? Graded assertiveness.''
Thinking together is helpful if a concern (even if poorly defined) is //acknowledged// between parties.  //What about the situation when a worker notices something of concern in their colleague's situation or practice, which they, however, do not seem to recognise?//.
>''Here there is a requirement for'' graded assertiveness in challenging a team member.
This may be necessary to create awareness of the concern, and is certainly a critical aspect of a team's duty to pay attention to [[Managing Risk]] (one of the [[Core Features of AMBIT]].)

!!Role play videos on Thinking Together
* Below are two videos - "thinking apart" and thinking together, that give a simple demonstration of how the technique might be helpful.
* There are also role-played examples of doing it, and not-doing it in team meetings, where the technique can have a helpful impact on the effectiveness and sustainability of meetings that involve case discussion, group supervision, etc.

!!''How not to do it: Thinking Apart''
Here we offer two examples of what might be called ''"Thinking Apart"'' - well-meaning but un-marked and un-boundaried (and ultimately, not very well [[mentalized|Mentalization]]) discussion, that can inadvertently serve to amplify anxiety or shame in the worker:

<html><iframe width="560" height="315" src="https://www.youtube.com/embed/dhVwRaNGmtk" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></html>

<html><iframe width="480" height="360" src="https://www.youtube.com/embed/GMKWnfMN6uo?rel=0" frameborder="0" allowfullscreen></iframe></html>

!!''Thinking Together (OK, it is idealised!)''
<html><iframe width="560" height="315" src="https://www.youtube.com/embed/iUaWgJ2ibiE" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></html>

<html><iframe width="480" height="360" src="https://www.youtube.com/embed/ZeSW-uWFfE0?rel=0" frameborder="0" allowfullscreen></iframe></html>

!!''Exercises''
These steps can be put to work in a more formal exercise - the Passed-outwards Discussion introduces the rationale for making space for mentalizing in discussing high affect situations, and the Thinking Together training exercise helps to practice the day to day routine.


!!''Feedback from AMBIT-influenced teams (2014)''
>>"We are now using thinking together regularly"
>>"Thinking together is used in our peer supervision"
>>"We talk about 'having an AMBIT moment' - meaning thinking together time"
>>"Utilising thinking together in our case discussions has helped team stay more focused and achieve more from team discussions. Shared team language and people feel more supported and cohesive."
>>"The "thinking together" concept has been very influential when used appropriately.  It is very clear in meetings when we have an "AMBIT facilitator" and mark our task compared to meetings that try to follow an agenda, but we miss the mark."
>>"Outside of meeting the team use 'thinking together' frequently and speak v positively of it at review."



* We can bring a referral issue or think about something that has been going on in the team.
* When we are not able to engage young people, think about how much do we keep trying until we decide an end point.
* Consultations: think about how to offer them in this space.
* Checking in on how groups are going and face to face work is going.
* How we support each other and promote help seeking within the team.
* A safe space to expose our vulnerabilities and ask for help from each other in an open way. Create a culture within the team to challenge each other.
* Non judgemental, listening to each other and validate each other's feelings even if we do not understand the other. Validate how each other sees things, and how they see the world.
* Bring ourselves together in the work.
* Think about our cultural differences within the team and also how our team is viewed by the population that we work with. How we acknowledge those differences within the team and the way we work. Think about race, gender and ethnicity. How do we enable ourselves to be accessible to communities.
* Fostering a sense of containment in this space: conversations that we need to in our team. For example, what may not be working well in our team dynamics. 
* We will use the AMBIT frame in terms of mentalizing each other, thinking together, etc.
* Cyra's role as the facilitator.
* Signs and safety and wellbeing: language that social workers use for child protection work and cases. One tool that is used when working with young people is the 3 houses: house of worries, good house and future house. This is helpful to get the child's point of view. We can adopt that model to see as a team what is working well and what we hope for the future. Also to explore what we are worried about in the team, what is working well and what needs to happen and how the future can look like.
* How do we know each other better in a more personal level and bring more of ourselves in the work? For example, at the beginning of our meetings have a catch up, also attend lunch breaks to relate to each other as people. Have a space to manage this ongoing working from home situation.
* Sharing our vulnerabilities more and asking each other for help.
* Catch up with each other 15 minutes before the meeting, we can join at 9:15 am.
* The possibility to do the team meeting together face to face monthly.
* Once a month have an hour to do a fun activity, like a quizz night after work or watching the same movies at the same time.
* Cyra can check with each individual in the team what they are worried about.
* Bring for next thinking together meeting what has been going well and what changes we want to do. Adapt these ideas to the house if we can. Each one to share something with the team that we are worried about and what we need to work on. It can be visual or talk about it. Then we can think about common themes. 

We looked at this document, which outlines the Thrive Framework

https://www.annafreud.org/media/9254/thrive-framework-for-system-change-2019.pdf 

We discussed in more detail the differences between Thriving, Getting Advice and Getting Help. 

The team is set up to see CYP for Getting Advice and Getting Help. We reflected that this might be in the context of a problem with a recent onset, that is mild in nature or it might be that a CYP has an existing difficulty, but currently feels that some Advice or Help that is more focused/specific would help (e.g. a young person who has ongoing struggles with low mood, but wants help specifically to manage the exam period). 

It was helpful to think about understanding this as the purpose of what we are doing. Other members of the team might be more familiar with work that might fall within the Getting More Help or Getting Risk Support. 


A description of the Thrive model can be found here 



https://www.annafreud.org/media/9254/thrive-framework-for-system-change-2019.pdf 

The Targeted Wellbeing Service is listed in a local document as offering services that fit between the Getting Advice and Getting Help quadrants. 

However, some of the wellbeing work undertaken with adolescents may draw on aspects of Risk Support. 

Videos on the Thrive model:
http://implementingthrive.org/implemented/toolkit/toolkit-phase-1/stakeholder-engagement/7-minute-briefings/
!!!Westminster Drug Project

*Two branches to this service, a mental health and wellbeing branch and a drug misuse branch. 
* Work with young people on relationships, drug misuse
* offer a wellbeing service- been running the branch of the service for 
*unlikely to turn people away- often try to find other services to support them.
*Will support young people who are using around risk reduction
* Work with YP with a diagnosis but look to bring in other services 
*1-2 months waiting list- but priority is made based on level of need.
*3 practitioners- psychotherapist, keyworker(goal based, social, health needs), and a practitioners who works with building up the network.
*offers a weekly session mostly over video calls now but usually in the community.
''*to send referral form and check with her if they need to be a user. ''

!!!Early Help
*Family wellbeing centre have taken over from the children's centres
*up to 18 or 25 with SEND
*9 sites

__The support is grouped into 4 sections__

*0-5
*6-11
*12-18
*parents which specific service for dads.

__the different types of support__


*health offer - school nursing, sight and hearing clinics, health visiting etc.
*parenting programme offer
*housing officers
*young carers 
*speech and language - currently only under five
*Brent start
*school admissions
*lots of voluntary sector 
*fun fit families - healthy lifestyle


__Roles at the centres__

*Centre manager - case manging and centre management, developing steering groups,
*early years officer 
*triage officer- identifying families needs
*family support assistant - may run a group based on need.


__How can we support each other to support families?__

*book rooms s and when you need.
*can we offer group work to enhance their 
*to plan a meeting with our team and the centre managers for me to email JP with NC and ST cc'd
*for Nicky to send across the core offer
*''There was significant discussion during the training and afterward regarding our ability to book rooms in these centres (particularly over the summer). This needs further exploration within the team as it was suggested that to use this space it would be helpful for us to provide them with running groups etc. This is to be discussed with JP and brought back to the team.''

!!Kooth
*Online anonymous platform providing mental health support for 11-15yr olds
* three main types of support: professional online support, peer support and wellbeing tools/ resources
*www.kooth.com
*no referral needed and no waiting list
*working with lots of 
*NHS commissioned
*across the whole of London
*online counselling support 
*young people 
*they can text and receive a reply within 24 hours
*Kooth early intervention 
*anonymous service- although some demographic information needed
* able to Journal their mood/ symptoms
* everything is pre-moderated and confidential- nothing goes live if it is triggering or offensive
* trained counselors 
* can speak about face to face services they could access.
*Kooth podcast
*utilise outcome measures - RCADS, Goals etc.
*CBT resources- apps etc.
*case notes 
*contains other services that the practitioner can signpost to. 
*meet the team section - user can request new counsellors
* duty of care - disclosures: Each client was given a ‘traffic light’ tier relating to their level of risk and if the practitioners were concerned for the child’s safety they can ask the child for their personal information/ investigate who they are based on their conversations, location and age and share this information with police/ ambulance services etc.
[img width=100% [alexis-brown-omeaHbEFlN4-unsplash.jpg]]

!!What's here?
This page is a tag for all the pages that either describe or sort the many training exercises developed for teams to practice skills in relation to AMBIT.  

!!Training Exercises Contents
The below contents table categorises the exercises from training. Click on the arrows to view the dropdown lists.

<div class="tc-table-of-contents">
<<toc-selective-expandable 'Training exercises'>>
</div>

!!What training do you or your team actually //need//?
Consider using the [[AMBIT Practice Audit Tool (APrAT)]] to help your team decide what to practice or work on.<br>There is an [[APrAT exercise in, or across, teams]] to structure this.  

!!Additional Training Exercises
*''Advice on planning'' a //local// training event: [[Planning a training event in your team]] 
*''Pre-formed'' suggested team sessions: <<tag [[Suggested Team Training Sessions]]>> 
*List ''Locally-developed sessions:'' <<tag [[Local AMBIT training session plans]]>> 







[img width=100% [ian-dooley-3NCA3tbaE5I-unsplash.jpg
]]


!!The Manual
* Each team who trains in AMBIT gets their own online manual. A list of all the current manuals can be found on the signposting site. The online manual provides teams with all of the core AMBIT content, i.e. everything you need to know to be able to use the AMBIT approach in your work, as well as a space for teams to capture their own practice and what they are continuously learning from their practice.

!!Training Slides
* Teams who train in AMBIT are provided with the training slides from each day of training through the [[Downloadable Resources from Training]] page. The training slides are accessed through the manuals and are added to a teams manual following the training- the links to each day can be found on your homepage and are freely available to download from Google Docs.

!!Training Exercises
* Descriptions of all training exercises can also be found on the manual. 
* Additionally, you can access a list of all the Downloadable Resources from Training, through which you can download the tools in pdf format.

!!Videos
* There are a vast amount of videos on AMBIT, which can be found on the manual. Using the tag <<tag [[Videos]]>> users can access these videos. Any page tagged with 'Videos' will have a video explanation or role play to explain the theory or tool being described. You can also access all videos from YouTube on [[AMBIT.tv|https://www.youtube.com/user/ambitafc/videos]]
//N.B All AMBIT Training Resources are freely available under the [[Creative Commons License|Licensed]].//
 
Below is a list of training themes that is linked to the types of difficulties that they are supporting children, young people and their families with. We can tag pages we create in training with one or more of these 'themes' so that they are easier to find when we want to remind ourselves of the things we have learnt or how we work with specific difficulties. All training pages can be found under the tag 'Wellbeing Training' 
<<list-links "[tag[Training Themes]]">>


See [[Training ideas]] for previously discussed ideas and [[Understanding our training needs]] for an overview of our training needs
Possible ideas for work with adolescents?

* Teaching the [[AIM cards|AIM Cards]] as an assessment method with adolescents

* Building a toolkit around how to use this and how to link interventions with particular cards. 
* Session plans based on commonly chosen cards

!!!Training ideas developed for CWPs/ EMHPs

Carolyn Edwards and colleagues at Kings College London have developed some extremely useful activities that supervisors could do with their EMHP/CWP trainees. 

<<link-pdf "Training Ideas for CWPs/EMHPs" "https://drive.google.com/file/d/1agO7x_uZD6nNvd28y1CKk1yW1Y6aGFyy/view?usp=sharing">>

!!!Training topics 29.04.2020

*Review last week's topic to see what we implemented
*[[Troubleshooting|Troubleshooting]] interventions with parents
*Working with parents to support CYP's emotion regulation

!!!Topics for today 08.04.2020

__Queries__

*''how to respond when YP don't seem bought into the strategies we are suggesting'' - we added our thoughts about this to this page where we are collecting our ideas about how we are applying [[active planning|Active planning stance and collaborative working]] in our work
*''ideas for having more exploratory/getting to know you sessions'' - we added more ideas to the [[engagement during remote working|Engagement in remote working]] page
*''working with looked after children and balancing priorities of different people in the network in relation to the focus of the work, including balancing exploratory and change work''. We started this page about [[working with looked after children|Working with Looked After Children]] and will have some further dialogue within the team. 
*Dilemmas related to [[working with parents |Dilemmas when working with parents]]were also discussed:
**''how to best respond when parents are expressing difficult feelings/thoughts about their children'' (e.g. showing understanding whilst not 'colluding')
**''how to respond when parents are asking you to pass on a message to their child''


!!!Topics for today's training 22.04.20

*Improving self-esteem and confidence
*[[Addressing sleep|Working with sleep difficulties]] (especially with adolescents)
*Support parents to manage challenging behaviour at home (younger children)

6th December 2019

!!Next week ideas

* Understanding the context: What is our stance on wellbeing in this team and what are our core values/ ideas? Describing the difference between mental health conditions and wellbeing. How does this all link into us explaining ourselves.

* Setting up a helping process: How we work within a school context.

* Wider networks: Building rapport with outside networks and how this relates to the referral form. How do we work out who is best to include (e.g. not taking referral form as absolute fact to make assumptions about involved people). 

* Monitoring your work: How do we balance working with goals and outcome measures with ensuring the sessions flow and can be also guided by what the young person/ parents may bring and they want to engage with. 

!!Other training needs

* Behaviour manual training- feels quite complex and feel the need to get specific training in this.
* Sessions with parents- how to have difficult conversations with parents when we are young and don't have children ourselves.

We met together for our first session of Well-being Practitioner training with LT. 

''Today's Purpose'': 

*to reach a shared understanding of what we want to learn about that will help us in our role as Well-being Practitioners
* to share our experience with each other
* to begin working on some of our learning needs

Here is a summary of what we covered. 

[[Introductions exercise|Introductions exercise]]

[[Understanding our training needs|Understanding our training needs]]

[[Sharing our existing strengths and experience|Sharing our existing experience and skills]]

[[Creating resources for young people]]

Started a [[Manualizing list]]

[[Reflections on the first training]]
We covered the following in today's workshop

[[What is the difference between wellbeing and mental health?|What do we think the difference is between well-being and mental health?]]

[[Videos on CYP wellbeing - our reflections|Reflections on wellbeing videos]]

[[On my mind - self-care ideas for CYP|Self-care: On My Mind]]

[[Thrive framework - where is our service positioned?|Thrive framework]]

[[Wellbeing patchwork activity|Wellbeing patchwork]]

[[Reflections on today's workshop|Reflections on training workshop 2]]
{{Open book pic (2).jpg}}

!! Core AMBIT Training Content
These pages cover the CORE aspects of the AMBIT approach and form the basis of the AMBIT manual.
Each of the pages tagged with 'TrainingCore' covers the content to support the topics covered within the [[AMBIT Training|AMBIT Basic Five Day Training]].

All of these pages are tagged here
 <<tag TrainingCore>>


''The AMBIT manual contains many pages in addition to the Core Training pages. These include further explanation of related theory, therapeutic approaches and interventions, evidence and research. These pages are not integral to using or applying the AMBIT approach but are intended to be a resource and a learning aid for workers who would like to read in further depth.''

!!Links to the Core Training pages 

!!!Overview
*[[Mentalization]]
*[[Core Features of AMBIT]]
*[[AMBIT: an overview]]


!!!Client
*[[Working with your CLIENT]]
*[[Scaffolding existing relationships]]
* [[Managing Risk]]
*[[Active Planning]]
* [[AIM Cards]]
* [[Broadcasting Intentions]]
* [[Epistemic Trust]]
* [[Relationship to help]]
* [[The Therapist's Mentalizing Stance]]

!!! Team
* [[Working with your TEAM]]
* [[KeyWorker]]
* [[Keyworker well-connected to wider team]]
* [[SupervisoryStructures]]
* [[Thinking Together]]
* [[Marking the Task]]
* [[Stating the Case]]
* [[Mentalizing the Moment (in Thinking Together)]]
* [[Return to Purpose]]


!!!Network
* [[Working with your NETWORKS]]
* [[Working in multiple domains]]
* [[Taking Responsibility for integration]]
* [[Addressing Dis-integration]]
* [[Dis-integration grid]]
* [[Sculpting a network]]
* [[The AMBIT Pro-Gram]]


!!!Learning

* [[LEARNING at work]]
* [[Respect for Evidence]]
* [[Respect local practice and expertise]]
* [[Manualization]]
* [[Community of Practice]]
* [[Evaluating outcomes]]
* [[Developing learning organisations]]
* [[TiddlyManual]]
* [[Training Resources]]
* [[Training exercises]]

!What do we want to cover?

* Differences between primary and secondary school
* Common worries about going to secondary
* Changes in routine for going to secondary school
* Meeting new people and making new friendships
* Ending primary school
* Moving on from network of support at primary school
* Developmental stage transition -from childhood to adolescence
*What might help to prepare children for transition in current circumstances?
* Motivation to carry on with education when there is a change to routine ("What's the point, I'm not going back?")
*Including parents in transitions planning
*Including schools in transitions planning

! Exploring children's perspectives on primary and secondary school

Important to be aware that children will have a range of perspective about going to secondary and we would want to "hold the balance". This means that we want to think about these issues from as many different perspectives as possible - what are the worries, what are the hopes, what will  be different, what will be the same; what will they miss, what will they look forward to etc. 


!Differences between primary and secondary school

* A new building to get used to
*Different rules
* They will go from being the oldest to being the youngest
*Being around much older children/YP
* New teachers, new subjects
*Increased demands and expectations
*Having to get used to being around different classes and different children.
* Being put in 'sets' according to ability; so more awareness of ability relevant to peers. 
*Maybe less acceptance of difference and more emphasis on "fitting in". Perhaps less tolerance of difference or different needs, a wish not to stand out. 
*More adolescent environment - might be different peer pressures e.g. to respond a certain way to authority; aspirations. 
*Breaktime/playtime might feel different (different ways of spending the time, e.g. games/activities less common and more 'hanging out')
*Might be less dialogue/relationship between home and school
*Might be less awareness of home context at school, because might be less regular contact with parents (e.g. not being picked up from school). 
*Might be more difficult to form relationship/seek out help/have people know what is going on with you because of all the different teachers - might be overwhelming for some.
*More responsibility on CYP to remember to do things
*Harder to develop individualised approaches to support that are consistent across a large number of teachers

!Things that might be positive/opportunities that come from going to secondary school

*Chance to make new friends
*Wider range of subjects or more facilities around some subjects (e.g. music, art, technology)
* More independence (new journey, being able to travel on their own)
*Getting a new phone or more pocket money!
* More clubs, activities, teams to join - more extra-curricular activities. 
*More opportunities to develop existing hobbies - e.g. orchestra, band, sports competitions with other schools
* Some children might want to have a fresh start after primary school
* More choices of what club you go to - more autonomy
*Library!
*Different options in PE
*More trips/projects that are offered

__What might be the same about secondary school?__

Remembering to think with CYP about what won't change; what will feel the same, to help them feel that there is some continuity or sense of familiarity or mastery that they might already have. 

! What worries might children have?

* Being a new place
* Not knowing people
* Making new friends
* Not being able to fit in
* Finding the work hard or not being able to keep up
* Who you will be in a class with
* Will the teachers be nice? Will I like them? Will they like me?
* Puberty and physical differences between peers
* Missing siblings that you might have been at primary school with
* Getting lost in a new building, being late
* Getting detentions
*Forgetting the timetable, forgetting equipment
*Remembering all the equipment and carrying it around!
* Getting bullied
*Nervous about new subjects or having to do new subjects that they don't like
* Worries about specific subjects (e.g. PE - new activities, more competition, ability)
* Worrying about what other people think of you
* Having 'cool' uniform, shoes, bag etc
*Hearing specific rumours or stories about what happens at secondary school 
* Worries about gangs, seeing police at school

! Where might children's worries come from?

*Their own worries
* Worries that their friends might have
* Worries that their parents might have

! Methods for exploring this

* Through questions
*Designing worksheets or a workbook
*Draw a picture of what you think your first day of secondary would look like - can then ask them to tell you the story

! Talking about friendships

*Practical ideas:
* How to make new friends
**Conversation starters
**Finding common interests
**Doing activities together
**Inviting people to do things out of school
**Joining clubs together
**Travelling to and from school with
**Who could they link up with from primary school 
**Asking people to hang out at breaktime
**Asking to sit next to people in lessons

*Exploring with CYP "What makes a good friend?"; "What do your friends like about you?"; "What are your strengths and interests - all about me"

*Exploring what CYP would look for in a friend; draw their ideal friend - what would they talk about, what would they do together etc. 

* Friendly/unfriendly behaviours - what might these look like? What impact might the unfriendly behaviours have? What might alternatives to those things be?

* Bullying - what is it, what does it look like, what can CYP do if they see bullying or experience bullying?

* How to repair friendships/arguments

** exploring different scenarios
** exploring their perspective about what happened 
** helping them to take other people's perspectives

''ADD THE OTHER IDEAS HERE''

* How to keep in touch with friends from primary school

! Ideas

*Helping people in the network to understand them better - through making a booklet or document with a young person to help other people understand them more - i.e. an "all about me" book or "when I'm feeling this way, this is what I find helpful". How can we help the teachers better understand you? How would you like them to react to you? How would you explain it to them if you are feeling more calm?

Could be useful generally as well as for transition


* exploring friendship difficulties through play (e.g. acting out a story with lego figures and making each one have a superpower or strategy that they could talk about that might help in the situation). 
''Children and YP''

*Consider health anxiety, and a place for psychoeducation. Could this present itself in differing ways, e.g. irritability, anger, separation anxiety
*Sessions with children: 'What do you think will be different about school when you go back' 
*Practice skills you need for school at home

''Parents''

*Encourage conversation in the home with families about coronavirus, we could prompt 

''School''

*How can we consider our support to school teams at this time
*Individual schools and children resources
*Encourage information sharing
*Risk assessments of school, can we help create activities that minimise risk and teach skills

*Share managing transitions AFC booklet 



Once agreed an intervention to try out (e.g. a behavioural parenting technique), can be useful to check out some thoughts on what implementing this might be like:

*How manageable does this feel?
*Is there anything you could see that might go wrong?
*How easy/hard do you imagine it will be to stick to this each day?
*What might get in the way?
*What could we do about that?

Setting an expectation that its helpful to try things out, see what happens and refine them is a helpful frame, so support the parent to have a balance of realism and hope about what it might be like to make some changes
We looked at the suggested list of topics together prepared by LT and discussed which felt like priorities, as well as adding new ideas. 

!__''Suggested topics:''__

@@.bubbles-triangle-border.bubbles-left
''Understanding the context:''
What factors influence wellbeing in children and young people? What are the risk and protective factors? What is our stance on wellbeing in this team? What are our core values/ideas? (e.g. about role of family in the work etc)

@@

@@.bubbles-triangle-border.bubbles-left
''Setting up a helping process: ''engagement and relationship building; confidentiality and risk; who to include in the work; using mapping to understand needs; balancing strengths and needs
@@



@@.bubbles-triangle-border.bubbles-left
'' Helping with specific needs:'' working with anxiety, low mood and behaviour

@@


@@.bubbles-triangle-border.bubbles-left
'' Monitoring your work'': using goals, using routine outcome measures

@@

@@.bubbles-triangle-border.bubbles-left
'' Team working:'' What team working skills are important in this work?; Asking for help; 
What is supervision and why is it important?


@@


@@.bubbles-triangle-border.bubbles-left
'' Network skills:'' Who else might be involved with the young people we see?;
What do we know about these workers and what their job might be like?



@@

!__''Our additional ideas''__

<<<.bubbles-oval-thought
''NETWORKS''

How do I find my place in the network of helpers?
How do I work out what other people are helping with?
How do I make sure everyone is on the same page?
<<<

<<<.bubbles-oval-thought
''TEAM''

How do I introduce the service?
How do I introduce myself?
What's group supervision?
What's the difference between line management and supervision?

<<<

<<<.bubbles-oval-thought
''CLIENT''

How do I personalise the work to suit each young person?
How can I be helpful within an 8 session timeframe?
How do I involve the young person's network in the work?
<<<

<<<.bubbles-oval-thought
''LEARNING''

What should I do if the plans I make don't fit the context I'm applying them in?
What's the best way to manage working in lots of different contexts and environments?
<<<
<center> [img width=100% [NAV.PNG]] </center>

!!How to use the manual

This page covers how to navigate this manual and how to get started with developing and editing your teams manual. Navigating the manual is recognised as something that people who are new to it can find difficult: 20 minutes spent exploring and understanding this page will be time well spent!

!!!''[[Wellbeing Service Index]]''
The index lists all of the pages which have been added to the Wellbeing Service manual.

!!!Keeping track of Recent Changes to your manual

*You can find your most recently edited pages under the 'Recent Changes' tab in the right hand side panel. 

!!!What pages have I got opened?
Browsing and opening pages is the best way to explore the manual content but this means you can end up with quite a lot of pages open on your desktop!

* You can see a list of all the pages you currently have open by clicking on the ''Open Pages'' tab on the right hand side panel. 
* You can //skip from open page to open page// by clicking their titles in this list (quicker than scrolling if you are on a laptop or PC).
* If you've got too many pages open to skip around easily, you can //close pages directly from this list// by clicking the little X beside the titles (marked in the picture above.)


!!!''The Search bar''
Use the search bar to find pages that have been added to the manual. 

!!!Tags and links
The software used to support this on-line manual is called tiddlywiki. It has similarities to other wiki software, most notably for Wikipedia. This has enormous flexibility so that material can be linked together in very creative ways. However, for some users, they experience the manual as being hard to find things and to know what is available in the manual.

A ''[[tag |Tags]]'' (a pill-shaped button usually found above the page title) joins together pages to do with a particular topic. You can think of tags as "chapter headings", so there is a tag for Mentalization that links together all the pages related this concept. This is a big topic so it has lots of pages connected together under this tag. Within this big topic, there are tags with a smaller number of pages such as Attachment. Other than thinking of tags as topic/chapter headings, you can think of them as being like a washing line (remember these?) where all the clothes (pages) on the line are strung together - whether or not the line is stretched out or jumbled up, the clothes will stay connected in order. The line is doing what a tag does for pages.


[[Links]] make a specific connection between two individual pages, so that someone can easily explore more detailed content related to the page that they are reading. Using the metaphor of the washing line, a link would connect just //two pieces// of clothing, like a pair of socks! If you click a link, this page will open below the page you were just on.


!!!Printing stuff
*You can print pages from the manual, which is easy (right click on your mouse and select print), and allowed under the terms of the [[Creative Commons License|Licensed]].  Don't expect to be able to just "print the whole thing out", though!

!!!Sharing stuff with colleagues

Create an instant address link ("URL") that you can email or text to colleagues - that will open a copy of the manual //with specific chosen page(s) pre-opened for them to look at//.

* Get the page(s) you want to share opened in your manual.
* Use the crazy looking hashtag just above the search bar to copy the URL of all the current pages you have open to your clipboard:
{{ht.JPG}}

{{URL.JPG}}
* Open your text or email programme, and 'paste' the URL address in, press send and share the link with your colleagues.
* This function means that you can direct your colleagues to specific pages, so if you wanted to share the page that was created at the last team meeting for everyone to review, or something that came up in supervision , etc, you can link them directly to that single page.
* ''This function effectively turns the whole manual into a big filing cabinet of individual shareable worksheets!''

---

!!You may also be interested in:

<<image-link "How to edit your teams manual" "luciano-de-sa-ObwMZBdEWdI-unsplash (1).jpg" "How to edit your teams manual" "200">>


!!!The purpose of this page is to describe the development of the WEST approach to consultation

Firstly, we need to recognise that:

*Consultation can mean different things and be different in different contexts and for different professional groups

* There are overlaps between the terms 'assessment' and 'consultation' e.g. In a consultation we will need to be gathering information and helping to make sense' of the situation. This crosses over with what we do in an assessment

*There are also differences between assessment and consultation that we can define, (although these are not always clear-cut)

The WEST team define the first contact with a client or network member contact as an 'initial assessment' rather than 'consultation' to help clarify some of the differences set out below

Some of the differences that we define in the WEST team between assessment and consultation are:

1. In consultation we are contracting with another professional to use our knowledge/specialism to help them with an issue and to find ways forward ''together'' in a defined/one off piece of contact. This is a bit different to the ongoing gathering of information/iterative approach to assessment where we are responding to new information and building an evolving picture over time...

2. The picture we gain from assessments changes and develops as we learn more over time and this should happen- it is expected. The initial idea/plan from a consultation might change once the assessment develops further

3. We frame consultation as a more discreet piece of contact with another professional (although this could include a number of 'consultation sessions')

4. In a consultation there is more emphasis on how we can work indirectly with a client by supporting the professional that we are consulting to in order to help their work with their client

*It is important to note that both in assessment and consultation we will be thinking about ways forward and resources/strengths of the client/network. This is an area of overlap

*Consultation is different to supervision in that we don't have accountability or power to direct the work of the consultee, where as in supervision, the supervisor will hold some of the responsibility for the work of the supervisee



!!!What are the different scenario's where we might use consultation in WEST?

1.Working with network members to help them use their pre-existing relationship to carry out a piece of intervention work with a client but being guided/supported by us e.g.....

* helping a social worker to plan and carry out conversations with a CYP around loss or bereavement when the SW best placed to carry this out using the existing trust they have in the relationship

*Supporting a teacher to develop and carry out strategies for managing a difficult/challenging behaviour in their classroom

*Supporting another network member to have conversations with a parent about parenting strategies e.g how to use praise and rewards with their child...

2. When a network member/professional approaches the team with a request for help/support , ''or often with a request to take on a referral''...

here we would carry out a consultation to help the professional think about their case, the options, what might be the most helpful ways forward by providing a different perspective from 'the edge of the pond'.

This does not always mean taking on the case. We recognise that this situation can be difficult when a professional comes with lots of 'certainty' about what is needed, (and when the certainty is that WEST should work with this young person). It can feel challenging ion this context when we decide that taking the referral is not appropriate for WEST.







!!!Key aspects to the WEST model of consultation 


(this is not set in stone and can continue to develop over time)

!!!First steps


*We need to 'broadcast' and make explicit our intentions as the person who is setting up the consultation...before starting/when arranging, we would explain how we see the purpose of the consultation, set a time frame and explain our service context (if appropriate)

We can use analogies to help us explain how we see the role of consultation e.g. the ripples in the pond analogy...e.g. where the consultee may be 'in the middle' with the client and the consultant is here to help bring another perspective, to help think through the issues/ think together about next steps as someone who is 'on the bank'.
We may want to explain some ideas around why we don't automatically see young people individually, especially when there are complex networks involved and the difficulties that can happen with lots of workers and low trust( which can result in a CYP or family being overwhelmed, unable to make use of help)

Again, explaining the above can be hard if a referrer is very certain about what they think is needed. It can take confidence to re-position ourselves as being there to help think through options rather than to 'take on the case')

One way to help with the above dilemma is to enquire about what different people in the network think about what the problem is, what should happen and who should do what. In particular it is important to enquire about what the child/family may want. This is a way to help introduce multiple perspectives and open new conversations about the similarities and differences between views about what should happen. We can use the [[Dis-integration Grid|Dis-integration Grid]] to help us structure this conversation and we could share this with the consultee to highlight differences and develop curiosity around these areas.

!!!What is our general stance in a consultation?


*Open and transparent stance
*make an effort to validate and connect with the professionals dilemma (mentalize them)
*Model a curious stance to behaviour
*Enquire about strengths and difficulties 
* Actively enquire about the network around the client, in particular who else is involved and their relationship to the client/family (we can map this using mapping exercise such as the [[PRO-GRAM|The AMBIT Pro-Gram]] from the professionals perspective. Using this kind of mapping exercise we can enquire about where trust may exist between client/family and network members and then begin to think about how we can we use this relationship in the most helpful ways? This includes considering whether there are existing relationships in the network that we can strengthen?

* The consultation is like a  'filtering down of information process'

* Scotty draws on the Signs of Safety and Wellbeing model - strength and solution focussed questioning 

* Begin to establish from the above who any future work will best involve?

*Establish any practical next steps
* summarise back and set out plans



[[Thinking Together|Thinking Together]] provides a framework that we can apply to consultation conversations

It is important to help the consultee 'mark their task' first. Consultee's might feel the need to 'jump into story telling' or sharing details of the problem before having any defined idea of what they need help with. We can explain that in order for us to know how to be helpful it is important first to spend some time understanding what they would like from the conversation... what kind of help they might need (they might not know this at the start without thinking about it)

*We recognise that it can be really hard to 'mark a task' with a consultee who comes with certainty that what they need is for WEST to take the referral on. In this context it is important to spend time first explaining how we see consultation, what we do as a service, how we work, why we don't automatically take referrals, and how the consultation process is designed to help think about what may be the most helpful steps for the client. 


!!! Initial assessments

 (note the difference between 'consultation in WEST and initial assessment as explained above)

!!!Wat to do when the ideas/plan change after the initial assessment

Sometimes after the initial assessment the ideas or goals suggested at this stage change or develop. This can be because we learn more, the context changes or because the CYP wants something different to the request from others in the network.

''How do we manage this?''



*We should expect/predict this (its normal)
*share the changes of plan with the network and explain why/explain thinking behind this
*Discuss with team if we need help in making new plans
*Put CYP view and needs at the centre e.g. when members of the network may be feeling anxious and seem 'certain' about what is needed, shift to focus on what the CYP may want, think, be hoping for...
*We can use [[Active planning|Active Planning]] as out basic stance to balance our ideas/intentions (and those of network) whilst trying also to attune to the CYP






''What makes a helpful link/handover between initial assessment and beginning the EWs work with a case?''

1. Scotty/Jyoti carry out the initial assessment then connect with the EW about what has been learned after the case has been allocated. 

After allocation EW's will send a message to Scotty/Jyoti to arrange a brief talk re the below points.

EW's can also join the weekly referral meeting after they have been allocated a new case to learn more about the case.

In this brief handover meeting it is helpful to discuss:


* What referrers original concern was, what was their expectation (referrer). Any additional information about network 
that is important

*Who to contact first from network  (being put in contact with them if possible to 'bridge' and make introductions)

 *The current formulation- any parts of the formulation that are particularly relevant to beginning the work

*Risk assessment 

*How people have presented in the assessment- and helpful points around how the EW may best position themselves to build relationships and not undermine existing network strengths

*Having a joint handover meeting with Jyoti/Scotty, the EW and the referrer when possible can bridge the relationship and start of work by the EW. This may not be realistic always but it is easier to do this when we are working with people within the organisations in our local network (this is also a helpful way of building relationships in our networks)


* Hearing the young person's voice- what do they want from the work?- we recognise that in many instances young people are not consulted during the initial assessment process. For teenagers who are able to give consent/have capacity we would consider this but we are also aware that beginning an assessment with a YP then handing over to another team member to do their assessment may not be helpful for the CYP

*Sometimes tensions then arise when the CYP has very different ideas to what they want compared to the initial referral question/request/idea from initial assessment

!!!How do we manage this dilemma?

*Broadcast our intentions to the CYP and be open about ideas that others have in the network (see Dis-integration grid as a way to help this). Think with the CYP about what they make of others' ideas for help...what fits? what doesn't? what is similar/different to their ideas/hopes?

*Share the CYP perspectives/hopes with the network

*Hold in mind the [[Active planning stance |Active Planning]]







!!!27.01.2021

* To focus more heavily on goals in the report- % of YP who show improvement over 2.45
* To think with team why collecting time 2 of SDQ/RCADS is more challenging
* To consider shorter outcomes such as ORS and CORS

!!! Discussion with team 03.02.2021

What are the difficulties around collecting outcome measures? - 

* Covid has impacted the ability to collect SDQs and RCADS
* SDQ and RCADS are really long measures
* It feels like we are collecting them for our benefit not theirs
* SDQs are hard to collect when working virtually (in particular from parents and teachers as we are not seeing them - they are being sent out but not returned). The language barrier for some parents may be relevant to this. 
* The CYP do not enjoy completing these measures
* Sometimes the young person will stop engaging after completing only one measure (so no time 2 measures are collected for this reason)
* There are a lot of measures to go through in the first session when you are trying to build a relationship with CYP

Other points to consider - 

* The goals help to keep sessions on track and remind CYP of their goals
* We are getting good scores of improvement for GBOs
* SRS feedback - how can we phrase the questions better and in a way that makes it seem helpful to them?
* Could we use one subscale (which is shorter) as the second time point for RCADS? 
* RCADS is a useful tool to help pull apart difficulties for anxious and low mood CYPs. It is the only symptom measure that we collect.
* CAMHS services give questionnaires to complete with the referral form. 
* We would probably get a lower response rate if we sent to them separately.

!!! 17.02.2021

JP had conversation with Peter F about this - 

* Given that we are collecting goals frequently we are getting good amount of goals
* SDQ score - we usually work around one goal (e.g. emotion) so the score on one domain may have changed, even though the rest of the domains may not change 
* SDQs in lots of different languages
* Could collect for assessment not as part of outcome measures


Discussion - 

* Different cut off ages - RCADS 8+; SDQ 11+
* Social workers use SDQs once a year for LAC children (for LAC reviews)
* LAC with high SDQ scores is one of our vulnerability factors on service spec - if we get  a LAC child we should collect the SDQ 
* We will be re-commissioned based on who we see and what outcome measures we collect 
* Could ask social worker to complete SDQ if a LAC referral has been made (send word doc)

Going forward - 

* ''Should be collecting SDQs for //ALL// LAC children and at two time points'' 
* Should use SDQ/RCADS as an ''//assessment tool//'' for non-LAC CYP
*  Should be collecting parent AND teacher SDQ (and self if applicable)
* We can use SDQ scoring tool (via EJ) 
* We need to record when/why we are not collecting them 
* EJ will send out SDQ when we receive a LAC referral


!!! 03/03/2021
Elly created skeleton of report based on previous reports 

__CH and Elly came together to discuss the parts they would be working on (25.06.2020):__

*Elly to do the demographic info and complexity factors (for main report and virtual school) 
*CH to do POD export and analysis (for main and VS)
*both using the caseload analysis spreadsheet on the shared drive. 
*EJ to complete tabs: demographic info, total complexity factors and the demographic info section of the virtual school tab. 
*CH to complete tabs: session overview, directindirect sessions, consultation, supervision and the session information on the virtual school tab.

CH and Elly to revisit written feedback on the 2nd of June - agree on what should be included in this report - JP SUGGESTS: including as much as possible.


__Questions that have come up:__

*when  doing  case demographics should they be done for all cases seen this term or only new referrals? - all cases seen this term.

__points that have come up__

*need to count WBR as a separate category like direct/ indirect ect. and need to separate this data from the direct and indirect work.
*complexity factors taken form record keeping not referral forms 

__ideas to make the next report smoother__

*For EJ to check over the spreadsheet at the end of the deadline for anomalies and errors.


!!!Q4 2020
*include BBCH break down (and in annual report)

!! New target group reporting - annual report 2020

*The target groups we need to report on are as follows:
**child protection plans 
**LAC and post LAC or care leavers 
**EHCP where Social emotional mental health is identified as a primary need
**at risk of exclusion 
**edge of care (clarify with JP if multiple vulnerabilities i.e. CSE, gang affiliation needs to be reported separately or only as part of those who are at edge of care.
**young carers 
**those excluded from mainstream education or in PRU
* Need a graph showing the break down of referral sources
* then separate graph for each of the main referral sources and the number of children within each target group for each of these sources - e.g. we had 5 referrals from schools and 3 were on the edge of care 2 were at risk of CSE. 
*if a child falls into more than one target group they will be counted 'twice' and this will be stated below the graphs. i.e. 5 out of the 10 referrals received from schools had more than one presenting need/ target group and 5 had 3 or more.
*for each referral source target group reporting explain what/how long we see them for, if we refer on and where to.
* include a table in KPI spreadsheet that has a full break down of the number of children in each target group. 
*need to include CWP criteria, and harrow horizons (Banardos) and compare to how many we are seeing- why they can't be referred on.

''CH and EJ need to develop a simple way to capture this information for next year and for the annual report.''

''Need to consider direct meetings with everyone to go through data''



!Commissioning report meeting 9th Dec 2020 (JP,EJ,CH)
*training info and feedback - in annual report 
!!Termly reports:
*No KPI report in excel - Word document with table, and case study, and some feedback.
*Separate report for VS
*term 1 + Christmas holidays, term2 +Easter, 3 term+summer
*''Friday the 8th January'' - Next data deadline?
!!!Proposed reporting periods:

[img[Reporting deadlines.PNG]]

!!!Term 1 2020-2021
*Deadline Friday 8th January - all data, POD, case studies, feedback and session information
*RS to write case study and use feedback from cases
*VS report - Theresa to write up ''one'' of the groups. 

!!AFC request
*CH to write email to practitioners, when did you start going back to face to face, how may kids support, how many sessions roughly. Breif bullet points about how they have adapted going back to face to face- deadline for Monday. cc elly and JP 
* CH will write up without number for EJ to fill in the numbers.
Protocols were developed for a waiting list on the 19th of August due to the team reaching capacity and practitioners having CYP on hold which are being reviewed in Sept to evaluate the teams capacity.

We need to make contact and offer a consultation to each case before putting them on the waiting list. 
This ensures everyone has had contact within three weeks and that the family know they have been accepted and we are clearer on the aim of the referral.
Elly to make a template for a letter after a consultation has been given stating the date of the consultation what was discussed and when the family will be seen. 

We need to consider risk level and evaluate this during the initial consultation.
We will ''prioritise based on risk'' rather than date of referral.
!!!Background to this discussion

During the second lockdown (winter) we have been thinking about the ongoing stresses and difficulties in working at home and in isolation.

In addition there have been ongoing uncertainties about how we will work going forward (face to face or remote) and this may remain uncertain over time.

As well as this we are at a stage in our teams development when we are  developing our approach and model and there can often be questions and dilemmas about the most helpful ways to work within the parameters of our service.

In this context we thought about how we stay connected and how we seek and offer help to each other when we are feeling anxious or uncertain (this also includes, of course, when we need to talk about our case work)

* in AMBIT we try to recognise explicitly that anxiety or high emotion , stress, worry are an inevitable part of the work we are in.

*The team already use the AMBIT [[Thinking Together|Thinking Together]] model as a structure for offering and seeking help in team meetings and in supervision. Some team members are beginning to use this in more informal situations with each other too.


We talked about how in this current context there are more stressors and changes happening that can impact on us and our ability to mentalize.

''We described situations that can happen in the team where it can feel like we 'end up jumping in the middle of the pond together'....this is a bit like someone having a worry or a dilemma, and others around them join them in the worry or discussion about the concern. The sense is that this can lead to people leaving a conversation feeling more uncertain or sometimes more anxious''

In AMBIT we use the idea of ''ripples in a pond'' to highlight how we can be at different positions in relation to 'the intensity' or the dilemma. That the aim is that for the person who is in the 'middle of the pond' in the 'intensity' that they need to be able to use help (to regain the capacity to mentalize) through connections with others who are stepped further back 'on the bank' 'or at the edge of the ripples'

We discussed ideas today about how we might try to stay on the bank and help people who are in the middle of the pond, particularly if this is challenging and there is a pull to also 'jump in the middle'

!!''Some ideas were:''

*Before having conversations with team mates about potentially emotive issues, checking with them how they would feel about discussing this particular issue...do they feel like they could take a 'position on the bank' if we talk about this or are they in an ok headspace to help me think this through? are they too close to the middle to be able to help me think at the moment without also 'jumping in'

*having the above conversation together kick starts mentalizing in both colleagues i.e. 'how do i feel about this? can i be helpful right now...where am i in relation to this issue?'

*Being honest with each other about this and if it would be difficult , thinking, who else might be closer to the bank on this one that could help me to think it through

*When we do end up in the pond all together naming that this is ok ! this can happen as part of this work. Just naming it has happened is helpful for getting back out !

*Using the thinking together structure explicitly in more informal help seeking conversations as this helps to 'stay om the bank' if you have a defined role as being the helper (so its harder to 'jump in')

Add more ideas as they develop...........




This is the core tag for the Brent Wellbeing Service. Below is a list of all pages tagged with 'Wellbeing Service':


 <div class="tc-table-of-contents">
<<toc-selective-expandable 'Wellbeing Service'>>
</div>
<<list-links "[!is[system]!is[image]sort[]]">>

Two main types of helping roles within the team are: 

#Wellbeing practitioners
#Outreach therapists

*''Wellbeing work'' - ie. because the team has been commissioned to provide a Tier 2 service, positioned in the Thrive model as between Getting advice and Getting Help. 

*''Targeted work ''- i.e. with children and young people who fit into the vulnerable groups that have been identified. They may have a range of needs, which may include difficulties with their emotional wellbeing and mental health. They may not be accepted by CAMHS, perhaps because their difficulties are seen as being related to their context or because they do not easily engage in structured forms of help. 

!!Wellbeing Practitioners 
will be using evidence-based early interventions using a brief guided self-help model. To aid this work the below guided self help [[Intervention Manuals]] can be used. These have been divided into 4 key area with which children/young people and families are likely to be referred:

# Child Anxiety 
# Adolescent Anxiety
# Adolescent Low Mood
# Behaviour Problems

!!Outreach therapists

We adapted this exercise and thought about what a wellbeing patchwork might look like. We worked in pairs to make some patchworks using post-its and stickers.

http://www.safehandsthinkingminds.co.uk/wp-content/uploads/2016/03/Parenting-Patchwork-exercise-worksheet.pdf 

We brainstormed ideas about what we think contributes to children and young people's wellbeing

Create a page to summarise your key ideas:

* Sense of belonging in the community
* Being connected to people who share your culture and interests
* Stability in family
* Friends
* Religion
* Accessing education and getting on ok there
* Being part of clubs/groups
* Freedom and choice - having options and ability to make choices 
* Feeling valued and important - a sense of self-esteem
* Being able to enjoy things - having fun!
* Feeling loved and supported
* Having people you can trust and depend on
* Having a voice
* Being able to develop healthy
* Good physical health
* Good personal hygiene
* Opportunities to develop cognitively
* Being active
* Having interests
* Having hobbies
* Safe environment
* Good living conditions
* Having future goals and aspirations - feeling like you have aims and a purpose and a drive. 
* People valuing you for your skills, characteristics and ideas
* Being around other people
* Being able to use other people for help
* Regular structure and routine
* Rules and boundaries
* Being able to spend time with your parent/family member


Maslow's Hierarchy of Needs



* We need to consider the context for which we know them. And consider how we respond on a case by case basis.
* Some of our team live and work in brent for a long time and so may know many people but might not know them closely. 

''Case discussion''


* If they are closely linked to us i.e we know the family or child very well then the practitioner would have to leave the room/ conversation when the case is being discussed.

''Supervision''

*if the supervisee is working with a case that the supervisor knows then the supervisee would have be reallocated a different supervisor 
These are our ideas from the beginning of the session about what the difference might be between well-being and mental health

* Well-being – you might do things like self-help to improve your wellbeing.
* Mental health – diagnoses such as depression, anxiety. More medicalized?
* Could be a thin line between them – young people might interchangeably use these terms or confuse the two – might think that feeling low occasionally means they are depressed. 
* Everyone has mental health – but people can equate this term with meaning that someone has a mental health condition/disorder. 


* Well-being - Everyday decisions that you make to keep yourself well vs. being unwell and needing to act on it. 
* Physical health analogies – e.g. being diabetic vs. pre-diabetic. 
* Can be stigma around mental health; its less visible, maybe seen as a less legitimate need than physical health?
* Might be differences around how mental health and seeking help is viewed between individuals/groups/cultures/societies – some families might feel shame if a family member is experiencing a difficulty with their mental health. 
* Good communication
* Containment 
*feeling safe, secure and supported
* Knowledge 
* Time 
* Trust in eachother 
* Understanding from senior management what it is like to be in the frontline of what it is like dealing with complicated factors: referral forms / new processes 
* Clear ethos of team, and how we come across to others 
To do our job well we need -

* Supervision (making proper use of supervision)
* Good communication within/between the team
* Voicing when someone is unsure about something
* respect each others different ways of working 
* if we are struggling, to be able/feel able to communicate to our team
* active planning (ensuring we have a task, plan and implement)
* what we are offering is appropriate for who we are working with
* listening to the what the clients want 
* Supportive, encouraging and cohesive team around them 
* Non-judgemental approach within the team
* Everyone in the team is approachable - always someone to talk to
* Trust and confidence in one another and our abilities - we can also recognise our own limitations and vulnerabilities and be able to seek help
* Honesty and the ability to disagree
* Ability to acknowledge one another's perspectives even if we don't agree
* Variety of skills, knowledge and expertise etc.
* Clear systems, processes and protocols in order to feel confident that we're doing what we should be doing in the right way - particularly when the work feels difficult - this was harder at the start but should ease anxieties 
* Good communication skills and listening with each other, as well as families and other professionals in the network
* Representing peoples voice- managing to capture YP and families voices that we support so we can represent this to the wider network
*Ability to work independently, being able to think on your feet when you might not have immediate support from your team due to nature of the work (outreach work).
* The ability to reach out to team members when needed.
How do we learn from evidence? What evidence do we make use of in our work

*CBT based interventions around well-being
** The CWP-IAPT and EMHP manuals have been used and have involved adapting them to our context
* We use evidence gathered from outcome measures to guide our intervention
* Positive, rewarding feelings (both with children, and own knowledge)
* Feelings of hope
* Making a difference
* Safe
* Overwhelming 

* Frustrations 
* Resentment (wanting to do work, barriers in the network)
* Lose hope 
* Holding other peoples stress
Positive - 

* Fulfilling to see when a CYP is improving, making progress and achieving their goals
* Feeling very contained and have space to think about different aspects of work and rely on others in the team
* Seeing of the progression of our service, how we are improving, expanding and adapting, brings pride 


Negative -

* Not knowing how to proceed or feeling stuck with a case, it can bring about negative feelings, but this is the nature of the work 
POSITIVES

* Empowering to empower someone else
* Satisfying to be able to engage YP/ families who are hard to engage
* Achievement 

NEGATIVES

* Anxious about amount of work, how to manage workload and clinical cases, complexity of cases, risk and safeguarding
* Frustration with other professionals in the network, with ourselves and parents/ YP
''-''

*Frustration 
*Helplessness 
*Despair 
*Concern 
*Sadness 
*Anxiety 
*Worry 
''+''

*Hopefulness
*Joy
*Connected/ relatedness / closeness 
*Satisfaction
!! Things to consider
* What happens when the risk increases so that it is not suitable for a practitioner to hold?
* What risk are we identifying? Risk to the young person from external factors or risk of their mental health declining?
* The referrer filling out the referral form - cases of them filling out too much/not enough

!!! In initial consultation stages - 
* Which professionals hold the risk?


!!! Social care involvement
* It is easier to hold a higher risk case when there is a good and involved social worker involved 
* Are there protective factors?
* Social care can withdraw when we start intervention as they feel we are holding the risk 

!!! What things do we need to feel that we are managing the risk
* Social worker/mentor that is also involved in the family to feed back to/communicating work to someone regularly
* Support from the team (e.g. Scott) to discuss the risk
* Having a key professional who has a ''long term ''relationship to the family as they will need to practice and continue the techniques/methods once our work has finished. 

!!! How can we look after the risk once we end
* Involve the family more
* Speak to others in the network (//raise anxiety// within the network)

!!! Moving forward
* Speak to members of our own team more
* Use the network better 
* Brent Family Front Door (Safeguarding)
* If risk to mental health escalates higher than mild to moderate then referral to CAMHS need to be made (CAMHS on duty worker)
* If risk is from external factors they must be escalated via social care

!!! Still to consider - 
* Specific avenues to go down depending on the risk (look at different scenarios)
* Clarify which professionals we need to contact when
* How to have conversations between wellbeing practitioner and someone senior about risk (using AMBIT techniques? Ensuring that the anxiety is recognised)





__''What have we taken from the Wellbeing Practitioner Training?''__

__Feedback 1__

* I have a look in the manual before my sessions and usually find something very helpful I can use from what we've covered
* Sessions have helped me to communicate better with my clients, using the OARS
* Has helped me with technique as well as giving me ways to express my ideas more clearly
* Being more practical in my work
* How to make sense of things with people
* How to have meetings with parents and schools
* Being mindful of pre-contemplation and contemplation stages – rather than trying to persuade or force people. It doesn’t help their ambivalence to do that! Keeping those stages in mind, rather than jumping to quick-fix has been usefful. 
* Working with low mood – has been useful to use the resources. 
* Having ideas of what to say – how to phrase things

__Feedback 2__


* How to run an assessment session, how to structure it in a collaborative way. Using spider diagrams – going well, not going well, what they would like help with. Planning out the questions within those to cover all areas of life. 
* Using AIM cards to generate an initial assessment and overview – found it really helpful with teenagers, especially doing it online, if they can do it on their phone
* “More than one person in a session” – how to structure it with the agenda, so you can interrupt as you need! Being able to broadcast at the beginning how you might approach it, so that people know what to expect.
*Having some sentence starters and prompts so that we have ways to say/do things - e.g. for how to draw people into conversations who are quieter; how to manage the louder people!
* Motivational Interviewing – stages of change were really helpful to work out what stage is the person actually at. Helps to make sense of when I’m stuck – usually I realise I’m trying to do something that’s not matched to their stage. 
** Pros and cons of change tool has been helpful
** OARS – was worried when starting out that I wouldn’t know what to say or respond. Helpful that you don’t have to come up with pearls of wisdom – using reflections and summaries can help keep the conversation going
** Restructuring the sentence – saying the “change talk” bit last when you hear ambivalence - helps to elicit more change talk. 
** Taking up the opposite side of the argument, not just arguing for the change, which doesn’t leave the client with space to do that
** Rolling with resistance – don’t panic! Explore it a bit more
* Practising in roleplays
* Active Planning – being transparent about what I am hoping to get out of the session. In my agenda setting before, might not say WHY and remember to ask them what they wanted to cover. Both your ideas and their ideas. Considering the context of what has happened that week
* Rules – how to come to a shared agreement between parents and teenagers. How to do it in a way that feels ok for the young person – how to help them accept rules by combining psycheducation on rules in a young person friendly way, with inviting their input into designing them. 
* Brain swapping – helping people to mz each other. How about we swap brains and try to work out what the other person might be thinking/feeling?
* How to make it creative and visual – the art of play even in remote work! How to make it interesting to CYP and adapting how many words you use depending on the age. 
* Roleplays – helpful because makes me feel I can do it when we've practised it. 
* Creative and collaborative

__Feedback 3__

* Reminding each other of the things we have covered when we help each other out in our work each week
* Behaviour interventions – being able to work with parents to manage a range of behaviour difficulties. 
* Holding the balance – e.g. through the AIM cards, nice to draw out the strengths and positives to then build on them, not just to focus on problems. 
* Brain House – making the characters, writing stories with younger children to help them develop their emotion regulation skills, printing it out as a story book, sharing it with the network "How you can help me and how I can be encouraged to help myself". 
**Helps the consistency between the two environments. 
* Mapping out the team around the young person – making sure we focus on involving the network from the beginning of the work. This is especially important when we might be worried (or it might be the case) that they don’t have many people around - we might have been more reluctant to do it. 
* Remembering the importance of holding in mind from the outset that we won’t be there forever – part of the task is to find other people in the network to carry on the bits that they found helpful in the work. 
* Traffic lights – how to help parents help the children move between the different zones of regulation
* Self-esteem – using the team around the YP to help him become more aware of his strengths and skills by setting him a homework task to ask different people. 
* CBT hot cross bun – still trying to draw it out on the computer (rather than on paper in person!) to link thoughts, feelings and behaviours together. 
* Helpful balance of theory and how to put it into practice
*Being given feedback about what we are doing well which builds our confidence and also constructive feedback about what we can improve on. 
*Being able to share examples of work and hear examples of work, in terms of getting ideas about what to say or ideas about how to approach things. 


''A wellbeing review is a direct session that takes place instead of a direct intervention''


* We created these as a result of Covid-19, as a way to stay connected with the families that could not complete their work/goals working virtually
*We need to record them on our record keeping
* we need to distinguish the difference on our record keeping/ report writing-on a session by session basis 
!!!What is the purpose?
*Helps to maintain/develop therapeutic relationships 
*Showing to families that we are holding them in mind
*Keeps the context there to ease the transition back into therapeutic work
*To assess/ review if the family are able to access therapeutic work online
*To review/ check with the family what feels right for them in terms of sessions


!!!When would we use these?
*When the child/ family are not able to engage in online working
*If the child attention span is sort/ easily distracted
*If the family are not invested in the online working/ willingness to help facilitate this
* If the child doesn't have access to the internet/ technology 
*If the family living situation makes online sessions difficult 
*If it is a school based problem- this may not be affecting them now, goals cannot be worked towards
*The age of the child is too young to engage in online sessions
*If the difficulties are not acute/ time sensitive
*If they have a very intense school day online
*If the child chooses not to have sessions 

!!Have we used these outside of the COIVD-19 lockdown?
*Check ins over exam seasons 
*Life situations causing breaks in sessions 

!!How are they different from an adapted online session?
*does not focus on goals but we might check in about these
*does not set an agenda 
*No set time/ usually shorter
*do not think about problem solving with families 
*It does not have a structure like an intervention
*It is an organic conversation to catch up with the CYP/parent to check in with them and see how they are
*adapted online session for some children may still not be very long or always very focused - this makes it feel blurred
*they may blur together/ overlap which causes issues when recording what they are.
* if the conversation moved towards a therapeutic conversation around goals/ progress we may record this afterwards as a session
* Difficult relationships with families
* Anxiety
* Networks misunderstanding what we do, not being able to link up networks
* Do we know what we do? Are we specific enough? We may get referrals from people who may be unsure of what they want from us
* Overthinking things / talking over things before they are properly investigated 
* Sometimes CYP do not want to engage
* Hard to proceed with cases we are working with
* Negative feelings that a CYP can provoke in us
* Different points of view within the team (maybe specific to one case or more generally with how we work)
* Not being able to physically be together as a team
* complex cases
* Ambivalence and resistance in YP and families
* Lack of communication between professionals
* Big workload and lack of time
* Can sometimes feel isolated - due to the nature of the work (outreach)
*containing the lives and struggles of the families we see to a working day and then move on with our own lives.
*we might not always have the answer we are expected to have by others- this can be hard to sit with
*We can't always change things immediately the way families and professionals might like us to 
*There is no magic solution! Which is sometimes what people want. Hard to help people realise this.
What does wellbing mean to us?

#emotional and social health and how we can look after this
#Can be affected by environment, social context (our networks) and OUR ACTIONS

Difference to MH?

#spectrum of effect of emotions 
#intensity of this effect
#diagnosis


What you are reading is a WIki Manual.  It is a way of manualizing complex interventions that offers multiple additional functions over paper "how-to-do-it" guides, and a lot more than other web-based treatment manuals that do not use the  highly innovative opensource software called Tiddly Wiki (hence the name.)

The use of wiki manuals has increased enormously over the past years at the [[AFNCCF|Anna Freud National Centre for Children and Families]] and AMBIT is proud to have been the beginning of this.  Here is a brief introduction to how wiki manuals are being used across the centre, and below this is more detail on what they are and how they work.

<html><iframe width="560" height="315" src="https://www.youtube.com/embed/uMWnm3ymDzU" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></html>

!!Brief narration and animation to explain "Why use Wikis?"
By Dickon Bevington
<html><iframe width="480" height="360" src="https://youtube.com/embed/EZ_yHJ1WLTE?rel=0" frameborder="0" allowfullscreen></iframe></html>

Tiddlymanuals take much inspiration from the 'OpenSource' movement in computer software development.  They are freely available (though released under a [[Creative Commons License]]), as the notion of closely guarded, and expensively-marketed, intellectual property in respect of best psychotherapeutic practice seems contradictory in the helping professions.  We acknowledge the support of the [[AFNCCF|Anna Freud National Centre for Children and Families]] and our sponsors in allowing this development.

''Practitioners using Tiddlymanuals remain responsible for their own professional practice.''

~TiddlyManuals take the form of [[Wiki]]s, but they function as completely self-contained and easily editable documents, too; they can be downloaded, saved locally, and run from a USB stick, or a local computer without any access to the internet.
 
See the [[User Guide]] for more details, and go to @tiddlymanuals to see other versions of tiddlymanuals that are available.
A list of topics that we need to consider when working remotely.

For all pages about this topic please see the tag 

!!<center><<tag [[Working Remotely (COVID-19)]]>></center>

'' What online methods will we be using?''

* Try to use a software that allows you to see the YPs face if possible. W can use FaceTime, Whatsapp, Teams. 
* Most YP will have a computer to complete school work. 

''How do we use resources working remotely.''

* Especially if we were planning play based support.
*How to make sure YP have enough help to complete them, 
*What are the best resources to send
*Need to consider: wifi, printing, IT access
*we could send pictures or screen shots of resources

 ''How to practically support younger children online.''

''Working with Adolescents''- confidentiality, managing what can we share, what is being shared due to overhearing.

''Helping families share a space and the conflict this might bring''

''What is an appropriate intervention when working remotely.''

''How do we do an initial assessment, what can we use instead of aim cards''

''Conducting risk assessments remotely''

*The use of questionnaires can be helpful to instigate conversations
''Topic ideas to support families during lock-down''

*Helping children understand the current situation: Why can't I leave the house?
*Keeping a routine
*Living with worry and anxiety for children of any age.
*Supporting parents with behaviour management
*Managing conflict in the family
*Supporting YP to look after their mental health and well-being.

''What to offer if the agreed goals are no longer relevant due to the current situation.''

*parents may want to 'pause' cases if family do not feel the support is helpful now but might become helpful 
*Need to keep in mind that preset goals may or may not have changed but that we need to ensure we avoid certainty
*Don't assume that they would like to continue receiving support. People may have different priorities at this time. 
<center>[img[Stance-Domains.jfif]]</center>

!!Why intervene in multiple domains?
Making deliberate attempts to work in multiple domains is one of the [[Core Features of AMBIT]]. This element of the AMBIT stance is increasingly recognised in policies that encourage a broader set of core skills.

We recognise the complex and 'multifactorial' causes of many of the problems faced by young people - it is rare that problems have a single cause.  Practitioners are trained to work across a range of intervention modalities. Intervening in a single domain (such as the domain of individual psychology - beliefs and motivations, etc) ALONE is not AMBIT, unless there are explicit efforts to work in at least one //other domain//.

!!Multiple interventions
The kind of interventions a worker might use will often have  been developed in, or may be seen traditionally as the province of separate professional groupings. Having a wider range of "barefoot" skills, equips the KeyWorker for active, flexible, "light-footed", non-clinic-based, “frontline” or “street-level” work, allowing the person of the worker him or herself to act in an integrative role (see [[Taking Responsibility for integration]], one of the [[Core Features of AMBIT]]), rather than exposing the young person to multiple professionals at a time when developing a therapeutic attachment to just one individual may be hard enough.  One of the purposes of this approach is precisely to //reduce// the need for a young person to be seen by different specialists and, through a willingness to work across different domains of functioning, to invest in the development of a helping relationship with the AMBIT keyworker. 

There is a strong focus on effective practice (see [[Respect for Evidence]]) – using manualized evidence-based treatment modalities as far as possible, albeit in settings that have previously not been seen as ideal for these to be delivered within.

<html><iframe title="YouTube video player" width="640" height="390" src="https://www.youtube.com/embed/ym-N1mOzFQs?rel=0" frameborder="0" allowfullscreen></iframe></html>

!!What  are "domains"? 

''1. Biological''

*Workers have an understanding not of psychopharmacology (which remains the province of the prescriber) but of:

# Key physical signs that would indicate a need for closer medical assessment, 
# The rationale for using medication
#Tools for developing and sustaining adherence to pharmacological treatment regimes, both addressing the individual and the systemic context (engaging family-members in the task of supporting adherence to a prescription, for instance.)

''2. Individual psychological''

Workers have skills in:

# Mentalization-based approaches to therapy
# Basic CBT
# Motivational approaches
# Psychoeducational techniques 

''3. Family/care network''

*The basic approach is ~Mentalization-Based Family therapy, which emphasises the value in improving the capacity to mentalize within and between family members, but includes, also, structural interventions addressing power hierarchies, boundaries, and the promotion of developmentally appropriate responsibilities.
 
''4. Social-ecological''

*A range of interventions are included, aimed at shifting a young person’s social ecology towards more mainstream and pro-social networks and positive recreational activity. 

''5. Education/Vocational/Employment''

*Interventions within this domain are designed to promote the development of links to sustainable, mainstream institutions or employers (which may be referred to as “mainstreaming”) if at all possible.  An overarching goal is to establish networks beyond Mental Health or Social Care institutions if at all possible. 

''6. Inter-professional network''

*There is a strong emphasis on how to identify and avoid Dis-integratedInterventions amongst the ProfessionalNetworkMembers that tend to collect around young people with complex needs.

!!Mentalization as an organising principle 

In [[AMBIT]], the 'oil' which lubricates these different types of intervention together is a pervasive use of mentalization as an organising principle. 
!What is school like for CYP?

*Might be a safe space/unsafe space – home might feel unsafe, so school is safe or vice versa
* Different for every child – have their own experiences at home, states of mind, relationships with parents
* Could be a place where there is pressure to conform/perform/fit in
* Rules might be quite different between home and school – might be some aspects of school life might be quite unfamiliar. They might have to switch between “how I do things at home”, “how I do things at school. 
* Could feel scary school – expectations change as you get older. Having to take on more responsibility to remember things, look after yourself, be independent. 
* How manageable school feels might depend on how your parents are – do they take an interest in school, do they remind you about things you need etc. 
* Peer pressure – could be more pressure to fit in – might involve feeling that you have to change how you are to fit in
* Are you cool? Are you not cool? What’s your identity? What group are you in?
* Could be exciting also – fun, developing etc. An opportunity to explore different identities
* More choice over forming relationships/friendships – lots of children. 
* Children relate according to their interests 
* Might really enjoy learning about new things 
* Enjoying getting positive feedback from teachers for doing things well
* Being successful at school can be really validating
* Opposite also true – not doing well at school/in subjects can make CYP feel stressed/bad about themselves
* Can feel under a lot of pressure – comparison to peers
* Different schools have different expectations – goal-posts can feel that they are always moving. 
* Have to respect authority
!! The announcement of a second lockdown has raised further questions about how we work in a face to face way in schools.

!!! Things to consider - 
* Schools are in a bubble, if we went to visit multiple schools in one day we would be going into multiple bubbles
*We must tell schools that we might be going in to another 2 or 3 schools in one day, to see if they are comfortable with that 
* If we have multiple cases from one school we should consider the possibility of allocating all cases from one school to one practitioner (if feasible). This could reduce the number of schools that you need to visit.
* Now that we have these extra restrictions, CYP networks must really justify the need for working face2face.



A 1 hour webinar is available on the Future NHS Platform. this webinar covered how to work remotely with children and young people with anxiety and low mood. It has short presentations from different people on working with adolescents with anxiety and low mood (low and high intensity), working with parents of younger children with anxiety, using ROMS remotely, and some feedback from young people on remote working. 
It had good feedback from those who attended (there were 650 of them!).

If you follow this link on the platform, you can access all of the recordings, resources and slides.  
 
https://future.nhs.uk/connect.ti/MHLDAcovid19/view?objectId=19345904
''Questions we want to find out:''

* What are problem behaviours happening at home/ school/ community? Can be easier to approach by domain…
* With each behaviour; onset, frequency and duration?
Getting really specific is helpful:

**What are the behaviours?
**Helpful to spend some time on why you think the problem is happening? 

* What’s the parents sense of why this happens or why it’s difficult for the YP/ child?
** Could you give me an example of how it tends to happen? Can you talk me through a recent example; how did it start? (can give some ideas)
** What are the triggers? 
** What sets it off?
** What helps?
** What makes it worse?
** How does the parent usually respond when behaviour happens?
** What kind of thing have they tried? (can give some ideas of what’s absent and present and where you might be able to start work)
** What has worked/ what does tend to help (even if there’s only a little improvement)

''ROUTINE'' is important – one way of managing behaviour is to make sure as many things are happening as possible – makes problematic behaviour much less likely as child will be reasonably happy, regulated – if something does happen it’s a bit of a frustration rather than building up and becoming overwhelming – can be ‘nipped in the bud’

# What is the routine? How does it look?
** Tell me how the day works?
** What do you tend to do in the evenings? What time do you get ready for bed; dinner etc.?
** What time is the behaviour most problematic – sometimes just directing parent towards putting activity in can help


# How clear are RULES AND EXPECTATIONS on what they’re supposed to be doing
** Are there house rules? In school? (e.g. listening etc.) – does the child know what’s expected of them; do they get reminded about it? Is it clear?
** Can explore directly with children:
** What are important things for children to do?
** How do we make a happy house?
** Thinking with the parent about what they do, do when they see what’s expected – do they praise? Are they just so relieved they don’t comment as to ‘rock the boat’? What are the child’s views on praise? Does this work?
** Can help to form picture of how much reinforcement is happening
** When they do, do something wrong, what happens? What’s discipline? Consequences? (‘all parents have different ways of doing things and this isn’t me telling you what to do, I just want to get a better understanding and through using some ideas of things that other parents do’)
** Do you take things away? Ground them? Punish them?
** Are there no punishments, or lots and lots of punishments (then child thinks I’ve got nothing to lose or 'I’m so angry and cross and hopeless that there’s no point in behaving anyway')
** Do they follow through with punishments?

''What is the general state of the quality of the relationship? ''

** Looking at warmth; play; stimulation
** How do you spend time together? 
** Do they have a preference for attention they get?
** Do they like positive attention or do they seem to prefer getting attention through misbehaving etc.
** Focus on the NEED rather than the attention (e.g. ‘sounds really hard that they’re always wanting to spend time with you)
** Parents should be able to generate type of things they enjoy doing with their child and what the state of the relationship
** Language –age-dependent (e.g. much younger child may do ‘play’ whilst older children wouldn’t)
Is there warmth and reciprocity?

''Where is the parent at in terms of own regulation?''

* e.g. modelling – is the parent themselves reacting by losing their temper quickly, shouting, hitting etc., this is an important part of the picture as reward program is going to be difficult if they can’t keep their cool.

''Behaviour charts''

* Behaviour programs – e.g. is there a particular behaviour they want to focus on with the child?
E.g. listening: every time you do good listening, you’ll earn a token. We can count them up at the end of the week and if you get x amounts of tokens, we can do y. Parent can do by reviewing by day or by every time they see the nice things happening
* Every time might be more motivating as other misbehaviour in the morning may make the day feel hopeless and difficult

''Rules''

* Might be several rules – tick on chart how well child has done them – full tick if done great, half tick if not – green, amber and red (e.g. amber = problem with 1 of more behaviour). Each colour corresponded to certain amount of time on the PlayStation etc. (individual reward).
* Need to work out desirable behaviour and see if child is more likely to do them if they’re encouraged by a  reward and worried about the consequence (which can be not getting the reward or use consequence of losing PlayStation for day for e.g. or going to bed early – withdrawing a privilege).
* Important to make sure child is only losing something for a shorter period of time (e.g. day) – children don’t tend to learn from longer lessons but more from short, sharp consequences – quick cycles are best)

''Individual skills for parents''

* What is praise and what it looks like
* How to give instructions – be calm and direct; try and talk about behaviour you want to see rather than what you don’t want to see
* Setting house rules
* Ignoring is also an option – can be implicit or explicit (tell them you’re going to ignore a certain type of behaviour ‘e.g. I’ll listen to you when you can be respectful again) - this can be for more low-level behaviour 
* Walking away; taking a breather 
* Working out how to detach rather than persist in these moments (e.g. ‘I’m going to come back and speak to you when we’re both calm’)

''Repair conversations''

* Template of how we’ll sort things out afterwards can be very helpful (goal: have your say, get it off your chest and move one). 
* Could use this template to introduce talking about feelings
** E.g. I wasn’t very happy when you did this … I’m going to think of something I could have done differently and you’re going to think about one thing you’ve done differently and we can both say sorry and move on.
* Has it ever worked? What can go well?
* Do you ever have conversations about child’s worries/ feelings?
* What worries might the child have?
* What feelings do they think their child has?
* Can make a chart with child – check-in with them at the end of the day and use faces

''Working with goals''

* Want one quite specific goal of what the undesired behaviour is and what the desirable behaviour if – do they have skills and if not, how can we as a unit develop them together?
* Problems with respecting parental authority – if so, can try behaviour chat and consequences
* What skills are you going to focus on?
* What are you motivated and interested to hear about?

Could use card or quiz on their strengths and what they’d like to improve on in terms of parenting strengths and difficulties – might help to reduce the extent to which they feel judged. Not about not being a good parent, but that for lots of different reasons it gets tough sometimes.. It’s helpful if we can prioritise in your mind and respect the fact that you’ve tried a lot already and you know you’re child best. 


All Looked After Children have different circumstances and needs, which we will need to be held in mind and used to guide the best way of helping them and their networks. This page is not intended to replace this process, but instead to list some general principles that are helpful to consider when thinking about offering a helping intervention. 

All Looked After Children will have a social worker and the majority of Looked After Children will be living in a foster placement, supported by one or two foster carers (nb. some children will live in alternative residential settings). 

Following the principle of [[scaffolding existing relationships|Scaffolding Existing Relationships]], we would want to be thinking very carefully about how our work supports, strengthens and makes best use of these relationships, as they are most likely to endure long beyond our involvement. 

This group of young people may also find it more challenging than others to build trusting relationships with people, because they are likely to have had experiences that have left them finding others hard to trust. This means that we may need to allow longer for engagement and building a relationship. 

Looked After Children can also have needs in a number of different areas, meaning that they can attract quite large networks of professionals. They may be faced with a large number of adults trying to form relationships with them, all trying to help with different things. This might be quite overwhelming for the young person, particularly if they do not share ideas with the workers about what their needs are. 

Considering how best to respond to referrals for Looked After Children needs particular care and attention to ensure that the response is helpful to the young person. Very often, referrals may be based on things that other people think would be helpful for the young person and are not always coming from the young person themselves. At other times, the young person might have made an explicit request for help with an issue, which we would want to make sure is responded to. 

It is helpful to think carefully with social workers and foster carers about where the request for help is coming from and if the young person is in agreement with this, whether there is anyone in the existing network who might be able to provide this, before setting up a new form of help. If something is offered, it is useful to think about whether this might be best done through or with the social worker and/or foster carer/s, in order to support their relationship with the young person and ability to sustain any benefits of the work. At other times, more thinking may be required with the network about the best way to proceed, if something is being asked for that the young person has not requested themselves. 

It is not very helpful for a young person to be introduced to a new worker, who has been given a task to complete by another worker, without the young person having any say about whether this is wanted, needed or how it might best happen. 

What can also be inadvertently overlooked are existing relationships of trust that the young person already has. There may be someone in their existing network (both personal or professional) who might be better placed (in the young person's eyes) to be helpful to them. We should be considering what role these people could play in helping before assuming that this task should be assigned to a new person who the young person does not know and would need to build a trusting relationship with. 

We should be mindful that whilst some short-term, goal-focused wellbeing work might be useful for some young people who are Looked After (particularly if they are help-seeking), work on their underlying difficulties or exploring/unpicking events related to their life story (which is likely to include relational and developmental trauma) is long-term work that is beyond the scope of the intervention length offered by WEST and needs careful planning, in order to ensure that there is sufficient stability and support available to the young person in order to make best use of this. 

We may want to consider offering consultations to social workers and network meetings before agreeing to meet with young people to carry out a piece of wellbeing work, in order to give full consideration to the above. 

!!!Short-term goal focussed work with looked after children:



*How do we approach this? 
*what will be important to consider when we have a referral that asks for this?
*What might be indicators of short term work being possible with a looked after child?
*What might be indicators that it could be less helpful/not possible to start short term work?
*what happens when we agree to short term work at the initial consultation but then further complexity factors arise which suggest short-term work may not be helpful? how do we manage this as a service?
*How can we feel confident in explaining our rational for not starting direct work with a CYP when there seems to be other helpful ways of approaching the work (e.g. supporting a social worker, working instead with a foster carer or helping support the network etc)


Key theory to hold in mind: Attachment theory- how can we promote in our stance the  principles of promoting a 'safe base', consistency, trust, predictability for the CYP (particularly when there may be a large network around them)

Holding attachment theory in mind, it is likely that the CYP may have had adverse experiences of attachment relationships and hence there is a genuine risk of overwhelming the CYP with demands to create too many new attachments 

Note: review learning from AFC around effective work in this area and case studies done with looked after children that can be beneficial. See what the evidence tells us.

[[Attachment Theory|Attachment Theory]] see here for re-capp on key features of 



!!What do we do when we get a referral for a LAC
*Scotty conducts consultation/ assessment (note we aim to include Scotty and Jyoti in some future training sessions to learn about how they carry out consultations)
**Does Scott speak to the YP who are old enough about what they want from the support?
*Referral accepted
*Allocated to WP
*WP reads record keeping from AS about consultation ( it may be helpful to speak with Scotty in person about what he has found out about the CYP at an early stage)
*Make contact with the network 
** explain what we do/how our service works,  invite them to help us in understanding the young person's needs, what do they see as the problem:

!!!Key early questions to ask when talking to referrer/members of network:

Whose idea was the referral? what were they hoping for? what does the CYP think about this? does the CYP agree? What has been discussed with the CYP? Do they know about you being involved? What is the CYP understanding of you being involved?

Next steps in the process:

**Do we start with the network or do we start by speaking with Scott? Clarify this - this could be a hindering or time consuming thing, but might feel helpful to get a sense of the network 
**then contact SW, referrer then foster carer then YP/child
*Contacting the Social worker
**History, context, what are the main strengths and difficulties, begin by using the [[Dis-integration Grid]] to map different members of the network and their ideas about the problem, the intervention and their ideas about who should do it
*Contacting the carer/foster carer
**what are their concerns, goals, what is their relationship like, what is their family set up and how does the young person slot in, how long has the YP been in their care, do they spend time together or are they in their room, what are the next steps- will they be there for a long time.
*school
** what is their behaviour like at school, peer relationships, relationships with teachers, learning etc.

*YP/Child 

**Do you know who i am and why i am calling you? was it a surprise/ did you know? Broadcast who I am what I do...clear about our intentions. What were they told? 
**What is their understanding of why they are there, 
**What is their reaction to you calling? (their understanding/ experience of helping professionals/ attachment styles)
**Their understanding of their living situation 
**Use network mapping ([[PRO-GRAM|The AMBIT Pro-Gram]] - is it more helpful to support the network in an aspect of their work? how does the CYP see their network and who is helpful/has trust from their perspective?
**have conversation with YP about helping relationships and whether they would feel ok with someone coming in for a short time
**What is contact/ relationship like with biological family
**Relationship to help- what is their experience of help in the past - how have they found this, what have they had previously? 

!!Can we help?


!!!What are some indicators that short term direct work is possible with LAC?
*If the CYP agrees and can themselves identify something specific/ have a clear (ish) idea of what they want help with - low mood/ exam stress etc.
*If the network are in agreement for the type of support needed 
* The CYP can make use of remote work (in lockdown)
*There are not barriers to forming a relationship in a relatively short period
*The CYP has had some positive experiences of helping relationships


!!!What are some indicators that short-term goal focussed direct work may not be helpful/ possible 
*when they cant think about what they would like help with in the first few sessions
*When the requests for help come from others and the CYP does not agree, or when there are lots of conflicting views in the network about what is needed and the CYP doesn't agree either
*When we see that it may take  a number of sessions to form a relationship with the CYP in order for them to access any support from us
*There are others in the network who already seem to be doing something similar with the CYP to the request for us to do. It may make more sense that another member of the network who has pre-existing trust/relationship is supported to do this work rather than add another worker to a large system
*There are other key issues that need to be prioritised first in order that they are safe and contained e.g. somewhere to live, some stability, safety 


''Note: It can feel challenging for WP to change suggest that appropriate support is not provision of 1:1 with child as this may have been agreed during the assessment phase. This can arise when we have agreed to the referral at the initial consultation but further complexity factors arise when we begin work''

!!!How might we manage these situations as a team?

*
*

!!What is the evidence base for supporting LAC
*Foster carers - attachment, attuning 
*Attachment styles  



*How do consultations happen (with LAC)
How best to input/connect about these?


See here for 
[[Ideas for supporting foster carers/members of a network around a LAC|Working with carers of LAC children and trauma]]

Particularly in the context of challenging behaviours that may be related to trauma in a CYP's history 

<<list-links "[tag[Working with Peer Difficulties]]">>


''What do we mean by peer difficulties?''

* Not having friends
* Poor social skills or understanding around friendships
* Arguments/fall outs with friends
* Antisocial peer group (worries about gang involvement; older peers; child sexual exploitation; county lines)
* Bullying or being bullied
* Problems on social media, cyberbullying
** Online friends

''Our previous experiences of working with these difficulties:''

* Teaching friendship/social skills
* Exploring “what is a friend?”
* How to respond appropriately in a social situation
* Managing emotions when with peers
* Self-esteem work around bullying
* Keeping safe in relationships – healthy/unhealthy relationships psychoeducation
* Managing conflict in friendships 
* Evaluating friendships – increasing interactions with positive peers; decreasing interactions with negative peers
* Working with parents around online safety
* Thinking with parents about supervision and monitoring 


''Why might children struggle with their peers?''

* Not fitting in
* Not valuing themselves; low self-esteem which might lead them to seek out acceptance/value from others
* Disruptions to friendships – e.g. moving house; moving schools
* Lack of opportunities to practice making and sustaining friends
* Hard to manage emotions
* Temperamental factors- being more outgoing vs. more shy
* Not being able to read people well – inappropriate responses
* Behaving in ways that other YP might find aversive
* Friendship/social skills not modelled at home
* Individual needs- ADHD; ASD might impact on friendships
* Poor peer relationship at school/performance at school might lead you to seek achievement and connection elsewhere e.g. outside of the home, negative peers
* Not being able to invite friends over- can’t hang out in family home; 
* Cultural/family factors – different views in the family about appropriate friendships and what its ok to do
* Lack of appropriate boundaries around friendships – e.g. permissive parenting style
* Push and pull factors 

''Exploring peer relationships''

* Exploring peer strengths and needs
** What’s going well with their friendships? 
** What are the challenges?
** Parents – who do you know? 

* Peer mapping 
** Who are their peers?
** Closer relationships; more distant
** What’s good/helpful about each person?
** What do they do together?
** Any challenges in that friendship?

''Bullying''

* Getting a picture of the bullying
** What does it look like?
** How does it start?
** What helps?
** What makes it worse?

* What’s the impact?
** How does it make me feel?
** What kinds of things does it make me think?
** What kinds of things does it make me do?

* What to do
** What have I tried?
** What could I try?
** How do other people help?
** How else could other people help?



!!Introduction 
One of the [[Core Features of AMBIT]] is using [[Mentalization]] in face to face work with your clients.  In focusing on what goes on between between client and worker, AMBIT is like pretty much any other therapeutic approach (it is AMBIT's emphasis on the //other three quadrants// of the AMBIT Wheel that makes AMBIT a bit different.)

Aside from [[The Therapist's Mentalizing Stance]], it is [[Active Planning]] (the way mentalizing informs our ''planning'' in work so as to allow for sensitive //adaptation// without a loss of //purposeful direction//) that most centrally captures this, but there are a wide range of other aspects of face to face working that are also gathered under this heading, as sub-topics. 

!!Aspects of Working with your Client
The main subtopics to Working with your Client are listed below, click on the tags to see a drop down list of the pages under each sub-topic.


*<<tag [[Active Planning]]>> - AMBIT's [[Mentalization]]-based approach to co-producing rationally-sequenced & effective action plans
 
*<<tag [[Relationship to help]]>> - How different clients respond differently to offers of help, and how to adapt the offer 

----

*<<tag [[Phases of AMBIT work]]>> - Orienting yourself to what should be happening, and when
*<<tag [[Manage CLIENT RELATIONSHIP]]>> - Making sense of and managing the therapeutic relationship between worker & client. 
*<<tag [[Managing Risk]]>> - Managing risk in general (& its pitfalls) and in relation to specific situations 
*<<tag [[Manage CLINICAL PROBLEM]]>> - Lists specific situations in direct face-to-face work (problems, scenarios, etc; not necessarily "clinical" in the technical sense) with suggested responses 
*<<tag [[I'm stuck: what next?]]>> - Other material, useful if your efforts to keep the work moving have stalled. 

-----

*<<tag [[Interventions (by target group)]]>> - Lists range of "manualized" interventions that might help, organised by the domain you want to work in (individual, family, etc) 
*<<tag [[Specific interventions]]>> - Lists links to specific guides ("how to do it" manuals) on a range of simple evidence-based interventions
*<<tag [[Monitoring Outcomes]]>> - Links to activities and resources directed at assessing whether the work of the team is effective. 



!!Introduction
Here we address working with the common problems that arise in working with the professional networks that gather around a young person and their family - particularly if you are keeping to one of [[Core Features of AMBIT]] which is to ensure that you are [[Addressing Dis-integration]]. 

!!Aspects of Working with your Networks
The yellow (& green) tags below provide you with the key themes which fall under working with your networks. Click on the tags to see a drop down list of the pages under each topic.

*<<tag [[Working with your NETWORKS]]>>Key topics, and local additions to how we work with large complex networks of professionals, families, and social contacts

*<<tag [[Addressing Dis-integration]]>> - The central theme of AMBIT practice with networks
*<<tag [[Working with other professionals]]>> - A collection of activities and advice for working effectively across agencies 
*<<tag [[Taking Responsibility for integration]]>> - The AMBIT stance element that underpins this work 
*<<tag [[Working with the Social Ecology]]>> - Addresses work with the INFORMAL networks around a young person 

!!Reframing expectations - a core feature

In AMBIT we try not to be //surprised// or //disappointed// by ''Dis-integration'' in practice across complicated networks; instead, we ''//expect it//''!  

Indeed, working with these //imperfect associations, affiliations and collaborations// (which requires consistent effort by workers in [[Addressing Dis-integration]]) is one of the [[Core Features of AMBIT]].  

This answers the AMBIT stance element that promotes [[Taking Responsibility for Integration]].

!!Note on definition

Although the Family is often the most important part of a young person's network, we locate many of the face to face working issues to do with the family under manage Clinical problems - this is because the '~Family-As-A-Whole' can in many respects be seen as the client, rather than just the young person (and the "family" is however the young person defines this, which may refer to carers who are not strictly family members).  


!!Introduction
Working with your TEAM is one of the [[Core Features of AMBIT]], both as a core practice, and as stance principle [[Keyworker well-connected to wider team]]. This page provides you with a brief introduction and links to ideas about AMBIT-Team working, and how you can use these in your local team.

!!Team working in AMBIT - the "well-connected team"
AMBIT is a method of working that involves the team as a whole - and in particular how we try to use [[Mentalization]] to structure and support team working, and in particular to help the team support the individual KeyWorker. 

Indeed, in earlier versions of AMBIT the [[Supervisory Structures]] in teams were given as the "[[core feature|Core Features of AMBIT]]" of AMBIT, rather than //"Working with your team"// in more general terms.  

AMBIT promotes the development of principles and specific practices that support team practice that are underpinned by the use of [[Mentalization]]. These principles and practices (the [[Core Features of AMBIT]]) can be adapted for a wide range of different service structures. AMBIT does not specify the managerial or organisational arrangements for teams which use this approach. 
 
The AMBIT approach aims to enable local expertise to work more effectively by explicitly finding ways to:

* Support practitioners to remain [[well connected|Keyworker well-connected to wider team]] to other team members
* Support practitioners to take responsibility for stimulating and sustaining //each others'// [[Mentalization]] 

This particularly happens through a key process which we call [[Thinking Together]].

!!Video on AMBIT and Team Working
By Liz Cracknell, one of the senior AMBIT Trainers - here she is addressing a Training for AMBIT Local Facilitators:
<html><iframe width="640" height="360" src="https://www.youtube.com/embed/0e_kGvCtOEw" frameborder="0" allowfullscreen></iframe></html>


!! Aspects of Working with your Team
The tags below (yellow pill shapes) provide you with the key themes within working with your team. Click on the tags to see a drop down list of the pages under each topic. 

!!<<tag AMBIT-Teamworking>> 
*Material specific to AMBIT's approach to team working 
!!<<tag [[SUSTAIN best practice]]>>
*Supporting teams to work in sustainable ways (beyond mere heroism) is a primary aim 
!!<<tag SupervisoryStructures>> 
*Includes boundaries & local rituals/disciplines such as [[Thinking Together]] 
!!<<tag [[Rituals and Disciplines]]>>
* Local rituals and disciplines that define a team culture are what AMBIT training helps teams start to choose 
!!<<tag [[Problems in teams]]>> 
*Problems occur in every team & are opportunities to learn 
!!<<tag [[Boundaries]]>> 
*Clear, well-marked boundaries help reduce risks and problems in teams

---
!!<<tag [[AMBIT training]]>> 
*Training in AMBIT is exclusively team-based for good reasons 
!!<<tag [[Core Features of AMBIT]]>> 
*This covers all parts of the AMBIT Wheel 
!!<<tag [[Roles and Responsibilities in an AMBIT team]]>> 
*Clarifying roles and responsibilities is a critical (and recurring) conversation 
!!<<tag [[Developing learning organisations]]>> 
*AMBIT is about explicitly attending to developing a team culture 
!!<<tag [[OUR Team]] 
*Developing [[OUR Team]] rather than //"making our team into an AMBIT team"// is the point!
!!<<tag [[Monitoring OUTCOMES]]>> 
*Monitoring outcomes (and //evaluating// these) indicates learning from your experts by experience. 

----

!!Diversity, with common core features
Another of the [[Core Features of AMBIT]], is to start with the assumption of respect for local expertise ([[Respect Local Practice and Expertise]]) both in the team, in wider networks, and in the [[KeyWorker]]. Thus, developing your LOCAL Team working is key!

As part of the development of a local team culture, local teams should record their own expertise and protocols in their local version of the manual.

BOOK for carers and workers: [[Attachment in Common Sense and Doodles|https://www.amazon.co.uk/Attachment-Common-Sense-Doodles-Practical/dp/1849053146]] Miriam Silver

!!Ideas for supporting foster carers/members of a network around a LAC 

We talked about some of the dilemmas faced by foster carers within this field and in particular situations where they may see/experience behaviours from a Child/young person that are hard to make sense of, distressing or  at times overwhelming. Sometimes these behaviours can feel as if they 'come out of the blue' or are 'incongruent' with a given situation.

*An overall aim of work with foster carers is to help support them to find ways to re-generate mentalizing (of the CYP and of themselves) when it is inevitably lost in situations where there is high emotion or confusing/distressing behaviours.

*Carers will need to have close relationships to the CYP they look after in order to support them well, but this will mean they are likely to be 'in the middle of the pond' with them at challenging times too

*Helping a foster carer hold on to or regain mentalizing is likely to allow more attuned responses to the CYP, more thoughtful and reflective ways of responding and will likely decrease the chances of responding in ways that might escalate the behaviours or develop further challenges in relationships

*It is also more likely to allow space for the carer to help the CYP to learn to regulate their emotional state- a key developmental challenge particularly for many LAC- i.e. if the CYP can experience //being// mentalized by the carer

!!Time Holes

This is a tool/ idea which relates to the above challenges and is grounded in  trauma theory

Some key relevant points from trauma theory 
 

!!!Memory storage and Trauma

*Non-traumatic memories are stored in a autobiographical way so they are stored with a sense of time and place/context. They can be expressed verbally or are 'verbally accessible' 
*Traumatic memories or memories that are stored when you feel in danger/ threat (this can be to your sense of self)  are often stored in a non verbal way, without sequence, time or narrative meaning they are often held as feelings in the body or visual/ sensory ways e.g. images/sensations

*Children and young people will be much less likely to have a verbal narrative about events because of the way that the memory has been stored in the brain

*These kind of memories are called 'situationally accessible memories' as they are unstable and easily triggered, often without warning but in situations that might somehow relate to the memory

*This might look like a young person reacting strongly with a fear/threat/fight/flight/freeze response to something which seems hard to understand or recognise

!!!Dissociation
*shutting off/ distancing from the real world
*may happen if the danger continues over a long time
*may look calm or not really there/cut off
*An adaptive response to prolonged threat
*a way of psychologically distancing from the distress
*Can have very severe psychological consequences if prolonger re self of self, emotion regulation, capacity to mentalize
*Dissociation is associated with developmental trauma or 'relational trauma' where source of trauma may be in a key relationship/attachment figure

*Stress Physiology and hence responses to stress may change/ adapt when exposed to the danger/ threat for a long time.

Goal of using the Time hole work (see above book by Miriam Silver for further explanation)

*Explaining in simple ways the potential link between past trauma and current behaviour- linking this to the nature of sensory/image based memories in trauma, ways in which the body may still be 'moving quickly into fight/flight/freeze in relation to sensory/image based memories which are unstable...'pop' back in relation to triggers

Can we (the foster carer and worker) piece together what the triggers might be that lead a CYP to fall back down their 'time hole'? what do we know about their history...exploring the current challenging situations in detail..(as you might in a good behavioural analysis) see here for more on this [[Behaviour problems|Working with Behaviour Problems]]

*Helping the foster carer consider what they might do/adapt/test out with some new ideas about a 'time hole' if they have been able to identify one...

*How might they talk to the CYP about what they have noticed ? is this possible appropriate? (it may not be at this stage)

*Are more sensory/physiological/somatosensory ways to help sooth/calm more appropriate? e.g. if trauma was at very early developmental stage? Trying to do 'talking work' may not be helpful now if trauma happened at pre-verbal stage

Discovering the triggers that lead us down the 'time hole' by getting curious about what these triggers might be and how the child may react.
<<list-links "[tag[Working with co-morbidity]]">>


It can be hard to know where best to focus when there are several different problems that a young person is facing

Some YP might be struggling with lots of different emotions (e.g. anger, anxiety, sadness etc). How do we prioritise between those?

*Could ask the YP which they might want to focus on. Would they prioritise one of these?
* Could do some general work on emotion regulation and work out which skills/approaches might be relevant that might help with all of these
<<list-links "[tag[Working with low mood]]">>


!How to do behavioural activation when CYP have to stay at home more?

Some of the activities that CYP might have been able to do as part of BA might now feel more limited

*Want to schedule activities that bring a sense of ''Achievement, Connection and Enjoyment''

These will look different for all YP but some examples might include

''Achievement'': getting up/out of bed by a certain time; doing some school work; making bed; cleaning/tidying room; showering; getting dressed; brushing teeth; reading a chapter; cooking a meal; doing a workout/hobby 

''Enjoyment'': watching favourite show/film; walk; cycle; looking after a pet; something that's relaxing (e.g. having a bath); face mask; playing an instrument; listening to music; reading; doing your hobby; drawing; watching a video of someone doing your hobby!; how to adapt your hobby for doing it at home!

''Connection:'' doing something with parent; doing something with a sibling; playing computer games online/in person with family members; chatting to friends; going on social media; Houseparty app; watch a movie on Netflix party; 

These might be things that are built up gradually (trying it once, then scheduling it more regularly)

Could look through the self-care tiles (put link)

They could ask others for ideas if they are struggling to come up with things themselves

Could also think with YP about how to generally try to maintain their routine and structure, which might help them to look after themselves. 



! How can do the values activity remotely

* You could show the values cards over the screen
* They could google "values" and work out what for homework what some of their values are and make a poster/drawing/list to represent these
* Could use the letters of their name to pick values that they think they have e.g. "C for caring; H for helpful; A for achieving; D for dynamic". Then explore how they are living those values at the moment - what activities they could do that relate to those
* They could ask their family members to name some values they think they have to get some ideas or about their positive qualities and repeat same question of how this links to activities that they could do
* What do they value in a friend? Which of those qualities do they have? What activities could they do at the moment that relate to those?


! How to help keep motivation/positivity up when not in the room with a YP who might be low/not talkative

* Could name this and check in with the young person - is it relevant/helpful?
* How could we do it in a way that feels the most interesting
* Could you use more writing/drawing to show them rather than just talking
*Asking the YP if its easier for you to offer more options/asked more closed questions that they can just say yes or no to, rather than open questions which might be a bit harder to think about
*Sending resources in advance so that they can look through and tell you what they think during the session (E.g. a list of activities - which would they want to try etc)
*Encouraging them to keep a diary/list of things they might want to talk about between sessions

! How the restrictions might be making low mood worse

! Keeping up motivation to do 'homework' tasks

*Not calling it homework! Find a name that might be more acceptable to them e.g. something for you to do before we next meet  an idea to try out; things to try; actions etc;
* Remembering to explain the purpose of it, how it could help, do they think its realistic - make it SMART
* Remember to check in on it
*If can't do a full diary (for example) what could be a smaller way of doing it - a drawing ,a picture, a note on their phone
*Send a reminder/summary text - thanks for talking to me today; look forward to hearing about how you get on with your diary entry etc. I'll have a think about.....before next time too. 
*Make it reciprocal - what is your homework going to be? Can they set you a task? Is there something you can offer to do?


! Harder to pick up on cues of the YP who is low in mood when on the phone if they are not very talkative


For all pages about this topic please see the tag 

<<list-links "[tag[Working with parents]]">>

''What have we each done when working with parents?''

* Worked with parents in an inpatient unit, updating them on what was going on with their child.
* ASD assessments, screening for neurodevelopmental disorders. 
* Eating disorder service:  family therapy and supporting and guiding parents in helping their children recover from eating disorders. 
*In hospital- atopic dermatitis- moderate the dysfunctional caregiver-child relationship through mentalizing in a group with other psychologists and professionals- encouraging parents to reflect on their childhood. often resulted in intergroup relationship building
*observed multi-familygroup with adult children and their parents
*learning mentor- liaised with parents on development, behaviour, engagement with school, independence of child - at home strategies
*TA discussed strategies and progress of child
* Mother-infant observation for 18 months
* Worked as support worker - liasing with parent's about their child's care and new behavioural problems/ health concerns during day - used communication books for non-verbal children
* Dissertation - interviewing parents of non-verbal children with ASD. Supported by linking parents with other services
* TA - similar liasing with parent's about needs of child and development
* Support worker in home with parent, yp and sister - liased about child's development and what I could offer to support 

''What works well when working with parents? What are important things to hold in mind?''

*acknowledging the difficulties of being a parent, validate struggles and feelings, normalise, positivity around that they are help seeking, non-blaming approach.
*Giving them control, allowing them to choose what areas to work on 
*Instilling hope – important to motivate parents to see small changes and keep goals in mind 
*Language; normalising, non-blaming, not patronising
*Remembering parents are an expert in their own child
*Trying to show them you’re on their side

''What dilemmas have come up and how have we addressed these previously?''

*mother who wanted a diagnosis of schizophrenia as behaviour of child was 'difficult'- exploring family history in a sensitive way, uncovered the child's lack of autonomy was coming from mothers need to protect and 'do things for him' 
*child having anxious attachment concerns- talking through parents experiences and own concerns from childhood and how this was being repeated with their own children. practitioner also explored with child how they felt about their parents- uncovered the parents separation was causing the child to feel detached from one of the parents. 
*Stigma around diagnoses; parents seeking an answer/ cure to symptoms rather than understanding and exploring the function of these behaviours/ symptoms 
**ADDRESSED by psychoeducation, parent training workshops
*Being set in their ways and seeing problem as child’s as opposed to need for family change
**ADDRESSED by explaining/ psychoeducation and keeping a realistic view of what can be changed within the family and work with that
*Feeling judged – parents feeling in a position of blame for their child struggling and not wanting to accept conversations around difficult issues 
**ADDRESSED through being transparent, presenting in a non-blaming way, normalising and acknowledging that everyone has/ is doing the best they can – emphasising that it isn’t about blame but ultimately helping the child
*Limited contact; restricted by wants of the child/ adolescent 
*Parents focussing on negatives rather than positives –struggling to see the small changes their child is making
**ADDRESSED by recording small changes, demonstrating small progress through memories and reinforcing positive things. Explaining that the task ahead might be quite big and not simple but small steps is the only way – being realistic and open about expectations from the beginning

''What specific barriers could we imagine coming up when working with parents in this work?''

*Parent expectations 
*Other children
*Previous experience with services
*Child and parent being on different pages
*Parental tension; different parenting styles
*Complex families
*Different cultures
*Stigma around mental health/ wellbeing
*seeking external reasons for the child's distress and the problems they face (diagnosis's for conditions) instead of mentalizing the reason for the behaviour
*reluctance to take some responsibility
*taking too much responsibility and feel high level of guilt, don't feel empowered to make change 
*negative labels of child being 'difficult'- barrier to understanding why the behaviour is occurring. Self fulfilling prophecy
*non-collaborative- that it is the child's issues and they need to change 
* they cant see the benefit/ link of what the change could do
*feel stuck in ways doing things 
*change may cause things to get worse/ not going to make things better- whats the point?
*unaware of their impact on the child.
*Disbelieving/ distrust of therapeutic intervention - perhaps due to previous experiences/ cultural reasons/ expectations 
! What do we want to cover?

* How to apply some of the strategies we have already learned to parent sessions (e.g. the brain house)
*How do we approach supporting parents to talk to children about their feelings?
*How to introduce some of the things that parents could try in a way that doesn't lead to them feeling blamed
* Thinking with parents about how to regulate their own emotions when they are trying to support a child who is emotionally dysregulated
*Addressing barriers that come up when supporting parents to mentalize the child's perspective

!Exploring feelings with parents and children

* What feelings do children know? Which ones come to visit them (at home, at school, with friends etc)?
* Using feelings cards – which one is this? How do people show this? What does someone look like when they feel this? What kinds of things might make someone feel this? Can you think of a time when you felt like this? Someone you know felt like this? 
* Feelings charades – acting out what the feelings look like and having to guess
* Using scenarios – give a picture/scenario and asking what the people involved might be feeling and why. Again using questions to link back to their experiences (have you felt like this?)
* Feelings backpack – which ones do they carry around, which ones weigh them down?
* How we manage different feelings:
* Understanding what might trigger them – what kinds of things make you feel x?
* What helps – what do you do, what do other people do that helps when you’re feeling x?
* Ideas of what might help – which have they tried, could they try, which have/haven’t previously helped
* Using hot cross bun to explore the experience of a feeling in detail, in terms of accompanying thoughts, behaviours and body sessions
* Metaphors like anger thermometer, volcano, racing car etc to explore the experience of the onset of the feeling – gradual, sudden, how can we spot the signs its coming and what could we do at different points before it boils over, gets too hot etc etc.
* Acting out strories/scenarios with the Lego people or toys to help explore situations, feelings, perspectives, behavior and different endings – how people could have helped each other to make a different ending
* When you’re like this, let’s pretend this one is your parent/carer, what can they do to help you? What doesn’t help etc 
<<list-links "[tag[Working with schools]]">>
<<list-links "[tag[Working with sleep difficulties]]">>


!Topics to cover

*What might sleep difficulties look like?
*Exploring sleep routine
*Relationship between sleep and mood - how anxiety and depression can affect sleep
*Sleep hygiene ideas
*Addressing low motivation to address sleep difficulties
*Reaching agreement between parents and YP about sleep routine

__What might sleep difficulties look like?__

* Staying up late
*Waking up late
*Reversed sleep pattern (i.e. awake at night, asleep in the day)
*Disturbed sleep - waking up a lot; poor quality of sleep
*Nightmares
*Difficulties getting to sleep
*Difficulties waking up

__Questions to ask to explore current sleep routine__

*What time do you get up?
*What time do you go to bed?
*How do you get yourself ready for bed?
*What do you do before you go to bed?
*What's your screen time like in the evenings?
*What are you doing during the day (particularly at the moment during lockdown?)
*Where are they spending time during the day (e.g. on/in their bed all day?)
*What's their physical activity daily?
*What's the room like in the day/night? (e.g. open/closing curtains, making the bed etc)
*What do you do when you wake up? (get up straight away, make your bed, do you use an alarm?)
*What's everyone else in your house's sleep routine look like?
*Are you tired during the day? Do you nap?
*Tell me about when you are trying to fall asleep - what's it like? Are there lots of things you are thinking about? Is it hard to switch your mind off?
*Are you sleeping all the way through or waking up a lot?
*What do you eat/drink/snack on during the evening? (sugary things, caffeine, big meals late at night). 
*Do you use any drugs (e.g. smoking, substances, alcohol?) - when?
*Noise - from outside/inside the house
*Do you share a room? Who do you share with? How does this affect your sleep?
*What are your friends' sleep habits like? Do you stay up late chatting to your friends? Either messaging or in a phone/video call.

__Exploring what YP know/feel about sleep and sleep hygiene__

//Exploring motivation//

*Do you feel that your sleep or any aspect of your routine is a problem?
* Are you able to get things done that you want to during the day? Are you able to concentrate (i.e. at school etc)? Is it interfering with other things that you do?
*Would you like to be able to sleep earlier, get more sleep, wake up earlier or make any other changes to your sleep pattern?
*What do other people think about your sleep pattern?
*What would be different if you could get more sleep?
* Using [[scaling questions|Scaling questions]] to explore importance, confidence ratings
*What does a really good night's sleep look like? 
*What's does a bad night's sleep look like?
*In an ideal world, what would you like your sleep to look like?

//Exploring existing knowledge//

*Why do we need sleep?
*What do you know already about what helps and what doesn't help with sleep?
*What do you know already about tips for a good night's sleep?
*What do you know about the effects of e.g. having caffeine/sugar before bed?
*What do you know about how sleep and mood affect each other?
*How important do you think sleep is?
*Do you know what kinds of things happen to people when they don't get enough sleep?
*Do you know that sleeps well/struggles with sleep? What does that look like? 
*What do you know about how many hours of sleep you (i.e. CYP your age) need?
*What do you know about why sleep is important for (their age)?

__Psycho-education about sleep specific to age__

We could make a psycho-education sheet about sleep. Could include some of the below, plus anything else that might specifically motivate a young person (e.g. being better at a particular hobby for example, or linking it to another goal that's important)

*Supports your brain development and do its maintenance (e.g. consolidating memories etc)
*To get rest!
*Our body needs a time to regenerate and repair
*Effects of sleep deprivation - negative
*Need sleep to help us make decisions, take in new information, be able to concentrate
*Different sleep stages (e.g. REM, non-REM) - they have different jobs etc. 
*To have enough energy to do things during the day (school, things we enjoy)
*Helps to regulate other important functions - appetite, hormones, mood etc. 
*Reasons why different age groups need different amounts of sleep - evolutionary perspective - needed different people to be awake at different times of the day!! Older people waking earlier, teenagers on a later shift! Anthropological theory. 
*Sleeping tablets - some people might raise this. 

__Supporting parents and teenagers to reach shared agreement about the sleep routine__

It can be difficult to [[reach shared agreement|Reaching shared agreement between parents and young people]] on things like this! This framework could be used to approach any kind of point of disagreement (doesn't have to just be about sleep!). There can be a lot of strong feelings about, which might be making it difficult to think, but also people may not have very clear ideas in their head about what they think/what they want, so having some time to work this through could also be helpful. Generally, if its hard to reach agreement, having a separate space where each person has an opportunity to work through their thoughts about what they might want and talk through any strong feelings, can be helpful before bringing people together, where what might happen is that the differences and feelings play out in the session in a way that makes collaborative thinking much harder! 

This is a ''mentalizing'' way of approaching the situation - giving each person the best chance to be in their thinking brain, by supporting them in whatever way is required to achieve this (e.g. chance to have their feelings validated, their perspective acknowledged, or help to work out what they think/feel if they haven't already done any thinking or are finding it overwhelming to work it out on their own, or need some more motivational work to increase their interest in thinking about the topic). 

Rather than having a joint conversation first off, could have a separate conversation with each person (i.e. parent, carer and YP) 

Following an active planning stance, it's helpful for workers to broadcast their intentions about why they might be approaching the conversation like this - i.e. "The bedtime/sleep routine is important to you both, but you're got quite different ideas at the moment about what it should looks like. I know that agreeing on this has been hard, so I want to try to help you find something you can both agree on, but its probably going to involve a compromise! I'm happy to think with you both to see if we can work this out - we can do it separately to start with, so you've each got a chance to tell me what you think and what your ideas are, then we can bring those together and see where you agree, where you disagree and work out what hte middle ground is".  

Some questions might include: 

*Asking each person what they feel their ideal would look like, in terms of the sleep/bedtime routine?
*What would it best look like if they could design it?
*How close is that to what is happening at the moment?
*If its not close to what's happening at the moment, what would be realistic?
*Where would they be prepared to move to? What would their compromise be? (supposing the other person had a different view)
*What do they think the other person (their child/ their parent) would think about their ideas?

Can ask parent/carer to write down their ideas/routine/rules around sleep and then ask them to give each part a priority rating (low, medium, high) and a realism/achievability rating. This can help them to refine their expectations in line with what is achievable and developmentally appropriate. 

Similarly, could show the parent/carers' ideas with the young person and ask them to rate them according to things they already do/could do/would be prepared to do (green), things that are a bit ok/achievable and things in red that they think are unreasonable and would be too hard. Acknowledge that can't get rid of rules/expectations all together as they are important to life (given examples). 

Increasing motivation/compliance with the proposed routine

*Explore what the pros and cons would be of trying it
*Seeing if they would be willing to experiment with trying it and let you know how it was - were there any pros and cons
* Would complying with it help in other ways (to get parents off their back; reduce arguments etc!)
* Following the parents' expectation might be worthwhile - e.g. if you show you can go to bed at this time, maybe they will let you stay up a bit later. 

*Explore with parents how they will positively reinforce compliance with routine
**praise, positive feedback, encouragement
**reward system (e.g. earning something they don't already get; linking something they do already get to this new behaviour of following sleep routine)










! Why are we writing this page?

We want to capture some of the ideas that we have about how we are involving parents in our work, particularly during this time of remote working

! How can we think with parents about why it might be helpful for them to be involved?

*

! How can we think with CYP about why it might be useful for their parents to be involved in the work?

We want to try to find a way of keeping parents' in the loop about the work. They often have an important role. 

* Explaining why its useful to you to be able to check in with them, in a way that the YP might be able to connect with
* Can be useful to share with parents about what you and the young person about what you are learning together, so that they understand them better/feel more understood or less misunderstood
* Can be useful to think with the YP about how the parent could help with any of the strategies
*Are their bits of the work that they thnk it would be useful for the parents to know about?


!Reflection Time

We came up with the idea of ''Reflection Time'' that some families could try- a time to sit down and talk together as a family to talk about how the day has been. 

__Why might this be helpful?__

* To help build/strengthen the relationship between parents and children
* To have a way to check in emotionally with children about how they are feeling
*Could be an activity that can fill some structured time! Could send a well-being resource for the family to look through together (e.g. The Brain House)

! Sharing wellbeing resources with parents

Could send worksheets/booklets to families and then the worker could go through the sheets virtually with them so that they have an understanding of them and a way of talking about it with their CYP. (15 min sessions)

!Sharing a summary of the session with parent/carer

*Suggesting to the YP "(What shall we)Shall we share with your Mum/Dad what we have been doing today and what you're going to try this week?"
* Could include praise/positive feedback about how the CYP has managed the session
*Check with the YP about if they want to give the feedback, if they want you to do it, if they want to do it together












{"tiddlers":{"$:/Acknowledgements":{"title":"$:/Acknowledgements","text":"TiddlyWiki incorporates code from these fine OpenSource projects:\n\n* [[The Stanford Javascript Crypto Library|http://bitwiseshiftleft.github.io/sjcl/]]\n* [[The Jasmine JavaScript Test Framework|https://jasmine.github.io/]]\n* [[Normalize.css by Nicolas Gallagher|http://necolas.github.io/normalize.css/]]\n\nAnd media from these projects:\n\n* World flag icons from [[Wikipedia|http://commons.wikimedia.org/wiki/Category:SVG_flags_by_country]]\n"},"$:/core/copyright.txt":{"title":"$:/core/copyright.txt","type":"text/plain","text":"TiddlyWiki created by Jeremy Ruston, (jeremy [at] jermolene [dot] com)\n\nCopyright (c) 2004-2007, Jeremy Ruston\nCopyright (c) 2007-2024, UnaMesa Association\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n\n* Neither the name of the copyright holder nor the names of its\n  contributors may be used to endorse or promote products derived from\n  this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."},"$:/core/icon":{"title":"$:/core/icon","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> viewBox=\"0 0 128 128\"><path d=\"M64 0l54.56 32v64L64 128 9.44 96V32L64 0zm21.127 95.408c-3.578-.103-5.15-.094-6.974-3.152l-1.42.042c-1.653-.075-.964-.04-2.067-.097-1.844-.07-1.548-1.86-1.873-2.8-.52-3.202.687-6.43.65-9.632-.014-1.14-1.593-5.17-2.157-6.61-1.768.34-3.546.406-5.34.497-4.134-.01-8.24-.527-12.317-1.183-.8 3.35-3.16 8.036-1.21 11.44 2.37 3.52 4.03 4.495 6.61 4.707 2.572.212 3.16 3.18 2.53 4.242-.55.73-1.52.864-2.346 1.04l-1.65.08c-1.296-.046-2.455-.404-3.61-.955-1.93-1.097-3.925-3.383-5.406-5.024.345.658.55 1.938.24 2.53-.878 1.27-4.665 1.26-6.4.47-1.97-.89-6.73-7.162-7.468-11.86 1.96-3.78 4.812-7.07 6.255-11.186-3.146-2.05-4.83-5.384-4.61-9.16l.08-.44c-3.097.59-1.49.37-4.82.628-10.608-.032-19.935-7.37-14.68-18.774.34-.673.664-1.287 1.243-.994.466.237.4 1.18.166 2.227-3.005 13.627 11.67 13.732 20.69 11.21.89-.25 2.67-1.936 3.905-2.495 2.016-.91 4.205-1.282 6.376-1.55 5.4-.63 11.893 2.276 15.19 2.37 3.3.096 7.99-.805 10.87-.615 2.09.098 4.143.483 6.16 1.03 1.306-6.49 1.4-11.27 4.492-12.38 1.814.293 3.213 2.818 4.25 4.167 2.112-.086 4.12.46 6.115 1.066 3.61-.522 6.642-2.593 9.833-4.203-3.234 2.69-3.673 7.075-3.303 11.127.138 2.103-.444 4.386-1.164 6.54-1.348 3.507-3.95 7.204-6.97 7.014-1.14-.036-1.805-.695-2.653-1.4-.164 1.427-.81 2.7-1.434 3.96-1.44 2.797-5.203 4.03-8.687 7.016-3.484 2.985 1.114 13.65 2.23 15.594 1.114 1.94 4.226 2.652 3.02 4.406-.37.58-.936.785-1.54 1.01l-.82.11zm-40.097-8.85l.553.14c.694-.27 2.09.15 2.83.353-1.363-1.31-3.417-3.24-4.897-4.46-.485-1.47-.278-2.96-.174-4.46l.02-.123c-.582 1.205-1.322 2.376-1.72 3.645-.465 1.71 2.07 3.557 3.052 4.615l.336.3z\" fill-rule=\"evenodd\"/></svg>"},"$:/core/images/add-comment":{"title":"$:/core/images/add-comment","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-add-comment tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M56 56H36a8 8 0 100 16h20v20a8 8 0 1016 0V72h20a8 8 0 100-16H72V36a8 8 0 10-16 0v20zm-12.595 58.362c-6.683 7.659-20.297 12.903-36.006 12.903-2.196 0-4.35-.102-6.451-.3 9.652-3.836 17.356-12.24 21.01-22.874C8.516 94.28 0 79.734 0 63.5 0 33.953 28.206 10 63 10s63 23.953 63 53.5S97.794 117 63 117c-6.841 0-13.428-.926-19.595-2.638z\"/></svg>"},"$:/core/images/advanced-search-button":{"title":"$:/core/images/advanced-search-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-advanced-search-button tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M74.565 87.985A47.776 47.776 0 0148 96C21.49 96 0 74.51 0 48S21.49 0 48 0s48 21.49 48 48c0 9.854-2.97 19.015-8.062 26.636l34.347 34.347a9.443 9.443 0 010 13.36 9.446 9.446 0 01-13.36 0l-34.36-34.358zM48 80c17.673 0 32-14.327 32-32 0-17.673-14.327-32-32-32-17.673 0-32 14.327-32 32 0 17.673 14.327 32 32 32z\"/><circle cx=\"48\" cy=\"48\" r=\"8\"/><circle cx=\"28\" cy=\"48\" r=\"8\"/><circle cx=\"68\" cy=\"48\" r=\"8\"/></g></svg>"},"$:/core/images/auto-height":{"title":"$:/core/images/auto-height","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-auto-height tc-image-button\" viewBox=\"0 0 128 128\"><path d=\"M67.987 114.356l-.029-14.477a4 4 0 00-2.067-3.494l-15.966-8.813-1.933 7.502H79.9c4.222 0 5.564-5.693 1.786-7.58L49.797 71.572 48.01 79.15h31.982c4.217 0 5.564-5.682 1.795-7.575L49.805 55.517l-1.795 7.575h31.982c4.212 0 5.563-5.67 1.805-7.57l-16.034-8.105 2.195 3.57V35.614l9.214 9.213a4 4 0 105.656-5.656l-16-16a4 4 0 00-5.656 0l-16 16a4 4 0 105.656 5.656l9.13-9.13v15.288a4 4 0 002.195 3.57l16.035 8.106 1.804-7.57H48.01c-4.217 0-5.564 5.682-1.795 7.574l31.982 16.059 1.795-7.575H48.01c-4.222 0-5.564 5.693-1.787 7.579l31.89 15.923 1.787-7.578H47.992c-4.133 0-5.552 5.504-1.933 7.501l15.966 8.813-2.067-3.494.029 14.436-9.159-9.158a4 4 0 00-5.656 5.656l16 16a4 4 0 005.656 0l16-16a4 4 0 10-5.656-5.656l-9.185 9.184zM16 20h96a4 4 0 100-8H16a4 4 0 100 8z\"/></svg>"},"$:/core/images/blank":{"title":"$:/core/images/blank","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-blank tc-image-button\" viewBox=\"0 0 128 128\"/>"},"$:/core/images/bold":{"title":"$:/core/images/bold","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-bold tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M41.146 51.81V21.87h26.353c2.51 0 4.93.21 7.26.628 2.33.418 4.392 1.165 6.185 2.24 1.793 1.076 3.227 2.57 4.302 4.482 1.076 1.913 1.614 4.363 1.614 7.35 0 5.379-1.613 9.263-4.84 11.653-3.227 2.39-7.35 3.586-12.37 3.586H41.146zM13 0v128h62.028a65.45 65.45 0 0016.762-2.151c5.438-1.434 10.278-3.645 14.52-6.633 4.244-2.988 7.62-6.842 10.13-11.563 2.51-4.721 3.764-10.308 3.764-16.762 0-8.008-1.942-14.85-5.826-20.527-3.884-5.677-9.77-9.65-17.658-11.921 5.737-2.75 10.069-6.275 12.997-10.577 2.928-4.303 4.392-9.681 4.392-16.135 0-5.976-.986-10.995-2.958-15.059-1.972-4.063-4.75-7.32-8.336-9.77-3.585-2.45-7.888-4.213-12.907-5.289C84.888.538 79.33 0 73.235 0H13zm28.146 106.129V70.992H71.8c6.095 0 10.995 1.404 14.7 4.212 3.705 2.81 5.558 7.5 5.558 14.073 0 3.347-.568 6.096-1.703 8.247-1.136 2.151-2.66 3.854-4.572 5.11-1.912 1.254-4.123 2.15-6.633 2.688-2.51.538-5.139.807-7.888.807H41.146z\"/></svg>"},"$:/core/images/cancel-button":{"title":"$:/core/images/cancel-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-cancel-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M64 76.314l-16.97 16.97a7.999 7.999 0 01-11.314 0c-3.118-3.118-3.124-8.19 0-11.313L52.686 65l-16.97-16.97a7.999 7.999 0 010-11.314c3.118-3.118 8.19-3.124 11.313 0L64 53.686l16.97-16.97a7.999 7.999 0 0111.314 0c3.118 3.118 3.124 8.19 0 11.313L75.314 65l16.97 16.97a7.999 7.999 0 010 11.314c-3.118 3.118-8.19 3.124-11.313 0L64 76.314zM64 129c35.346 0 64-28.654 64-64 0-35.346-28.654-64-64-64C28.654 1 0 29.654 0 65c0 35.346 28.654 64 64 64zm0-16c26.51 0 48-21.49 48-48S90.51 17 64 17 16 38.49 16 65s21.49 48 48 48z\"/></svg>"},"$:/core/images/chevron-down":{"title":"$:/core/images/chevron-down","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-chevron-down tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M64.053 85.456a7.889 7.889 0 01-5.6-2.316L2.473 27.16a7.92 7.92 0 010-11.196c3.086-3.085 8.105-3.092 11.196 0L64.05 66.344l50.382-50.382a7.92 7.92 0 0111.195 0c3.085 3.086 3.092 8.105 0 11.196l-55.98 55.98a7.892 7.892 0 01-5.595 2.317z\"/><path d=\"M64.053 124.069a7.889 7.889 0 01-5.6-2.316l-55.98-55.98a7.92 7.92 0 010-11.196c3.086-3.085 8.105-3.092 11.196 0l50.382 50.382 50.382-50.382a7.92 7.92 0 0111.195 0c3.085 3.086 3.092 8.104 0 11.196l-55.98 55.98a7.892 7.892 0 01-5.595 2.316z\"/></g></svg>"},"$:/core/images/chevron-left":{"title":"$:/core/images/chevron-left","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-chevron-left tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M47.544 64.053c0-2.027.77-4.054 2.316-5.6l55.98-55.98a7.92 7.92 0 0111.196 0c3.085 3.086 3.092 8.105 0 11.196L66.656 64.05l50.382 50.382a7.92 7.92 0 010 11.195c-3.086 3.085-8.105 3.092-11.196 0l-55.98-55.98a7.892 7.892 0 01-2.317-5.595z\"/><path d=\"M8.931 64.053c0-2.027.77-4.054 2.316-5.6l55.98-55.98a7.92 7.92 0 0111.196 0c3.085 3.086 3.092 8.105 0 11.196L28.041 64.05l50.382 50.382a7.92 7.92 0 010 11.195c-3.086 3.085-8.104 3.092-11.196 0l-55.98-55.98a7.892 7.892 0 01-2.316-5.595z\"/></g></svg>"},"$:/core/images/chevron-right":{"title":"$:/core/images/chevron-right","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-chevron-right tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M83.456 63.947c0 2.027-.77 4.054-2.316 5.6l-55.98 55.98a7.92 7.92 0 01-11.196 0c-3.085-3.086-3.092-8.105 0-11.196L64.344 63.95 13.963 13.567a7.92 7.92 0 010-11.195c3.086-3.085 8.105-3.092 11.196 0l55.98 55.98a7.892 7.892 0 012.317 5.595z\"/><path d=\"M122.069 63.947c0 2.027-.77 4.054-2.316 5.6l-55.98 55.98a7.92 7.92 0 01-11.196 0c-3.085-3.086-3.092-8.105 0-11.196l50.382-50.382-50.382-50.382a7.92 7.92 0 010-11.195c3.086-3.085 8.104-3.092 11.196 0l55.98 55.98a7.892 7.892 0 012.316 5.595z\"/></g></svg>"},"$:/core/images/chevron-up":{"title":"$:/core/images/chevron-up","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-chevron-up tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M63.947 44.544c2.027 0 4.054.77 5.6 2.316l55.98 55.98a7.92 7.92 0 010 11.196c-3.086 3.085-8.105 3.092-11.196 0L63.95 63.656l-50.382 50.382a7.92 7.92 0 01-11.195 0c-3.085-3.086-3.092-8.105 0-11.196l55.98-55.98a7.892 7.892 0 015.595-2.317z\"/><path d=\"M63.947 5.931c2.027 0 4.054.77 5.6 2.316l55.98 55.98a7.92 7.92 0 010 11.196c-3.086 3.085-8.105 3.092-11.196 0L63.95 25.041 13.567 75.423a7.92 7.92 0 01-11.195 0c-3.085-3.086-3.092-8.104 0-11.196l55.98-55.98a7.892 7.892 0 015.595-2.316z\"/></g></svg>"},"$:/core/images/clone-button":{"title":"$:/core/images/clone-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-clone-button tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M32.265 96v24.002A7.996 7.996 0 0040.263 128h79.74a7.996 7.996 0 007.997-7.998v-79.74a7.996 7.996 0 00-7.998-7.997H96V48h12.859a2.99 2.99 0 012.994 2.994v57.865a2.99 2.99 0 01-2.994 2.994H50.994A2.99 2.99 0 0148 108.859V96H32.265z\"/><path d=\"M40 56h-7.993C27.588 56 24 52.418 24 48c0-4.41 3.585-8 8.007-8H40v-7.993C40 27.588 43.582 24 48 24c4.41 0 8 3.585 8 8.007V40h7.993C68.412 40 72 43.582 72 48c0 4.41-3.585 8-8.007 8H56v7.993C56 68.412 52.418 72 48 72c-4.41 0-8-3.585-8-8.007V56zM8 0C3.58 0 0 3.588 0 8v80c0 4.419 3.588 8 8 8h80c4.419 0 8-3.588 8-8V8c0-4.419-3.588-8-8-8H8zM19 16A2.997 2.997 0 0016 19.001v57.998A2.997 2.997 0 0019.001 80h57.998A2.997 2.997 0 0080 76.999V19.001A2.997 2.997 0 0076.999 16H19.001z\"/></g></svg>"},"$:/core/images/close-all-button":{"title":"$:/core/images/close-all-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-close-all-button tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M28 111.314l-14.144 14.143a8 8 0 01-11.313-11.313L16.686 100 2.543 85.856a8 8 0 0111.313-11.313L28 88.686l14.144-14.143a8 8 0 0111.313 11.313L39.314 100l14.143 14.144a8 8 0 01-11.313 11.313L28 111.314zM28 39.314L13.856 53.457A8 8 0 012.543 42.144L16.686 28 2.543 13.856A8 8 0 0113.856 2.543L28 16.686 42.144 2.543a8 8 0 0111.313 11.313L39.314 28l14.143 14.144a8 8 0 01-11.313 11.313L28 39.314zM100 39.314L85.856 53.457a8 8 0 01-11.313-11.313L88.686 28 74.543 13.856A8 8 0 0185.856 2.543L100 16.686l14.144-14.143a8 8 0 0111.313 11.313L111.314 28l14.143 14.144a8 8 0 01-11.313 11.313L100 39.314zM100 111.314l-14.144 14.143a8 8 0 01-11.313-11.313L88.686 100 74.543 85.856a8 8 0 0111.313-11.313L100 88.686l14.144-14.143a8 8 0 0111.313 11.313L111.314 100l14.143 14.144a8 8 0 01-11.313 11.313L100 111.314z\"/></g></svg>"},"$:/core/images/close-button":{"title":"$:/core/images/close-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-close-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M65.086 75.41l-50.113 50.113c-3.121 3.121-8.192 3.126-11.316.002-3.118-3.118-3.123-8.19.002-11.316l50.114-50.114L3.659 13.982C.538 10.86.533 5.79 3.657 2.666c3.118-3.118 8.19-3.123 11.316.002l50.113 50.114L115.2 2.668c3.121-3.121 8.192-3.126 11.316-.002 3.118 3.118 3.123 8.19-.002 11.316L76.4 64.095l50.114 50.114c3.121 3.121 3.126 8.192.002 11.316-3.118 3.118-8.19 3.123-11.316-.002L65.086 75.409z\"/></svg>"},"$:/core/images/close-others-button":{"title":"$:/core/images/close-others-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-close-others-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M64 128c35.346 0 64-28.654 64-64 0-35.346-28.654-64-64-64C28.654 0 0 28.654 0 64c0 35.346 28.654 64 64 64zm0-16c26.51 0 48-21.49 48-48S90.51 16 64 16 16 37.49 16 64s21.49 48 48 48zm0-16c17.673 0 32-14.327 32-32 0-17.673-14.327-32-32-32-17.673 0-32 14.327-32 32 0 17.673 14.327 32 32 32zm0-16c8.837 0 16-7.163 16-16s-7.163-16-16-16-16 7.163-16 16 7.163 16 16 16z\"/></svg>"},"$:/core/images/copy-clipboard":{"title":"$:/core/images/copy-clipboard","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-copy-clipboard tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><rect width=\"33\" height=\"8\" x=\"40\" y=\"40\" rx=\"4\"/><rect width=\"17\" height=\"8\" x=\"40\" y=\"82\" rx=\"4\"/><rect width=\"17\" height=\"8\" x=\"40\" y=\"54\" rx=\"4\"/><rect width=\"33\" height=\"8\" x=\"40\" y=\"96\" rx=\"4\"/><rect width=\"12\" height=\"8\" x=\"40\" y=\"68\" rx=\"4\"/><path d=\"M40 16H24c-4.419 0-8 3.59-8 8a8.031 8.031 0 000 .01v95.98a8.03 8.03 0 000 .01c0 4.41 3.581 8 8 8h80a7.975 7.975 0 005.652-2.34 7.958 7.958 0 002.348-5.652v-16.016c0-4.414-3.582-7.992-8-7.992-4.41 0-8 3.578-8 7.992V112H32V32h64v8.008C96 44.422 99.582 48 104 48c4.41 0 8-3.578 8-7.992V23.992a7.963 7.963 0 00-2.343-5.651A7.995 7.995 0 00104.001 16H88c0-4.41-3.585-8-8.007-8H48.007C43.588 8 40 11.582 40 16zm4-1.004A4.001 4.001 0 0148 11h32c2.21 0 4 1.797 4 3.996v4.008A4.001 4.001 0 0180 23H48c-2.21 0-4-1.797-4-3.996v-4.008z\"/><rect width=\"66\" height=\"16\" x=\"62\" y=\"64\" rx=\"8\"/><path d=\"M84.657 82.343l-16-16v11.314l16-16a8 8 0 10-11.314-11.314l-16 16a8 8 0 000 11.314l16 16a8 8 0 1011.314-11.314z\"/></g></svg>"},"$:/core/images/delete-button":{"title":"$:/core/images/delete-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-delete-button tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\" transform=\"translate(12)\"><rect width=\"105\" height=\"16\" y=\"11\" rx=\"8\"/><rect width=\"48\" height=\"16\" x=\"28\" rx=\"8\"/><rect width=\"16\" height=\"112\" x=\"8\" y=\"16\" rx=\"8\"/><rect width=\"88\" height=\"16\" x=\"8\" y=\"112\" rx=\"8\"/><rect width=\"16\" height=\"112\" x=\"80\" y=\"16\" rx=\"8\"/><rect width=\"16\" height=\"112\" x=\"56\" y=\"16\" rx=\"8\"/><rect width=\"16\" height=\"112\" x=\"32\" y=\"16\" rx=\"8\"/></g></svg>"},"$:/core/images/discord":{"title":"$:/core/images/discord","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-discord tc-image-button\" viewBox=\"0 -28.5 256 256\"><path d=\"M216.856 16.597A208.502 208.502 0 0 0 164.042 0c-2.275 4.113-4.933 9.645-6.766 14.046-19.692-2.961-39.203-2.961-58.533 0-1.832-4.4-4.55-9.933-6.846-14.046a207.809 207.809 0 0 0-52.855 16.638C5.618 67.147-3.443 116.4 1.087 164.956c22.169 16.555 43.653 26.612 64.775 33.193A161.094 161.094 0 0 0 79.735 175.3a136.413 136.413 0 0 1-21.846-10.632 108.636 108.636 0 0 0 5.356-4.237c42.122 19.702 87.89 19.702 129.51 0a131.66 131.66 0 0 0 5.355 4.237 136.07 136.07 0 0 1-21.886 10.653c4.006 8.02 8.638 15.67 13.873 22.848 21.142-6.58 42.646-16.637 64.815-33.213 5.316-56.288-9.08-105.09-38.056-148.36ZM85.474 135.095c-12.645 0-23.015-11.805-23.015-26.18s10.149-26.2 23.015-26.2c12.867 0 23.236 11.804 23.015 26.2.02 14.375-10.148 26.18-23.015 26.18Zm85.051 0c-12.645 0-23.014-11.805-23.014-26.18s10.148-26.2 23.014-26.2c12.867 0 23.236 11.804 23.015 26.2 0 14.375-10.148 26.18-23.015 26.18Z\"/></svg>"},"$:/core/images/done-button":{"title":"$:/core/images/done-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-done-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M42.26 111.032c-2.051.001-4.103-.78-5.668-2.345L2.662 74.758a8 8 0 01-.005-11.32c3.118-3.117 8.192-3.12 11.32.007l28.278 28.278 72.124-72.124a8.002 8.002 0 0111.314-.001c3.118 3.118 3.124 8.19 0 11.315l-77.78 77.78a7.978 7.978 0 01-5.658 2.343z\"/></svg>"},"$:/core/images/down-arrow":{"title":"$:/core/images/down-arrow","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-down-arrow tc-image-button\" viewBox=\"0 0 128 128\"><path d=\"M64.177 100.069a7.889 7.889 0 01-5.6-2.316l-55.98-55.98a7.92 7.92 0 010-11.196c3.086-3.085 8.105-3.092 11.196 0l50.382 50.382 50.382-50.382a7.92 7.92 0 0111.195 0c3.086 3.086 3.092 8.104 0 11.196l-55.98 55.98a7.892 7.892 0 01-5.595 2.316z\"/></svg>"},"$:/core/images/download-button":{"title":"$:/core/images/download-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-download-button tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M64 128c35.346 0 64-28.654 64-64 0-35.346-28.654-64-64-64C28.654 0 0 28.654 0 64c0 35.346 28.654 64 64 64zm0-16c26.51 0 48-21.49 48-48S90.51 16 64 16 16 37.49 16 64s21.49 48 48 48z\" class=\"tc-image-download-button-ring\"/><path d=\"M34.35 66.43l26.892 27.205a4.57 4.57 0 006.516 0L94.65 66.43a4.7 4.7 0 000-6.593 4.581 4.581 0 00-3.258-1.365h-8.46c-2.545 0-4.608-2.087-4.608-4.661v-15.15c0-2.575-2.063-4.662-4.608-4.662H55.284c-2.545 0-4.608 2.087-4.608 4.662v15.15c0 2.574-2.063 4.661-4.608 4.661h-8.46c-2.545 0-4.608 2.087-4.608 4.662a4.69 4.69 0 001.35 3.296z\"/></g></svg>"},"$:/core/images/edit-button":{"title":"$:/core/images/edit-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-edit-button tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M95.627 10.059l-5.656 5.657 11.313 11.313 5.657-5.656-11.314-11.314zm5.657-5.657l1.966-1.966c3.123-3.122 8.194-3.129 11.319-.005 3.117 3.118 3.122 8.192-.005 11.32l-1.966 1.965-11.314-11.314zm-16.97 16.97l-60.25 60.25a8.12 8.12 0 00-.322.342c-.1.087-.198.179-.295.275-5.735 5.735-10.702 22.016-10.702 22.016s16.405-5.09 22.016-10.702c.095-.096.186-.193.272-.292a8.12 8.12 0 00.345-.325l60.25-60.25-11.314-11.313zM35.171 124.19c6.788-.577 13.898-2.272 23.689-5.348 1.825-.573 3.57-1.136 6.336-2.04 16-5.226 21.877-6.807 28.745-7.146 8.358-.413 13.854 2.13 17.58 8.699a4 4 0 006.959-3.946c-5.334-9.406-13.745-13.296-24.933-12.744-7.875.39-14.057 2.052-30.835 7.533-2.739.894-4.46 1.45-6.25 2.012-19.46 6.112-30.77 7.072-39.597 1.747a4 4 0 10-4.132 6.85c6.333 3.82 13.754 5.12 22.438 4.383z\"/></g></svg>"},"$:/core/images/erase":{"title":"$:/core/images/erase","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-erase tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M60.087 127.996l63.015-63.015c6.535-6.535 6.528-17.115-.003-23.646L99.466 17.702c-6.539-6.538-17.117-6.532-23.646-.003L4.898 88.62c-6.535 6.534-6.528 17.115.003 23.646l15.73 15.73h39.456zm-34.95-7.313l-14.324-14.325c-3.267-3.268-3.268-8.564-.008-11.824L46.269 59.07l35.462 35.462-26.15 26.15H25.137z\"/></svg>"},"$:/core/images/excise":{"title":"$:/core/images/excise","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-excise tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M56 107.314l-2.343 2.343a8 8 0 11-11.314-11.314l16-16a8 8 0 0111.314 0l16 16a8 8 0 11-11.314 11.314L72 107.314v14.284c0 3.536-3.582 6.402-8 6.402s-8-2.866-8-6.402v-14.284zM0 40.007C0 35.585 3.59 32 8 32c4.418 0 8 3.588 8 8.007v31.986C16 76.415 12.41 80 8 80c-4.418 0-8-3.588-8-8.007V40.007zm32 0C32 35.585 35.59 32 40 32c4.418 0 8 3.588 8 8.007v31.986C48 76.415 44.41 80 40 80c-4.418 0-8-3.588-8-8.007V40.007zm48 0C80 35.585 83.59 32 88 32c4.418 0 8 3.588 8 8.007v31.986C96 76.415 92.41 80 88 80c-4.418 0-8-3.588-8-8.007V40.007zm-24-32C56 3.585 59.59 0 64 0c4.418 0 8 3.588 8 8.007v31.986C72 44.415 68.41 48 64 48c-4.418 0-8-3.588-8-8.007V8.007zm56 32c0-4.422 3.59-8.007 8-8.007 4.418 0 8 3.588 8 8.007v31.986c0 4.422-3.59 8.007-8 8.007-4.418 0-8-3.588-8-8.007V40.007z\"/></svg>"},"$:/core/images/export-button":{"title":"$:/core/images/export-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-export-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M8.003 128H119.993a7.984 7.984 0 005.664-2.349v.007A7.975 7.975 0 00128 120V56c0-4.418-3.59-8-8-8-4.418 0-8 3.58-8 8v56H16V56c0-4.418-3.59-8-8-8-4.418 0-8 3.58-8 8v64c0 4.418 3.59 8 8 8h.003zm48.62-100.689l-8.965 8.966c-3.125 3.125-8.195 3.13-11.319.005-3.118-3.118-3.122-8.192.005-11.319L58.962 2.346A7.986 7.986 0 0164.625 0l-.006.002c2.05-.001 4.102.78 5.666 2.344l22.618 22.617c3.124 3.125 3.129 8.195.005 11.319-3.118 3.118-8.192 3.122-11.319-.005l-8.965-8.966v61.256c0 4.411-3.582 8-8 8-4.41 0-8-3.582-8-8V27.311z\"/></svg>"},"$:/core/images/file":{"title":"$:/core/images/file","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-file tc-image-button\" viewBox=\"0 0 128 128\"><path d=\"M111.968 30.5H112V120a8 8 0 01-8 8H24a8 8 0 01-8-8V8a8 8 0 018-8h57v.02a7.978 7.978 0 015.998 2.337l22.627 22.627a7.975 7.975 0 012.343 5.516zM81 8H24v112h80V30.5H89c-4.418 0-8-3.578-8-8V8z\"/><rect width=\"64\" height=\"8\" x=\"32\" y=\"36\" rx=\"4\"/><rect width=\"64\" height=\"8\" x=\"32\" y=\"52\" rx=\"4\"/><rect width=\"64\" height=\"8\" x=\"32\" y=\"68\" rx=\"4\"/><rect width=\"64\" height=\"8\" x=\"32\" y=\"84\" rx=\"4\"/><rect width=\"64\" height=\"8\" x=\"32\" y=\"100\" rx=\"4\"/><rect width=\"40\" height=\"8\" x=\"32\" y=\"20\" rx=\"4\"/></svg>"},"$:/core/images/fixed-height":{"title":"$:/core/images/fixed-height","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-fixed-height tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M60 35.657l-9.172 9.171a4 4 0 11-5.656-5.656l16-16a4 4 0 015.656 0l16 16a4 4 0 01-5.656 5.656L68 35.657v57.686l9.172-9.171a4 4 0 115.656 5.656l-16 16a4 4 0 01-5.656 0l-16-16a4 4 0 115.656-5.656L60 93.343V35.657zM16 116h96a4 4 0 100-8H16a4 4 0 100 8zm0-96h96a4 4 0 100-8H16a4 4 0 100 8z\"/></svg>"},"$:/core/images/fold-all-button":{"title":"$:/core/images/fold-all-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-fold-all tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><rect width=\"128\" height=\"16\" rx=\"8\"/><rect width=\"128\" height=\"16\" y=\"64\" rx=\"8\"/><path d=\"M64.03 20.004c-2.05 0-4.102.78-5.667 2.344L35.746 44.966c-3.125 3.124-3.13 8.194-.005 11.318 3.118 3.118 8.192 3.122 11.319-.005l16.965-16.965 16.966 16.965c3.124 3.125 8.194 3.13 11.318.005 3.118-3.118 3.122-8.191-.005-11.318L69.687 22.348a7.986 7.986 0 00-5.663-2.346zM64.03 85.002c-2.05-.001-4.102.78-5.667 2.344l-22.617 22.617c-3.125 3.125-3.13 8.195-.005 11.319 3.118 3.118 8.192 3.122 11.319-.005l16.965-16.966 16.966 16.966c3.124 3.125 8.194 3.13 11.318.005 3.118-3.118 3.122-8.192-.005-11.319L69.687 87.346A7.986 7.986 0 0064.024 85z\"/></g></svg>"},"$:/core/images/fold-button":{"title":"$:/core/images/fold-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-fold tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><rect width=\"128\" height=\"16\" rx=\"8\"/><path d=\"M64.03 25.004c-2.05 0-4.102.78-5.667 2.344L35.746 49.966c-3.125 3.124-3.13 8.194-.005 11.318 3.118 3.118 8.192 3.122 11.319-.005l16.965-16.965 16.966 16.965c3.124 3.125 8.194 3.13 11.318.005 3.118-3.118 3.122-8.191-.005-11.318L69.687 27.348a7.986 7.986 0 00-5.663-2.346zM64.005 67.379c-2.05 0-4.102.78-5.666 2.344L35.722 92.34c-3.125 3.125-3.13 8.195-.006 11.32 3.118 3.117 8.192 3.121 11.32-.006L64 86.69l16.965 16.965c3.125 3.125 8.195 3.13 11.319.005 3.118-3.118 3.122-8.192-.005-11.319L69.663 69.723A7.986 7.986 0 0064 67.377z\"/></g></svg>"},"$:/core/images/fold-others-button":{"title":"$:/core/images/fold-others-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-fold-others tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><rect width=\"128\" height=\"16\" y=\"56.031\" rx=\"8\"/><path d=\"M86.632 79.976c-2.05 0-4.102.78-5.666 2.345L64 99.286 47.034 82.321a7.986 7.986 0 00-5.662-2.346l.005.001c-2.05 0-4.102.78-5.666 2.345l-22.618 22.617c-3.124 3.125-3.129 8.195-.005 11.319 3.118 3.118 8.192 3.122 11.319-.005l16.966-16.966 16.965 16.966a7.986 7.986 0 005.663 2.346l-.005-.002c2.05 0 4.102-.78 5.666-2.344l16.965-16.966 16.966 16.966c3.125 3.124 8.194 3.129 11.319.005 3.118-3.118 3.122-8.192-.005-11.319L92.289 82.321a7.986 7.986 0 00-5.663-2.346zM86.7 48.024c-2.05 0-4.102-.78-5.666-2.345L64.07 28.714 47.103 45.679a7.986 7.986 0 01-5.663 2.346l.005-.001c-2.05 0-4.101-.78-5.666-2.345L13.162 23.062c-3.125-3.125-3.13-8.195-.005-11.319 3.118-3.118 8.192-3.122 11.319.005L41.44 28.714l16.966-16.966a7.986 7.986 0 015.662-2.346l-.005.002c2.05 0 4.102.78 5.666 2.344l16.966 16.966 16.966-16.966c3.124-3.124 8.194-3.129 11.318-.005 3.118 3.118 3.122 8.192-.005 11.319L92.358 45.679a7.986 7.986 0 01-5.663 2.346z\"/></g></svg>"},"$:/core/images/folder":{"title":"$:/core/images/folder","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-folder tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M55.694 128H8C3.58 128 0 124.414 0 119.996V48.004C0 43.584 3.584 40 7.999 40H16v-8c0-4.418 3.578-8 8-8h32a8 8 0 018 8v8h40.001c4.418 0 7.999 3.586 7.999 8.004V59.83l-8-.082v-7.749A4 4 0 0099.997 48H56V36c0-2.21-1.793-4-4.004-4H28.004A4 4 0 0024 36v12H12.003A4 4 0 008 52v64a4 4 0 004.003 4h46.76l-3.069 8z\"/><path d=\"M23.873 55.5h96.003c4.417 0 7.004 4.053 5.774 9.063l-13.344 54.374c-1.228 5.005-5.808 9.063-10.223 9.063H6.08c-4.417 0-7.003-4.053-5.774-9.063L13.65 64.563c1.228-5.005 5.808-9.063 10.223-9.063zm1.78 8.5h87.994c2.211 0 3.504 2.093 2.891 4.666l-11.12 46.668c-.614 2.577-2.902 4.666-5.115 4.666H12.31c-2.211 0-3.504-2.093-2.891-4.666l11.12-46.668C21.152 66.09 23.44 64 25.653 64z\"/></g></svg>"},"$:/core/images/full-screen-button":{"title":"$:/core/images/full-screen-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-full-screen-button tc-image-button\" viewBox=\"0 0 128 128\"><path d=\"M0 8a8 8 0 018-8h32a8 8 0 110 16H16v24a8 8 0 11-16 0V8zM128 120a8 8 0 01-8 8H88a8 8 0 110-16h24V88a8 8 0 1116 0v32zM8 128a8 8 0 01-8-8V88a8 8 0 1116 0v24h24a8 8 0 110 16H8zM120 0a8 8 0 018 8v32a8 8 0 11-16 0V16H88a8 8 0 110-16h32z\"/></svg>"},"$:/core/images/github":{"title":"$:/core/images/github","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-github tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M63.938 1.607c-35.336 0-63.994 28.69-63.994 64.084 0 28.312 18.336 52.329 43.768 60.802 3.202.59 4.37-1.388 4.37-3.088 0-1.518-.056-5.55-.087-10.897-17.802 3.871-21.558-8.591-21.558-8.591-2.911-7.404-7.108-9.375-7.108-9.375-5.81-3.973.44-3.895.44-3.895 6.424.453 9.803 6.606 9.803 6.606 5.709 9.791 14.981 6.963 18.627 5.322.582-4.138 2.236-6.963 4.063-8.564-14.211-1.617-29.153-7.117-29.153-31.672 0-6.995 2.495-12.718 6.589-17.195-.66-1.621-2.856-8.14.629-16.96 0 0 5.37-1.722 17.597 6.57 5.104-1.424 10.58-2.132 16.022-2.16 5.438.028 10.91.736 16.022 2.16 12.22-8.292 17.582-6.57 17.582-6.57 3.493 8.82 1.297 15.339.64 16.96 4.102 4.477 6.578 10.2 6.578 17.195 0 24.618-14.966 30.035-29.22 31.62 2.295 1.98 4.342 5.89 4.342 11.87 0 8.564-.079 15.476-.079 17.576 0 1.715 1.155 3.71 4.4 3.084 25.413-8.493 43.733-32.494 43.733-60.798 0-35.394-28.657-64.084-64.006-64.084\"/></svg>"},"$:/core/images/gitter":{"title":"$:/core/images/gitter","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-gitter tc-image-button\" viewBox=\"0 0 18 25\"><path d=\"M15 5h2v10h-2zM10 5h2v20h-2zM5 5h2v20H5zM0 0h2v15H0z\"/></svg>"},"$:/core/images/globe":{"title":"$:/core/images/globe","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-globe tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M72.811 37.128v2.554c0 2.196.978 6.881 0 8.832-1.466 2.928-4.65 3.54-6.394 5.867-1.182 1.577-4.618 10.601-3.69 12.92 3.969 9.922 11.534 3.187 17.962 9.293.864.821 2.887 2.273 3.296 3.296 3.29 8.223-7.576 15.009 3.757 26.3 1.245 1.24 3.813-3.817 4.079-4.614.852-2.563 6.725-5.45 9.088-7.053 2.02-1.37 4.873-2.667 6.328-4.745 2.27-3.244 1.48-7.514 3.098-10.745 2.139-4.274 3.828-9.635 5.998-13.966 3.898-7.781 4.721 2.093 5.067 2.439.358.357 1.011 0 1.517 0 .094 0 1.447.099 1.516 0 .65-.935-1.043-17.92-1.318-19.297-1.404-7.01-6.944-15.781-11.865-20.5-6.274-6.015-7.09-16.197-18.259-14.954-.204.022-5.084 10.148-7.777 13.512-3.728 4.657-2.47-4.153-6.526-4.153-.081 0-1.183-.103-1.253 0-.586.88-1.44 3.896-2.306 4.417-.265.16-1.722-.239-1.846 0-2.243 4.3 8.256 2.212 5.792 7.952-2.352 5.481-6.328-1.997-6.328 8.56M44.467 7.01c9.685 6.13.682 12.198 2.694 16.215 1.655 3.303 4.241 5.395 1.714 9.814-2.063 3.608-6.87 3.966-9.623 6.723-3.04 3.044-5.464 8.94-6.79 12.911-1.617 4.843 14.547 6.866 12.063 11.008-1.386 2.311-6.746 1.466-8.437.198-1.165-.873-3.593-.546-4.417-1.78-2.613-3.915-2.26-8.023-3.625-12.128-.938-2.822-6.313-2.12-7.844-.593-.523.522-.33 1.792-.33 2.505 0 5.285 7.12 3.316 7.12 6.46 0 14.636 3.927 6.534 11.14 11.336 10.036 6.683 7.844 7.303 14.946 14.404 3.673 3.673 7.741 3.686 9.425 9.294 1.602 5.331-9.327 5.339-11.716 7.448-1.123.991-2.813 4.146-4.219 4.615-1.792.598-3.234.496-4.944 1.78-2.427 1.82-3.9 4.932-4.02 4.81-2.148-2.147-3.52-15.479-3.89-18.257-.588-4.42-5.59-5.54-6.986-9.03-1.57-3.927 1.524-9.52-1.129-13.761-6.52-10.424-11.821-14.5-15.35-26.292-.942-3.148 3.342-6.529 4.877-8.833 1.877-2.816 2.662-5.854 4.746-8.635C22.147 24.19 40.855 9.461 43.857 8.635l.61-1.625z\"/><path d=\"M64 126c34.242 0 62-27.758 62-62 0-34.242-27.758-62-62-62C29.758 2 2 29.758 2 64c0 34.242 27.758 62 62 62zm0-6c30.928 0 56-25.072 56-56S94.928 8 64 8 8 33.072 8 64s25.072 56 56 56z\"/></g></svg>"},"$:/core/images/heading-1":{"title":"$:/core/images/heading-1","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-heading-1 tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M14 30h13.25v30.104H61.7V30h13.25v75.684H61.7V71.552H27.25v34.132H14V30zm70.335 13.78c2.544 0 5.017-.212 7.42-.636 2.403-.424 4.576-1.13 6.52-2.12 1.942-.99 3.603-2.261 4.981-3.816 1.378-1.555 2.28-3.463 2.703-5.724h9.858v74.2h-13.25V53.32H84.335v-9.54z\"/></svg>"},"$:/core/images/heading-2":{"title":"$:/core/images/heading-2","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-heading-2 tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M6 30h13.25v30.104H53.7V30h13.25v75.684H53.7V71.552H19.25v34.132H6V30zm119.52 75.684H74.85c.07-6.148 1.555-11.519 4.452-16.112 2.897-4.593 6.855-8.586 11.872-11.978a133.725 133.725 0 017.526-5.141 59.6 59.6 0 007.208-5.353c2.19-1.908 3.993-3.975 5.406-6.201 1.413-2.226 2.155-4.788 2.226-7.685 0-1.343-.159-2.774-.477-4.293a11.357 11.357 0 00-1.855-4.24c-.919-1.307-2.19-2.403-3.816-3.286-1.625-.883-3.745-1.325-6.36-1.325-2.403 0-4.399.477-5.989 1.431-1.59.954-2.862 2.261-3.816 3.922-.954 1.66-1.66 3.622-2.12 5.883-.46 2.261-.724 4.7-.795 7.314H76.23c0-4.099.548-7.897 1.643-11.395 1.095-3.498 2.738-6.519 4.93-9.063 2.19-2.544 4.857-4.54 8.002-5.989C93.95 30.724 97.606 30 101.775 30c4.523 0 8.303.742 11.342 2.226 3.039 1.484 5.494 3.357 7.367 5.618 1.873 2.261 3.198 4.717 3.975 7.367.777 2.65 1.166 5.176 1.166 7.579 0 2.968-.46 5.653-1.378 8.056a25.942 25.942 0 01-3.71 6.625 37.5 37.5 0 01-5.3 5.565 79.468 79.468 0 01-6.148 4.77 165.627 165.627 0 01-6.36 4.24 94.28 94.28 0 00-5.883 4.028c-1.802 1.343-3.374 2.738-4.717 4.187-1.343 1.449-2.261 2.986-2.756 4.611h36.146v10.812z\"/></svg>"},"$:/core/images/heading-3":{"title":"$:/core/images/heading-3","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-heading-3 tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M6 30h13.25v30.104H53.7V30h13.25v75.684H53.7V71.552H19.25v34.132H6V30zm88.885 32.224c1.979.07 3.957-.07 5.936-.424 1.979-.353 3.745-.972 5.3-1.855a10.365 10.365 0 003.763-3.657c.954-1.555 1.431-3.463 1.431-5.724 0-3.18-1.078-5.724-3.233-7.632-2.155-1.908-4.929-2.862-8.32-2.862-2.12 0-3.958.424-5.513 1.272a11.318 11.318 0 00-3.869 3.445c-1.025 1.449-1.784 3.074-2.279 4.876a18.335 18.335 0 00-.636 5.565H75.381c.141-3.604.813-6.943 2.014-10.017 1.201-3.074 2.844-5.742 4.93-8.003 2.084-2.261 4.61-4.028 7.578-5.3C92.871 30.636 96.228 30 99.973 30a29.2 29.2 0 018.533 1.272c2.791.848 5.3 2.085 7.526 3.71s4.01 3.692 5.353 6.201c1.343 2.509 2.014 5.388 2.014 8.639 0 3.745-.848 7.014-2.544 9.805-1.696 2.791-4.346 4.823-7.95 6.095v.212c4.24.848 7.544 2.95 9.911 6.307s3.551 7.438 3.551 12.243c0 3.533-.707 6.696-2.12 9.487a21.538 21.538 0 01-5.724 7.102c-2.403 1.943-5.194 3.445-8.374 4.505-3.18 1.06-6.537 1.59-10.07 1.59-4.31 0-8.074-.618-11.289-1.855s-5.9-2.986-8.056-5.247c-2.155-2.261-3.798-4.982-4.929-8.162-1.13-3.18-1.731-6.713-1.802-10.6h12.084c-.141 4.523.972 8.286 3.34 11.289 2.366 3.003 5.917 4.505 10.652 4.505 4.028 0 7.402-1.148 10.123-3.445 2.72-2.297 4.081-5.565 4.081-9.805 0-2.897-.565-5.194-1.696-6.89a10.97 10.97 0 00-4.452-3.869c-1.837-.883-3.904-1.431-6.2-1.643a58.067 58.067 0 00-7.05-.212v-9.01z\"/></svg>"},"$:/core/images/heading-4":{"title":"$:/core/images/heading-4","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-heading-4 tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M8 30h13.25v30.104H55.7V30h13.25v75.684H55.7V71.552H21.25v34.132H8V30zm76.59 48.548h22.471V45.9h-.212L84.59 78.548zm43.46 9.54h-9.54v17.596H107.06V88.088h-31.8V76.11l31.8-44.626h11.448v47.064h9.54v9.54z\"/></svg>"},"$:/core/images/heading-5":{"title":"$:/core/images/heading-5","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-heading-5 tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M6 30h13.25v30.104H53.7V30h13.25v75.684H53.7V71.552H19.25v34.132H6V30zm77.755 1.484h38.372v10.812H92.765L88.95 61.164l.212.212c1.625-1.837 3.692-3.233 6.201-4.187 2.509-.954 5-1.431 7.473-1.431 3.675 0 6.96.618 9.858 1.855 2.897 1.237 5.335 2.968 7.314 5.194s3.48 4.858 4.505 7.897c1.025 3.039 1.537 6.325 1.537 9.858 0 2.968-.477 6.024-1.43 9.169a25.161 25.161 0 01-4.559 8.586c-2.085 2.58-4.752 4.7-8.003 6.36-3.25 1.66-7.137 2.491-11.66 2.491-3.604 0-6.943-.477-10.017-1.431-3.074-.954-5.777-2.385-8.109-4.293-2.332-1.908-4.187-4.258-5.565-7.049-1.378-2.791-2.138-6.06-2.279-9.805h12.084c.353 4.028 1.731 7.12 4.134 9.275 2.403 2.155 5.583 3.233 9.54 3.233 2.544 0 4.7-.424 6.466-1.272 1.767-.848 3.198-2.014 4.293-3.498 1.095-1.484 1.873-3.215 2.332-5.194.46-1.979.69-4.099.69-6.36 0-2.05-.284-4.01-.849-5.883-.565-1.873-1.413-3.516-2.544-4.929-1.13-1.413-2.597-2.544-4.399-3.392-1.802-.848-3.904-1.272-6.307-1.272-2.544 0-4.929.477-7.155 1.431-2.226.954-3.834 2.738-4.823 5.353H75.805l7.95-40.598z\"/></svg>"},"$:/core/images/heading-6":{"title":"$:/core/images/heading-6","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-heading-6 tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M6 30h13.25v30.104H53.7V30h13.25v75.684H53.7V71.552H19.25v34.132H6V30zm106.587 20.246c-.283-3.039-1.36-5.494-3.233-7.367-1.873-1.873-4.399-2.809-7.579-2.809-2.19 0-4.08.406-5.67 1.219a12.435 12.435 0 00-4.029 3.233c-1.095 1.343-1.979 2.88-2.65 4.611a37.696 37.696 0 00-1.643 5.459 46.08 46.08 0 00-.9 5.671 722.213 722.213 0 00-.478 5.247l.212.212c1.625-2.968 3.87-5.176 6.731-6.625 2.862-1.449 5.954-2.173 9.275-2.173 3.675 0 6.96.636 9.858 1.908 2.897 1.272 5.353 3.021 7.367 5.247 2.014 2.226 3.551 4.858 4.611 7.897 1.06 3.039 1.59 6.325 1.59 9.858 0 3.604-.583 6.943-1.749 10.017-1.166 3.074-2.844 5.76-5.035 8.056-2.19 2.297-4.805 4.081-7.844 5.353-3.039 1.272-6.395 1.908-10.07 1.908-5.441 0-9.91-1.007-13.409-3.021-3.498-2.014-6.254-4.77-8.268-8.268-2.014-3.498-3.41-7.597-4.187-12.296-.777-4.7-1.166-9.77-1.166-15.211 0-4.452.477-8.94 1.431-13.462.954-4.523 2.526-8.639 4.717-12.349 2.19-3.71 5.07-6.731 8.64-9.063C92.676 31.166 97.075 30 102.304 30c2.968 0 5.76.495 8.374 1.484 2.615.99 4.93 2.367 6.943 4.134 2.014 1.767 3.657 3.887 4.93 6.36 1.271 2.473 1.978 5.23 2.12 8.268h-12.085zm-11.66 46.852c2.19 0 4.099-.442 5.724-1.325a12.869 12.869 0 004.081-3.445c1.095-1.413 1.908-3.056 2.438-4.929.53-1.873.795-3.798.795-5.777s-.265-3.887-.795-5.724c-.53-1.837-1.343-3.445-2.438-4.823-1.095-1.378-2.456-2.491-4.08-3.339-1.626-.848-3.534-1.272-5.725-1.272-2.19 0-4.116.406-5.777 1.219-1.66.813-3.056 1.908-4.187 3.286-1.13 1.378-1.979 2.986-2.544 4.823-.565 1.837-.848 3.78-.848 5.83 0 2.05.283 3.993.848 5.83.565 1.837 1.413 3.48 2.544 4.929a12.39 12.39 0 004.187 3.445c1.66.848 3.586 1.272 5.777 1.272z\"/></svg>"},"$:/core/images/help":{"title":"$:/core/images/help","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-help tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M36.055 111.441c-5.24 4.396-15.168 7.362-26.555 7.362-1.635 0-3.24-.06-4.806-.179 7.919-2.64 14.062-8.6 16.367-16.014C8.747 92.845 1.05 78.936 1.05 63.5c0-29.547 28.206-53.5 63-53.5s63 23.953 63 53.5-28.206 53.5-63 53.5c-10.055 0-19.56-2-27.994-5.559zm35.35-33.843a536.471 536.471 0 00.018-4.682 199.02 199.02 0 00-.023-3.042c.008-1.357.595-2.087 3.727-4.235.112-.077 1.085-.74 1.386-.948 3.093-2.133 5.022-3.786 6.762-6.187 2.34-3.228 3.558-7.077 3.558-11.649 0-13.292-9.86-21.952-21.455-21.952-11.103 0-22.499 9.609-24.066 22.295a6.023 6.023 0 1011.956 1.477c.806-6.527 6.972-11.726 12.11-11.726 5.265 0 9.408 3.64 9.408 9.906 0 3.634-1.1 5.153-5.111 7.919l-1.362.93c-2.682 1.84-4.227 3.1-5.7 4.931-2.109 2.62-3.242 5.717-3.258 9.314.013.892.02 1.86.022 2.981a470.766 470.766 0 01-.022 4.943 6.023 6.023 0 1012.046.12l.003-.395zm-6.027 24.499a7.529 7.529 0 100-15.058 7.529 7.529 0 000 15.058z\"/></svg>"},"$:/core/images/home-button":{"title":"$:/core/images/home-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-home-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M112.985 119.502c.01-.165.015-.331.015-.499V67.568c3.137 2.948 8.076 2.884 11.134-.174a7.999 7.999 0 00-.002-11.316L70.396 2.343A7.978 7.978 0 0064.734 0a7.957 7.957 0 00-5.656 2.343L33 28.42V8.007C33 3.585 29.41 0 25 0c-4.418 0-8 3.59-8 8.007V44.42L5.342 56.078c-3.125 3.125-3.12 8.198-.002 11.316a7.999 7.999 0 0011.316-.003l.344-.343v52.945a8.11 8.11 0 000 .007c0 4.418 3.588 8 8 8h80c4.419 0 8-3.59 8-8a8.11 8.11 0 00-.015-.498zM97 112V51.574L64.737 19.31 33 51.048V112h64z\"/></svg>"},"$:/core/images/import-button":{"title":"$:/core/images/import-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-import-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M114.832 60.436s3.235-3.27 6.921.417c3.686 3.686.231 7.14.231 7.14l-42.153 42.92s-30.765 32.367-58.798 4.333C-7 87.213 24.59 55.623 24.59 55.623L67.363 12.85s22.725-24.6 43.587-3.738c20.862 20.862-3.96 43.09-3.96 43.09l-35.04 35.04S49.903 112.546 36.426 99.07c-13.476-13.477 11.83-35.523 11.83-35.523l35.04-35.04s3.902-3.902 7.78-.023c3.879 3.878.118 7.921.118 7.921l-35.04 35.04s-13.212 13.212-8.872 17.551c4.34 4.34 16.77-9.653 16.77-9.653l35.04-35.04s16.668-14.598 3.966-27.3c-13.893-13.892-27.565 3.702-27.565 3.702l-42.91 42.91s-23.698 23.698-3.658 43.738 43.012-4.385 43.012-4.385l42.895-42.533z\"/></svg>"},"$:/core/images/info-button":{"title":"$:/core/images/info-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-info-button tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\" transform=\"translate(.05)\"><path d=\"M64 128c35.346 0 64-28.654 64-64 0-35.346-28.654-64-64-64C28.654 0 0 28.654 0 64c0 35.346 28.654 64 64 64zm0-16c26.51 0 48-21.49 48-48S90.51 16 64 16 16 37.49 16 64s21.49 48 48 48z\"/><circle cx=\"64\" cy=\"32\" r=\"8\"/><rect width=\"16\" height=\"56\" x=\"56\" y=\"48\" rx=\"8\"/></g></svg>"},"$:/core/images/input-button":{"title":"$:/core/images/input-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-input-button tc-image-button\" viewBox=\"0 0 22 22\"><path d=\"M1.375 22h19.249c.365 0 .716-.145.973-.404v.001c.258-.257.404-.607.403-.972v-11a1.376 1.376 0 0 0-2.75 0v9.625H2.75V9.625a1.376 1.376 0 0 0-2.75 0v11C0 21.384.617 22 1.375 22Z\"/><path d=\"m9.732 11.904-1.541-1.541a1.375 1.375 0 1 0-1.944 1.944l3.887 3.888c.258.258.608.402.973.402h-.001c.353 0 .705-.134.974-.402l3.888-3.889a1.376 1.376 0 0 0 .001-1.944 1.377 1.377 0 0 0-1.946 0l-1.541 1.542V1.376a1.375 1.375 0 1 0-2.75 0v10.528Z\"/></svg>"},"$:/core/images/italic":{"title":"$:/core/images/italic","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-italic tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M66.711 0h22.41L62.408 128H40z\"/></svg>"},"$:/core/images/layout-button":{"title":"$:/core/images/layout-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-layout-button tc-image-button\" viewBox=\"0 0 24 24\" stroke-width=\"1\" stroke=\"none\"><path d=\"M0 0h24v24H0z\" fill=\"none\"/><rect x=\"2\" y=\"2\" width=\"7\" height=\"7\" rx=\"2\"/><rect x=\"2\" y=\"13\" width=\"7\" height=\"9\" rx=\"2\"/><rect x=\"12\" y=\"2\" width=\"10\" height=\"20\" rx=\"2\"/></svg>"},"$:/core/images/left-arrow":{"title":"$:/core/images/left-arrow","created":"20150315234410875","modified":"20150315235324760","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-left-arrow tc-image-button\" viewBox=\"0 0 128 128\"><path d=\"M0 64.177c0-2.026.771-4.054 2.317-5.6l55.98-55.98a7.92 7.92 0 0111.195.001c3.086 3.085 3.092 8.104.001 11.195L19.111 64.175l50.382 50.382a7.92 7.92 0 010 11.195c-3.086 3.086-8.105 3.092-11.196.001l-55.98-55.98A7.892 7.892 0 010 64.177z\"/></svg>"},"$:/core/images/line-width":{"title":"$:/core/images/line-width","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-line-width tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M16 18h96a2 2 0 000-4H16a2 2 0 100 4zm0 17h96a4 4 0 100-8H16a4 4 0 100 8zm0 21h96a6 6 0 000-12H16a6 6 0 100 12zm0 29h96c5.523 0 10-4.477 10-10s-4.477-10-10-10H16c-5.523 0-10 4.477-10 10s4.477 10 10 10zm0 43h96c8.837 0 16-7.163 16-16s-7.163-16-16-16H16c-8.837 0-16 7.163-16 16s7.163 16 16 16z\"/></svg>"},"$:/core/images/link":{"title":"$:/core/images/link","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-link tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M42.263 69.38a31.919 31.919 0 006.841 10.13c12.5 12.5 32.758 12.496 45.255 0l22.627-22.628c12.502-12.501 12.497-32.758 0-45.255-12.5-12.5-32.758-12.496-45.254 0L49.104 34.255a32.333 32.333 0 00-2.666 3.019 36.156 36.156 0 0121.94.334l14.663-14.663c6.25-6.25 16.382-6.254 22.632-.004 6.248 6.249 6.254 16.373-.004 22.631l-22.62 22.62c-6.25 6.25-16.381 6.254-22.631.004a15.93 15.93 0 01-4.428-8.433 11.948 11.948 0 00-7.59 3.48l-6.137 6.137z\"/><path d=\"M86.35 59.234a31.919 31.919 0 00-6.84-10.13c-12.5-12.5-32.758-12.497-45.255 0L11.627 71.732c-12.501 12.5-12.496 32.758 0 45.254 12.5 12.5 32.758 12.497 45.255 0L79.51 94.36a32.333 32.333 0 002.665-3.02 36.156 36.156 0 01-21.94-.333l-14.663 14.663c-6.25 6.25-16.381 6.253-22.63.004-6.25-6.249-6.255-16.374.003-22.632l22.62-22.62c6.25-6.25 16.381-6.253 22.631-.003a15.93 15.93 0 014.428 8.432 11.948 11.948 0 007.59-3.48l6.137-6.136z\"/></g></svg>"},"$:/core/images/linkify":{"title":"$:/core/images/linkify","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-linkify-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M17.031 31.919H9.048V96.85h7.983v6.92H0V25h17.031v6.919zm24.66 0h-7.983V96.85h7.983v6.92H24.66V25h17.03v6.919zM67.77 56.422l11.975-3.903 2.306 7.096-12.063 3.903 7.628 10.379-6.12 4.435-7.63-10.467-7.45 10.2-5.943-4.523L58.1 63.518 45.95 59.35l2.306-7.096 12.064 4.17V43.825h7.45v12.596zM86.31 96.85h7.982V31.92H86.31V25h17.031v78.77H86.31v-6.92zm24.659 0h7.983V31.92h-7.983V25H128v78.77h-17.031v-6.92z\"/></svg>"},"$:/core/images/list-bullet":{"title":"$:/core/images/list-bullet","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-list-bullet tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M11.636 40.273c6.427 0 11.637-5.21 11.637-11.637C23.273 22.21 18.063 17 11.636 17 5.21 17 0 22.21 0 28.636c0 6.427 5.21 11.637 11.636 11.637zm0 34.909c6.427 0 11.637-5.21 11.637-11.637 0-6.426-5.21-11.636-11.637-11.636C5.21 51.91 0 57.12 0 63.545c0 6.427 5.21 11.637 11.636 11.637zm0 34.909c6.427 0 11.637-5.21 11.637-11.636 0-6.427-5.21-11.637-11.637-11.637C5.21 86.818 0 92.028 0 98.455c0 6.426 5.21 11.636 11.636 11.636zM34.91 22.818H128v11.637H34.91V22.818zm0 34.91H128v11.636H34.91V57.727zm0 34.908H128v11.637H34.91V92.636z\"/></svg>"},"$:/core/images/list-number":{"title":"$:/core/images/list-number","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-list-number tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M33.84 22.356H128v11.77H33.84v-11.77zm0 35.31H128v11.77H33.84v-11.77zm0 35.311H128v11.77H33.84v-11.77zM.38 42.631v-2.223h.998c.826 0 1.445-.14 1.858-.42.413-.28.619-.948.619-2.002V22.769c0-1.442-.193-2.336-.58-2.683-.385-.347-1.477-.52-3.275-.52v-2.143c3.502-.147 6.252-.955 8.25-2.423h2.117v22.865c0 .921.15 1.575.449 1.963.3.387.949.58 1.948.58h.998v2.223H.38zm-.3 35.356v-1.902c7.19-6.554 10.786-12.58 10.786-18.08 0-1.562-.326-2.81-.979-3.744-.652-.934-1.524-1.402-2.616-1.402-.893 0-1.655.317-2.287.952-.633.634-.95 1.364-.95 2.192 0 .974.247 1.829.74 2.563.106.16.16.28.16.36 0 .147-.16.28-.48.4-.213.08-.752.308-1.618.681-.839.374-1.358.561-1.558.561-.24 0-.512-.37-.819-1.111A6.2 6.2 0 010 57.064c0-1.949.849-3.544 2.547-4.785 1.698-1.242 3.798-1.862 6.302-1.862 2.463 0 4.53.67 6.202 2.012 1.67 1.341 2.506 3.093 2.506 5.256a8.644 8.644 0 01-.849 3.724c-.566 1.201-1.92 3.053-4.064 5.556a165.471 165.471 0 01-6.272 6.938h11.445l-1.019 5.726h-2.117c.08-.28.12-.534.12-.76 0-.388-.1-.631-.3-.731-.2-.1-.599-.15-1.198-.15H.08zm12.124 19.207c1.745.04 3.236.637 4.474 1.792 1.239 1.154 1.858 2.773 1.858 4.855 0 2.99-1.132 5.393-3.396 7.208-2.263 1.815-5 2.723-8.209 2.723-2.01 0-3.669-.384-4.974-1.151C.652 111.853 0 110.849 0 109.607c0-.774.27-1.398.809-1.872.54-.474 1.128-.71 1.768-.71.639 0 1.162.2 1.568.6.406.4.782 1.055 1.128 1.962.466 1.268 1.239 1.902 2.317 1.902 1.265 0 2.287-.477 3.066-1.431.78-.955 1.169-2.686 1.169-5.196 0-1.709-.12-3.023-.36-3.944-.24-.921-.792-1.382-1.658-1.382-.586 0-1.185.307-1.797.921-.493.494-.932.741-1.319.741-.333 0-.602-.147-.809-.44-.206-.294-.31-.574-.31-.841 0-.32.104-.594.31-.821.207-.227.69-.594 1.449-1.102 2.876-1.922 4.314-4.017 4.314-6.287 0-1.188-.306-2.092-.919-2.713a3.001 3.001 0 00-2.217-.93c-.799 0-1.525.263-2.177.79-.653.528-.979 1.158-.979 1.892 0 .641.253 1.235.76 1.782.172.2.259.367.259.5 0 .121-.57.428-1.708.922-1.139.494-1.854.74-2.147.74-.413 0-.75-.333-1.009-1-.26-.668-.39-1.282-.39-1.842 0-1.749.93-3.224 2.787-4.425 1.858-1.202 3.965-1.802 6.322-1.802 2.064 0 3.851.447 5.363 1.341 1.511.895 2.267 2.116 2.267 3.664 0 1.362-.57 2.623-1.708 3.784a13.387 13.387 0 01-3.945 2.784z\"/></svg>"},"$:/core/images/list":{"title":"$:/core/images/list","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-list tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M87.748 128H23.999c-4.418 0-7.999-3.59-7.999-8.007V8.007C16 3.585 19.588 0 24 0h80c4.419 0 8 3.59 8 8.007V104H91.25c-.965 0-1.84.392-2.473 1.025a3.476 3.476 0 00-1.029 2.476V128zm8-.12l15.88-15.88h-15.88v15.88zM40 15.508A3.502 3.502 0 0143.5 12h55c1.933 0 3.5 1.561 3.5 3.509v.982A3.502 3.502 0 0198.5 20h-55a3.498 3.498 0 01-3.5-3.509v-.982zM32 22a6 6 0 100-12 6 6 0 000 12zm8 9.509A3.502 3.502 0 0143.5 28h55c1.933 0 3.5 1.561 3.5 3.509v.982A3.502 3.502 0 0198.5 36h-55a3.498 3.498 0 01-3.5-3.509v-.982zm0 16A3.502 3.502 0 0143.5 44h55c1.933 0 3.5 1.561 3.5 3.509v.982A3.502 3.502 0 0198.5 52h-55a3.498 3.498 0 01-3.5-3.509v-.982zm0 16A3.502 3.502 0 0143.5 60h55c1.933 0 3.5 1.561 3.5 3.509v.982A3.502 3.502 0 0198.5 68h-55a3.498 3.498 0 01-3.5-3.509v-.982zm0 16A3.502 3.502 0 0143.5 76h55c1.933 0 3.5 1.561 3.5 3.509v.982A3.502 3.502 0 0198.5 84h-55a3.498 3.498 0 01-3.5-3.509v-.982zm0 16A3.502 3.502 0 0143.5 92h55c1.933 0 3.5 1.561 3.5 3.509v.982A3.502 3.502 0 0198.5 100h-55a3.498 3.498 0 01-3.5-3.509v-.982zm0 16A3.505 3.505 0 0143.497 108h33.006A3.497 3.497 0 0180 111.509v.982A3.505 3.505 0 0176.503 116H43.497A3.497 3.497 0 0140 112.491v-.982zM32 38a6 6 0 100-12 6 6 0 000 12zm0 16a6 6 0 100-12 6 6 0 000 12zm0 16a6 6 0 100-12 6 6 0 000 12zm0 16a6 6 0 100-12 6 6 0 000 12zm0 16a6 6 0 100-12 6 6 0 000 12zm0 16a6 6 0 100-12 6 6 0 000 12z\"/></svg>"},"$:/core/images/locked-padlock":{"title":"$:/core/images/locked-padlock","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-locked-padlock tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M96.472 64H105v32.01C105 113.674 90.674 128 73.001 128H56C38.318 128 24 113.677 24 96.01V64h8c.003-15.723.303-47.731 32.16-47.731 31.794 0 32.305 32.057 32.312 47.731zm-15.897 0H48.44c.002-16.287.142-32 15.719-32 15.684 0 16.977 16.136 16.415 32zM67.732 92.364A8.503 8.503 0 0064.5 76a8.5 8.5 0 00-3.498 16.25l-5.095 22.77H72.8l-5.07-22.656z\"/></svg>"},"$:/core/images/mail":{"title":"$:/core/images/mail","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-mail tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M122.827 104.894a7.986 7.986 0 01-2.834.516H8.007c-.812 0-1.597-.12-2.335-.345l34.163-34.163 20.842 20.842a3.998 3.998 0 003.418 1.134 4.003 4.003 0 003.395-1.134L88.594 70.64c.075.09.155.176.24.26l33.993 33.994zm5.076-6.237c.064-.406.097-.823.097-1.247v-64c0-.669-.082-1.318-.237-1.94L94.23 65.006c.09.075.177.154.261.239l33.413 33.413zm-127.698.56A8.023 8.023 0 010 97.41v-64c0-.716.094-1.41.271-2.071l33.907 33.906L.205 99.218zM5.93 25.684a8.012 8.012 0 012.078-.273h111.986c.766 0 1.507.108 2.209.308L64.083 83.837 5.93 25.683z\"/></svg>"},"$:/core/images/mastodon":{"title":"$:/core/images/mastodon","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-mastodon tc-image-button\" viewBox=\"0 0 128 128\">\n  <path d=\"M112.716,76.735C111.231,85.764 99.411,95.646 85.836,97.561C78.757,98.559 71.787,99.476 64.355,99.073C52.201,98.415 42.61,95.646 42.61,95.646C42.61,97.044 42.683,98.374 42.829,99.619C44.409,113.79 54.723,114.639 64.493,115.035C74.354,115.434 83.134,112.163 83.134,112.163L83.539,122.695C83.539,122.695 76.642,127.071 64.355,127.875C57.58,128.315 49.167,127.674 39.369,124.61C18.118,117.965 14.463,91.202 13.904,64.048C13.733,55.985 13.839,48.383 13.839,42.024C13.839,14.257 29.238,6.118 29.238,6.118C37.002,1.905 50.326,0.134 64.177,-0L64.517,-0C78.369,0.134 91.701,1.905 99.465,6.118C99.465,6.118 114.864,14.257 114.864,42.024C114.864,42.024 115.057,62.511 112.716,76.735ZM96.7,44.179C96.7,37.307 95.219,31.847 92.245,27.807C89.177,23.767 85.16,21.696 80.174,21.696C74.403,21.696 70.034,24.316 67.146,29.556L64.337,35.118L61.529,29.556C58.64,24.316 54.271,21.696 48.501,21.696C43.514,21.696 39.497,23.767 36.43,27.807C33.455,31.847 31.974,37.307 31.974,44.179L31.974,77.8L43.249,77.8L43.249,45.167C43.249,38.288 45.699,34.796 50.599,34.796C56.017,34.796 58.733,38.938 58.733,47.128L58.733,64.99L69.941,64.99L69.941,47.128C69.941,38.938 72.657,34.796 78.075,34.796C82.975,34.796 85.425,38.288 85.425,45.167L85.425,77.8L96.7,77.8L96.7,44.179Z\"/>\n</svg>\n"},"$:/core/images/menu-button":{"title":"$:/core/images/menu-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-menu-button tc-image-button\" viewBox=\"0 0 128 128\"><rect width=\"128\" height=\"16\" y=\"16\" rx=\"8\"/><rect width=\"128\" height=\"16\" y=\"56\" rx=\"8\"/><rect width=\"128\" height=\"16\" y=\"96\" rx=\"8\"/></svg>"},"$:/core/images/minus-button":{"title":"$:/core/images/minus-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-minus-button tc-image-button\" viewBox=\"0 0 128 128\"><path d=\"M64 0c35.346 0 64 28.654 64 64 0 35.346-28.654 64-64 64-35.346 0-64-28.654-64-64C0 28.654 28.654 0 64 0zm.332 16c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48z\"/><rect width=\"80\" height=\"16\" x=\"24\" y=\"56\" rx=\"8\"/></svg>"},"$:/core/images/mono-block":{"title":"$:/core/images/mono-block","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-mono-block tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M23.965 32.967h.357c.755 0 1.328.192 1.72.577.39.384.586.947.586 1.688 0 .824-.206 1.418-.618 1.782-.413.363-1.094.545-2.045.545h-6.31c-.965 0-1.65-.178-2.056-.535-.405-.356-.608-.954-.608-1.792 0-.811.203-1.391.608-1.74.406-.35 1.09-.525 2.055-.525h.734l-.86-2.453H8.471l-.902 2.453h.734c.95 0 1.632.178 2.044.535.413.356.619.933.619 1.73 0 .824-.206 1.418-.619 1.782-.412.363-1.094.545-2.044.545h-5.41c-.964 0-1.649-.182-2.054-.545-.406-.364-.608-.958-.608-1.782 0-.741.195-1.304.587-1.688.391-.385.964-.577 1.719-.577h.356l5.62-15.641H6.835c-.95 0-1.632-.182-2.044-.546-.412-.363-.619-.95-.619-1.76 0-.825.207-1.42.619-1.783.412-.363 1.094-.545 2.044-.545h7.863c1.244 0 2.118.67 2.62 2.013v.063l6.647 18.2zM12.98 17.326l-3.04 8.848h6.08l-3.04-8.848zm22.402 9.372v6.395h3.145c2.223 0 3.788-.245 4.697-.734.908-.49 1.362-1.307 1.362-2.453 0-1.16-.433-1.985-1.3-2.474-.866-.49-2.383-.734-4.55-.734h-3.354zm10.693-2.327c1.524.559 2.642 1.324 3.355 2.295.713.972 1.07 2.212 1.07 3.722 0 1.272-.308 2.432-.923 3.48-.615 1.049-1.496 1.909-2.642 2.58a7.499 7.499 0 01-2.254.849c-.832.174-2.01.262-3.533.262H30.202c-.922 0-1.583-.182-1.981-.545-.399-.364-.598-.958-.598-1.782 0-.741.189-1.304.566-1.688.378-.385.93-.577 1.657-.577h.356V17.326h-.356c-.727 0-1.28-.196-1.657-.587-.377-.392-.566-.965-.566-1.72 0-.81.203-1.401.608-1.771.406-.37 1.062-.556 1.971-.556h9.645c2.95 0 5.19.573 6.72 1.72 1.53 1.145 2.296 2.823 2.296 5.031 0 1.09-.234 2.052-.703 2.883-.468.832-1.163 1.513-2.086 2.045zM35.381 17.2v5.284h2.83c1.72 0 2.932-.203 3.638-.609.706-.405 1.06-1.09 1.06-2.054 0-.909-.319-1.573-.955-1.992-.636-.42-1.667-.63-3.093-.63h-3.48zm35.863-3.816c.28-.503.566-.86.86-1.07.293-.21.664-.314 1.111-.314.685 0 1.17.182 1.457.545.287.364.43.986.43 1.866l.042 5.452c0 .964-.157 1.614-.472 1.95-.314.335-.884.503-1.709.503-.587 0-1.037-.14-1.352-.42-.314-.28-.584-.796-.807-1.551-.364-1.328-.944-2.282-1.74-2.862-.797-.58-1.901-.87-3.313-.87-2.153 0-3.802.727-4.948 2.18-1.147 1.454-1.72 3.558-1.72 6.311 0 2.74.58 4.844 1.74 6.311 1.16 1.468 2.817 2.202 4.97 2.202 1.467 0 3.085-.49 4.854-1.468 1.768-.978 2.883-1.467 3.344-1.467.545 0 1.003.23 1.373.692.37.46.556 1.034.556 1.719 0 1.23-1.084 2.39-3.25 3.48-2.167 1.09-4.606 1.636-7.318 1.636-3.662 0-6.625-1.21-8.89-3.627-2.264-2.419-3.396-5.578-3.396-9.478 0-3.76 1.146-6.884 3.438-9.372 2.293-2.488 5.2-3.732 8.723-3.732.992 0 1.97.112 2.935.335.964.224 1.992.574 3.082 1.049zm10.22 19.583V17.326h-.356c-.755 0-1.328-.196-1.72-.587-.39-.392-.586-.965-.586-1.72 0-.81.21-1.401.629-1.771.42-.37 1.097-.556 2.034-.556h5.178c2.922 0 5.06.126 6.416.377 1.356.252 2.51.671 3.46 1.258 1.691 1.007 2.988 2.443 3.89 4.31.9 1.865 1.352 4.021 1.352 6.467 0 2.586-.514 4.847-1.541 6.783-1.028 1.936-2.485 3.4-4.372 4.393-.853.447-1.852.772-2.998.975-1.147.203-2.852.304-5.116.304h-6.269c-.965 0-1.65-.178-2.055-.535-.406-.356-.608-.954-.608-1.792 0-.741.195-1.304.587-1.688.391-.385.964-.577 1.72-.577h.356zm5.41-15.725v15.725h1.195c2.642 0 4.592-.646 5.85-1.94 1.258-1.292 1.887-3.28 1.887-5.965 0-2.641-.64-4.612-1.918-5.912-1.28-1.3-3.205-1.95-5.777-1.95-.335 0-.59.003-.765.01a7.992 7.992 0 00-.472.032zm35.067-.126h-9.75v5.368h3.69v-.252c0-.797.175-1.39.524-1.782.35-.392.88-.587 1.594-.587.629 0 1.142.178 1.54.534.4.357.598.808.598 1.353 0 .028.007.118.021.272.014.154.021.308.021.462v4.34c0 .936-.167 1.607-.503 2.013-.335.405-.88.608-1.635.608-.713 0-1.251-.19-1.615-.567-.363-.377-.545-.936-.545-1.677v-.377h-3.69v6.269h9.75v-2.495c0-.937.178-1.608.534-2.013.357-.405.94-.608 1.75-.608.798 0 1.367.2 1.71.597.342.399.513 1.073.513 2.024v5.074c0 .755-.146 1.258-.44 1.51-.293.251-.873.377-1.74.377h-17.172c-.923 0-1.583-.182-1.982-.545-.398-.364-.597-.958-.597-1.782 0-.741.189-1.304.566-1.688.377-.385.93-.577 1.656-.577h.357V17.326h-.357c-.712 0-1.261-.2-1.646-.598-.384-.398-.576-.968-.576-1.709 0-.81.203-1.401.608-1.771.405-.37 1.062-.556 1.97-.556h17.173c.853 0 1.43.13 1.73.388.3.258.45.772.45 1.54v4.698c0 .95-.174 1.631-.524 2.044-.35.412-.915.618-1.698.618-.81 0-1.394-.21-1.75-.629-.357-.419-.535-1.097-.535-2.033v-2.202zM19.77 47.641c.267-.504.55-.86.85-1.07.3-.21.675-.314 1.122-.314.685 0 1.17.181 1.457.545.287.363.43.985.43 1.866l.042 5.451c0 .965-.157 1.615-.472 1.95-.314.336-.891.504-1.73.504-.587 0-1.045-.144-1.373-.43-.329-.287-.598-.8-.807-1.541-.378-1.342-.958-2.3-1.74-2.873-.783-.573-1.88-.86-3.292-.86-2.153 0-3.799.727-4.938 2.181-1.14 1.454-1.709 3.557-1.709 6.311s.598 4.882 1.793 6.385C10.599 67.248 12.294 68 14.488 68c.503 0 1.077-.06 1.72-.179a23.809 23.809 0 002.264-.555v-3.313h-2.37c-.95 0-1.624-.175-2.023-.524-.398-.35-.597-.93-.597-1.74 0-.84.199-1.437.597-1.793.399-.357 1.073-.535 2.024-.535h7.569c.978 0 1.667.175 2.065.524.398.35.598.937.598 1.762 0 .74-.2 1.31-.598 1.708-.398.399-.975.598-1.73.598h-.335v5.242c0 .447-.05.758-.147.933-.098.174-.293.353-.587.534-.797.476-2.062.895-3.795 1.258a25.576 25.576 0 01-5.263.546c-3.662 0-6.625-1.21-8.89-3.628-2.264-2.418-3.397-5.577-3.397-9.477 0-3.76 1.147-6.884 3.44-9.372 2.292-2.488 5.199-3.732 8.721-3.732.979 0 1.954.112 2.925.335.972.224 2.003.573 3.093 1.049zm15.84 3.941v4.823h6.857v-4.823h-.336c-.754 0-1.331-.195-1.73-.587-.398-.391-.597-.964-.597-1.719 0-.825.206-1.419.619-1.782.412-.364 1.093-.545 2.044-.545h5.41c.95 0 1.624.181 2.023.545.398.363.597.957.597 1.782 0 .755-.192 1.328-.576 1.72-.385.39-.947.586-1.688.586h-.357v15.642h.357c.755 0 1.328.192 1.719.576.391.385.587.947.587 1.688 0 .825-.203 1.419-.608 1.782-.405.364-1.09.546-2.055.546h-5.41c-.964 0-1.649-.179-2.054-.535-.405-.357-.608-.954-.608-1.793 0-.74.2-1.303.598-1.688.398-.384.975-.576 1.73-.576h.335v-6.186h-6.856v6.186h.335c.755 0 1.331.192 1.73.576.398.385.597.947.597 1.688 0 .825-.206 1.419-.618 1.782-.412.364-1.094.546-2.044.546h-5.41c-.964 0-1.65-.179-2.055-.535-.405-.357-.608-.954-.608-1.793 0-.74.196-1.303.587-1.688.392-.384.965-.576 1.72-.576h.356V51.582h-.356c-.741 0-1.304-.195-1.688-.587-.385-.391-.577-.964-.577-1.719 0-.825.2-1.419.598-1.782.398-.364 1.073-.545 2.023-.545h5.41c.936 0 1.614.181 2.033.545.42.363.63.957.63 1.782 0 .755-.2 1.328-.598 1.72-.399.39-.975.586-1.73.586h-.335zm31.754 0v15.642h3.523c.95 0 1.632.178 2.044.534.412.357.618.933.618 1.73 0 .811-.21 1.402-.629 1.772-.419.37-1.097.556-2.033.556H58.433c-.95 0-1.632-.182-2.044-.546-.412-.363-.619-.957-.619-1.782 0-.81.203-1.39.608-1.74.406-.35 1.09-.524 2.055-.524h3.523V51.582h-3.523c-.95 0-1.632-.181-2.044-.545-.412-.363-.619-.95-.619-1.761 0-.825.203-1.412.608-1.761.406-.35 1.09-.524 2.055-.524h12.455c.992 0 1.684.174 2.075.524.392.35.587.936.587 1.761 0 .81-.202 1.398-.608 1.761-.405.364-1.09.545-2.054.545h-3.523zm30.496 0v11.994c0 1.873-.122 3.228-.367 4.067a5.876 5.876 0 01-1.227 2.244c-.74.852-1.768 1.495-3.082 1.929-1.314.433-2.893.65-4.738.65-1.3 0-2.555-.126-3.764-.378a16.843 16.843 0 01-3.491-1.132c-.615-.28-1.017-.643-1.206-1.09-.188-.448-.283-1.175-.283-2.18v-4.32c0-1.202.175-2.04.525-2.516.349-.475.957-.713 1.824-.713 1.244 0 1.929.915 2.054 2.747.014.321.035.566.063.733.168 1.622.545 2.73 1.133 3.324.587.594 1.523.89 2.81.89 1.593 0 2.714-.422 3.364-1.268.65-.845.975-2.386.975-4.623V51.582H88.93c-.95 0-1.632-.181-2.044-.545-.413-.363-.619-.95-.619-1.761 0-.825.2-1.412.598-1.761.398-.35 1.086-.524 2.065-.524h10.693c.979 0 1.667.174 2.065.524.399.35.598.936.598 1.761 0 .81-.206 1.398-.619 1.761-.412.364-1.093.545-2.044.545h-1.761zm14.644 0v6.353l6.48-6.478c-.728-.084-1.238-.29-1.531-.619-.294-.328-.44-.85-.44-1.562 0-.825.198-1.419.597-1.782.398-.364 1.073-.545 2.023-.545h5.137c.95 0 1.625.181 2.023.545.399.363.598.957.598 1.782 0 .769-.2 1.345-.598 1.73-.398.384-.982.576-1.75.576h-.483l-6.101 6.06c1.132.839 2.167 1.94 3.103 3.302.937 1.363 2.034 3.456 3.292 6.28h.692c.825 0 1.44.188 1.845.566.405.377.608.943.608 1.698 0 .825-.206 1.419-.619 1.782-.412.364-1.093.546-2.044.546h-2.579c-1.132 0-2.048-.762-2.746-2.286-.126-.28-.224-.503-.294-.67-.923-1.958-1.768-3.467-2.537-4.53a16.616 16.616 0 00-2.705-2.914l-1.97 1.887v3.92h.335c.755 0 1.331.193 1.73.577.398.385.597.947.597 1.688 0 .825-.206 1.419-.618 1.782-.413.364-1.094.546-2.045.546h-5.41c-.964 0-1.649-.179-2.054-.535-.405-.357-.608-.954-.608-1.793 0-.74.196-1.303.587-1.688.391-.384.965-.576 1.72-.576h.356V51.582h-.357c-.74 0-1.303-.195-1.687-.587-.385-.391-.577-.964-.577-1.719 0-.825.2-1.419.598-1.782.398-.364 1.072-.545 2.023-.545h5.41c.936 0 1.614.181 2.033.545.42.363.63.957.63 1.782 0 .755-.2 1.328-.598 1.72-.399.39-.975.586-1.73.586h-.336zM13.44 96.326l4.005-11.889c.251-.782.6-1.352 1.048-1.709.447-.356 1.041-.534 1.782-.534h3.271c.95 0 1.632.182 2.044.545.413.363.619.957.619 1.782 0 .755-.2 1.328-.598 1.72-.398.39-.975.587-1.73.587h-.335l.587 15.641h.357c.754 0 1.32.192 1.698.577.377.384.566.947.566 1.687 0 .825-.2 1.42-.598 1.783-.398.363-1.072.545-2.023.545h-4.718c-.95 0-1.624-.178-2.023-.535-.398-.356-.597-.954-.597-1.793 0-.74.192-1.303.576-1.687.385-.385.954-.577 1.709-.577h.335l-.293-12.79-3.061 9.52c-.224.712-.542 1.226-.954 1.54-.413.315-.982.472-1.709.472-.727 0-1.303-.157-1.73-.472-.426-.314-.751-.828-.975-1.54l-3.04-9.52-.294 12.79h.336c.755 0 1.324.192 1.709.577.384.384.576.947.576 1.687 0 .825-.202 1.42-.608 1.783-.405.363-1.076.545-2.013.545H2.621c-.937 0-1.608-.182-2.013-.545-.405-.364-.608-.958-.608-1.783 0-.74.192-1.303.577-1.687.384-.385.954-.577 1.708-.577h.336l.608-15.641h-.336c-.754 0-1.331-.196-1.73-.588-.398-.39-.597-.964-.597-1.719 0-.825.206-1.419.619-1.782.412-.363 1.093-.545 2.044-.545h3.27c.728 0 1.311.175 1.752.524.44.35.8.923 1.08 1.72l4.109 11.888zm30.454 2.054V86.828H42.74c-.922 0-1.583-.182-1.981-.546-.398-.363-.598-.95-.598-1.76 0-.812.2-1.402.598-1.773.398-.37 1.059-.555 1.981-.555h5.955c.909 0 1.566.185 1.97.555.406.37.609.961.609 1.772 0 .741-.192 1.31-.577 1.709-.384.398-.933.598-1.646.598h-.356v19.038c0 .657-.07 1.069-.21 1.237-.14.167-.454.251-.943.251h-2.097c-.67 0-1.143-.07-1.415-.21-.273-.14-.507-.384-.703-.733l-8.722-15.327v11.385h1.216c.909 0 1.559.175 1.95.524.392.35.587.93.587 1.74 0 .825-.199 1.42-.597 1.783-.399.363-1.045.545-1.94.545h-6.017c-.909 0-1.566-.182-1.971-.545-.406-.364-.608-.958-.608-1.783 0-.74.188-1.303.566-1.687.377-.385.936-.577 1.677-.577h.336V86.828h-.336c-.713 0-1.265-.2-1.656-.598-.392-.398-.587-.968-.587-1.709 0-.81.206-1.401.618-1.772.413-.37 1.066-.555 1.96-.555h3.44c.824 0 1.383.108 1.677.325.293.216.622.653.985 1.31l7.989 14.551zM64.66 86.366c-1.803 0-3.218.727-4.245 2.18-1.028 1.455-1.541 3.474-1.541 6.06 0 2.586.517 4.613 1.551 6.08 1.034 1.468 2.446 2.202 4.235 2.202 1.804 0 3.222-.73 4.257-2.19 1.034-1.461 1.551-3.492 1.551-6.092 0-2.586-.513-4.605-1.54-6.06-1.028-1.453-2.45-2.18-4.268-2.18zm0-4.864c3.44 0 6.27 1.23 8.492 3.69 2.223 2.46 3.334 5.598 3.334 9.414 0 3.844-1.104 6.99-3.313 9.436-2.208 2.446-5.046 3.669-8.513 3.669-3.424 0-6.255-1.234-8.491-3.701-2.237-2.467-3.355-5.602-3.355-9.404 0-3.83 1.108-6.971 3.323-9.424 2.216-2.454 5.057-3.68 8.523-3.68zM87.461 98.17v4.298h2.16c.908 0 1.555.175 1.94.524.384.35.576.93.576 1.74 0 .825-.196 1.42-.587 1.783-.392.363-1.035.545-1.93.545h-7.254c-.922 0-1.583-.182-1.981-.545-.399-.364-.598-.958-.598-1.783 0-.74.189-1.303.566-1.687.378-.385.93-.577 1.657-.577h.356V86.828h-.356c-.713 0-1.262-.2-1.646-.598-.385-.398-.577-.968-.577-1.709 0-.81.203-1.401.608-1.772.406-.37 1.063-.555 1.971-.555h8.66c3.424 0 6.014.657 7.768 1.97 1.754 1.315 2.631 3.25 2.631 5.809 0 2.697-.873 4.738-2.62 6.122-1.748 1.384-4.34 2.076-7.78 2.076h-3.564zm0-11.343v6.625h2.977c1.65 0 2.89-.28 3.722-.839.832-.559 1.248-1.397 1.248-2.516 0-1.048-.43-1.855-1.29-2.421-.86-.566-2.086-.85-3.68-.85h-2.977zm27.267 20.568l-1.636 1.636a12.37 12.37 0 011.772-.44c.58-.098 1.15-.147 1.709-.147 1.104 0 2.268.164 3.491.492 1.223.329 1.967.493 2.233.493.447 0 1.03-.15 1.75-.45.72-.301 1.206-.452 1.458-.452.517 0 .947.2 1.29.598.342.398.513.898.513 1.5 0 .796-.472 1.474-1.415 2.033-.944.56-2.1.839-3.47.839-.937 0-2.139-.22-3.607-.66-1.467-.441-2.53-.661-3.187-.661-.992 0-2.11.272-3.354.817-1.244.546-2.013.818-2.307.818a2.14 2.14 0 01-1.53-.597c-.42-.399-.63-.878-.63-1.437 0-.391.134-.807.4-1.247.265-.44.733-1.01 1.404-1.709l2.118-2.139c-2.335-.852-4.194-2.386-5.578-4.602-1.384-2.215-2.075-4.763-2.075-7.642 0-3.802 1.104-6.909 3.312-9.32 2.209-2.411 5.053-3.617 8.534-3.617 3.467 0 6.304 1.209 8.513 3.627 2.208 2.418 3.312 5.522 3.312 9.31 0 3.774-1.097 6.884-3.291 9.33-2.195 2.446-4.977 3.67-8.345 3.67a22.5 22.5 0 01-1.384-.043zm1.195-21.03c-1.803 0-3.218.727-4.246 2.18-1.027 1.455-1.54 3.474-1.54 6.06 0 2.586.516 4.613 1.55 6.08 1.035 1.468 2.447 2.202 4.236 2.202 1.803 0 3.222-.73 4.256-2.19 1.035-1.461 1.552-3.492 1.552-6.092 0-2.586-.514-4.605-1.541-6.06-1.028-1.453-2.45-2.18-4.267-2.18z\"/></svg>"},"$:/core/images/mono-line":{"title":"$:/core/images/mono-line","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-mono-line tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M60.437 84.523h.908c1.922 0 3.381.489 4.378 1.468.997.979 1.495 2.411 1.495 4.298 0 2.1-.525 3.612-1.575 4.538-1.05.925-2.785 1.388-5.206 1.388h-16.07c-2.456 0-4.2-.454-5.232-1.361-1.032-.908-1.548-2.43-1.548-4.565 0-2.065.516-3.542 1.548-4.432 1.032-.89 2.776-1.334 5.232-1.334h1.869l-2.19-6.247H20.983l-2.296 6.247h1.87c2.42 0 4.155.453 5.205 1.361 1.05.908 1.575 2.376 1.575 4.405 0 2.1-.525 3.612-1.575 4.538-1.05.925-2.785 1.388-5.206 1.388H6.781c-2.456 0-4.2-.463-5.233-1.388C.516 93.9 0 92.389 0 90.289c0-1.887.498-3.32 1.495-4.298.997-.979 2.456-1.468 4.378-1.468h.908l14.308-39.83h-4.271c-2.42 0-4.156-.462-5.206-1.387-1.05-.926-1.575-2.42-1.575-4.485 0-2.1.525-3.613 1.575-4.538 1.05-.926 2.785-1.388 5.206-1.388h20.021c3.168 0 5.392 1.708 6.674 5.125v.16l16.924 46.343zm-27.976-39.83L24.72 67.225h15.483l-7.742-22.53zM89.506 68.56v16.284h8.008c5.66 0 9.646-.623 11.96-1.869 2.313-1.245 3.47-3.328 3.47-6.246 0-2.955-1.103-5.055-3.31-6.3-2.207-1.246-6.069-1.869-11.586-1.869h-8.542zm27.229-5.926c3.88 1.423 6.727 3.372 8.542 5.846 1.815 2.474 2.723 5.633 2.723 9.477 0 3.239-.783 6.193-2.35 8.862-1.565 2.67-3.808 4.859-6.726 6.567-1.709.997-3.622 1.718-5.74 2.163-2.118.445-5.116.667-8.996.667h-27.87c-2.349 0-4.03-.463-5.045-1.388-1.014-.926-1.521-2.438-1.521-4.538 0-1.887.48-3.32 1.441-4.298.961-.979 2.367-1.468 4.218-1.468h.907v-39.83h-.907c-1.851 0-3.257-.498-4.218-1.494-.961-.997-1.441-2.456-1.441-4.378 0-2.065.516-3.568 1.548-4.512 1.032-.943 2.705-1.414 5.018-1.414h24.56c7.51 0 13.214 1.459 17.111 4.377 3.898 2.92 5.847 7.19 5.847 12.814 0 2.776-.597 5.223-1.789 7.341-1.192 2.118-2.963 3.853-5.312 5.206zm-27.23-18.26v13.455h7.208c4.378 0 7.466-.516 9.264-1.549 1.797-1.032 2.696-2.776 2.696-5.232 0-2.313-.81-4.004-2.43-5.072-1.619-1.068-4.244-1.602-7.874-1.602h-8.863z\"/></svg>"},"$:/core/images/network-activity":{"title":"$:/core/images/network-activity","tags":"$:/tags/Image","text":"<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-network-activity tc-image-button\" viewBox=\"0 0 128 128\"><g class={{{ [{$:/state/http-requests}match[0]then[]else[tc-network-activity-background]] }}}>\n<$list filter=\"[{$:/state/http-requests}match[0]]\" variable=\"ignore\">\n<path d=\"M64.043 45.153a4.002 4.002 0 0 1 4.367 2.21l.084.188 30.403 73.4a4 4 0 0 1-7.307 3.25l-.084-.188-3.103-7.49-8.898 8.899a3.985 3.985 0 0 1-2.624 1.166l-.205.005a3.987 3.987 0 0 1-2.828-1.171l-9.849-9.848-9.847 9.848a3.985 3.985 0 0 1-2.624 1.166l-.204.005a3.987 3.987 0 0 1-2.829-1.171l-8.899-8.9-3.102 7.491a4 4 0 1 1-7.391-3.062l30.403-73.4a4.001 4.001 0 0 1 4.495-2.39l.042-.008Zm13.636 56.74-8.023 8.024 7.02 7.019 8.023-8.022-7.02-7.02Zm-27.353.008-7.019 7.019 8.016 8.016 7.019-7.02-8.016-8.015Zm13.68-13.68-8.023 8.023 8.016 8.016 8.023-8.023-8.016-8.016Zm-8.971-8.971-4.687 11.315 8.001-8.001-3.314-3.314Zm17.933.009-3.305 3.305 7.979 7.979-4.674-11.284ZM64 57.607l-5.666 13.68c.096.072.188.15.278.232l.133.126 5.261 5.262 5.262-5.262c.128-.127.261-.244.4-.35L64 57.607Zm0-34.69a8 8 0 1 1 0 16 8 8 0 0 1 0-16Z\"/>\n</$list>\n<$list filter=\"[{$:/state/http-requests}!match[0]]\" variable=\"ignore\">\n<path d=\"M109.395.952a4.002 4.002 0 0 1 3.787 2.708C117.529 11.62 120 20.753 120 30.462c0 15.186-6.044 28.96-15.858 39.047a4 4 0 1 1-6.47-4.626l-.12-.094C106.466 56.074 112 43.914 112 30.462c0-8.492-2.205-16.469-6.074-23.39l.054-.036a4 4 0 0 1 3.415-6.084Zm-90.762 0a4 4 0 0 1 3.072 6.562l.093.06A47.786 47.786 0 0 0 16 30.463c0 13.315 5.42 25.363 14.176 34.058l-.01.007a4 4 0 1 1-6.312 4.863l-.063.05C14.017 59.359 8 45.613 8 30.462c0-9.77 2.502-18.956 6.9-26.952A4.002 4.002 0 0 1 18.634.952Z\"/><path d=\"M64.043 44.698a4.002 4.002 0 0 1 4.367 2.21l.084.188 30.403 73.4a4 4 0 0 1-7.307 3.25l-.084-.188-3.103-7.49-8.898 8.9a3.985 3.985 0 0 1-2.624 1.166l-.205.005a3.987 3.987 0 0 1-2.828-1.172l-9.849-9.848-9.847 9.848a3.985 3.985 0 0 1-2.624 1.167l-.204.005a3.987 3.987 0 0 1-2.829-1.172l-8.899-8.899-3.102 7.49a4 4 0 0 1-7.391-3.061l30.403-73.4a4.001 4.001 0 0 1 4.495-2.39l.042-.009ZM77.68 101.44l-8.023 8.023 7.02 7.019 8.023-8.022-7.02-7.02Zm-27.353.007-7.019 7.019 8.016 8.016 7.019-7.019-8.016-8.016Zm13.68-13.68-8.023 8.023 8.016 8.016 8.023-8.023-8.016-8.016Zm-8.971-8.971L50.348 90.11l8.001-8.001-3.314-3.314Zm17.933.009-3.305 3.305 7.979 7.979-4.674-11.284ZM64 57.152l-5.666 13.68c.096.073.188.15.278.232l.133.127 5.261 5.261 5.262-5.261c.128-.128.261-.244.4-.351L64 57.152ZM38.503 1.058a4 4 0 0 1 2.7 6.952l.17-.175C35.582 13.625 32 21.625 32 30.462c0 8.838 3.582 16.838 9.374 22.629a4 4 0 0 1-5.659 5.658l-.01.01C28.473 51.52 24 41.526 24 30.485 24 19.567 28.374 9.67 35.466 2.453a3.995 3.995 0 0 1 3.037-1.395ZM89.369.952c1.14 0 2.17.478 2.899 1.244l.005-.006C99.518 9.43 104 19.434 104 30.485c0 10.826-4.3 20.648-11.287 27.85a4 4 0 1 1-6.054-5.213l-.032-.032C92.418 47.299 96 39.299 96 30.462c0-8.73-3.496-16.643-9.164-22.416A4 4 0 0 1 89.368.952Zm-39.282 11.14a4 4 0 0 1 2.59 7.048l.01.009A15.95 15.95 0 0 0 48 30.462a15.95 15.95 0 0 0 4.687 11.315l-.01.01a4 4 0 1 1-5.82 5.47l.173.177A23.925 23.925 0 0 1 40 30.462a23.925 23.925 0 0 1 7.03-16.97l.01.01a3.991 3.991 0 0 1 3.047-1.41Zm27.895.07a3.99 3.99 0 0 1 2.984 1.336l.006-.005A23.925 23.925 0 0 1 88 30.463a23.92 23.92 0 0 1-6.707 16.642l-.3.305a4 4 0 1 1-5.679-5.632v-.002A15.95 15.95 0 0 0 80 30.462a15.95 15.95 0 0 0-4.685-11.312 4.012 4.012 0 0 1-1.333-2.987 4 4 0 0 1 4-4ZM64 22.463a8 8 0 1 1 0 16 8 8 0 0 1 0-16Z\"/>\n</$list>\n</g></svg>"},"$:/core/images/new-button":{"title":"$:/core/images/new-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-new-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M56 72H8.007C3.591 72 0 68.418 0 64c0-4.41 3.585-8 8.007-8H56V8.007C56 3.591 59.582 0 64 0c4.41 0 8 3.585 8 8.007V56h47.993c4.416 0 8.007 3.582 8.007 8 0 4.41-3.585 8-8.007 8H72v47.993c0 4.416-3.582 8.007-8 8.007-4.41 0-8-3.585-8-8.007V72z\"/></svg>"},"$:/core/images/new-here-button":{"title":"$:/core/images/new-here-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-new-here-button tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M55.838 20.935l-3.572.938c-3.688.968-8.23 4.43-10.136 7.731L3.37 96.738c-1.905 3.3-.771 7.524 2.534 9.432l33.717 19.466c3.297 1.904 7.53.78 9.435-2.521l38.76-67.134c1.905-3.3 2.632-8.963 1.623-12.646L83.285 20.88c-1.009-3.68-4.821-5.884-8.513-4.915l-7.603 1.995.043.287c.524 3.394 2.053 7.498 4.18 11.55.418.163.829.36 1.23.59a8.864 8.864 0 014.438 8.169c.104.132.21.264.316.395l-.386.318a8.663 8.663 0 01-1.082 3.137c-2.42 4.192-7.816 5.608-12.051 3.163-4.12-2.379-5.624-7.534-3.476-11.671-2.177-4.394-3.788-8.874-4.543-12.964z\"/><path d=\"M69.554 44.76c-5.944-7.476-10.74-17.196-11.955-25.059-1.68-10.875 3.503-18.216 15.082-18.04 10.407.158 19.975 5.851 24.728 13.785 5.208 8.695 2.95 17.868-6.855 20.496l-2.037-7.601c4.232-1.134 4.999-4.248 2.24-8.853-3.37-5.626-10.465-9.848-18.146-9.965-6.392-.097-8.31 2.62-7.323 9.01.999 6.465 5.318 15.138 10.582 21.65l-.072.06c.559 1.553-4.17 6.44-5.938 4.888l-.005.004-.028-.034a1.323 1.323 0 01-.124-.135 2.618 2.618 0 01-.149-.205z\"/><rect width=\"16\" height=\"48\" x=\"96\" y=\"80\" rx=\"8\"/><rect width=\"48\" height=\"16\" x=\"80\" y=\"96\" rx=\"8\"/></g></svg>"},"$:/core/images/new-image-button":{"title":"$:/core/images/new-image-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-new-image-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M81.362 73.627l15.826-27.41a2.626 2.626 0 00-.962-3.59l-50.01-28.872a2.626 2.626 0 00-3.588.961L30.058 36.49l10.04-5.261c3.042-1.595 6.771.114 7.55 3.46l3.607 17.702 9.88.85a5.25 5.25 0 014.571 3.77c.034.115.1.344.199.671.165.553.353 1.172.562 1.843.595 1.914 1.23 3.85 1.872 5.678.207.588.412 1.156.614 1.701.625 1.685 1.209 3.114 1.725 4.207.255.54.485.977.726 1.427.214.212.547.425 1.011.622 1.141.482 2.784.74 4.657.758.864.008 1.71-.034 2.492-.11.448-.043.753-.085.871-.104.315-.053.625-.077.927-.076zM37.47 2.649A5.257 5.257 0 0144.649.725l63.645 36.746a5.257 5.257 0 011.923 7.178L73.47 108.294a5.257 5.257 0 01-7.177 1.923L2.649 73.47a5.257 5.257 0 01-1.924-7.177L37.471 2.649zm42.837 50.49a5.25 5.25 0 105.25-9.092 5.25 5.25 0 00-5.25 9.093zM96 112h-7.993c-4.419 0-8.007-3.582-8.007-8 0-4.41 3.585-8 8.007-8H96v-7.993C96 83.588 99.582 80 104 80c4.41 0 8 3.585 8 8.007V96h7.993c4.419 0 8.007 3.582 8.007 8 0 4.41-3.585 8-8.007 8H112v7.993c0 4.419-3.582 8.007-8 8.007-4.41 0-8-3.585-8-8.007V112zM33.347 51.791c7.428 7.948 9.01 10.69 7.449 13.394-1.56 2.703-13.838-2.328-16.094 1.58-2.256 3.908-.907 3.258-2.437 5.908l19.73 11.39s-5.605-8.255-4.235-10.628c2.515-4.356 8.77-1.256 10.365-4.019 2.414-4.181-5.103-9.639-14.778-17.625z\"/></svg>"},"$:/core/images/new-journal-button":{"title":"$:/core/images/new-journal-button","tags":"$:/tags/Image","text":"<$parameters size=\"22pt\" day=<<now \"DD\">>><svg width=<<size>> height=<<size>> class=\"tc-image-new-journal-button tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M102.545 112.818v11.818c0 1.306 1.086 2.364 2.425 2.364h6.06c1.34 0 2.425-1.058 2.425-2.364v-11.818h12.12c1.34 0 2.425-1.058 2.425-2.363v-5.91c0-1.305-1.085-2.363-2.424-2.363h-12.121V90.364c0-1.306-1.086-2.364-2.425-2.364h-6.06c-1.34 0-2.425 1.058-2.425 2.364v11.818h-12.12c-1.34 0-2.425 1.058-2.425 2.363v5.91c0 1.305 1.085 2.363 2.424 2.363h12.121zM60.016 4.965c-4.781-2.76-10.897-1.118-13.656 3.66L5.553 79.305A9.993 9.993 0 009.21 92.963l51.04 29.468c4.78 2.76 10.897 1.118 13.655-3.66l40.808-70.681a9.993 9.993 0 00-3.658-13.656L60.016 4.965zm-3.567 27.963a6 6 0 106-10.393 6 6 0 00-6 10.393zm31.697 17.928a6 6 0 106-10.392 6 6 0 00-6 10.392z\"/><text class=\"tc-fill-background\" font-family=\"Helvetica\" font-size=\"47.172\" font-weight=\"bold\" transform=\"rotate(30 25.742 95.82)\"><tspan x=\"42\" y=\"77.485\" text-anchor=\"middle\"><$text text=<<day>>/></tspan></text></g></svg></$parameters>"},"$:/core/images/opacity":{"title":"$:/core/images/opacity","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-opacity tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M102.362 65a51.595 51.595 0 01-1.942 6H82.584a35.867 35.867 0 002.997-6h16.78zm.472-2c.423-1.961.734-3.963.929-6H87.656a35.78 35.78 0 01-1.368 6h16.546zm-3.249 10a51.847 51.847 0 01-3.135 6H75.812a36.205 36.205 0 005.432-6h18.341zm-4.416 8c-1.424 2.116-3 4.12-4.71 6H60.46a35.843 35.843 0 0012.874-6h21.834zm-7.513-34h16.107C101.247 20.627 79.033 0 52 0 23.281 0 0 23.281 0 52c0 25.228 17.965 46.26 41.8 51h20.4a51.66 51.66 0 0015.875-6H39v-2h42.25a52.257 52.257 0 007.288-6H39v-2h4.539C27.739 83.194 16 68.968 16 52c0-19.882 16.118-36 36-36 18.186 0 33.222 13.484 35.656 31zm.22 2h16.039a52.823 52.823 0 010 6H87.877a36.483 36.483 0 000-6z\"/><path d=\"M76 128c28.719 0 52-23.281 52-52s-23.281-52-52-52-52 23.281-52 52 23.281 52 52 52zm0-16c19.882 0 36-16.118 36-36S95.882 40 76 40 40 56.118 40 76s16.118 36 36 36z\"/><path d=\"M37 58h53v4H37v-4zm3-8h53v4H40v-4zm0-8h53v4H40v-4zm-8 24h53v4H32v-4zm-2 8h53v4H30v-4zm-3 8h53v4H27v-4z\"/></g></svg>"},"$:/core/images/open-window":{"title":"$:/core/images/open-window","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-open-window tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M16 112h88.994c3.87 0 7.006 3.59 7.006 8 0 4.418-3.142 8-7.006 8H7.006C3.136 128 0 124.41 0 120a9.321 9.321 0 010-.01V24.01C0 19.586 3.59 16 8 16c4.418 0 8 3.584 8 8.01V112z\"/><path d=\"M96 43.196V56a8 8 0 1016 0V24c0-4.41-3.585-8-8.007-8H72.007C67.588 16 64 19.582 64 24c0 4.41 3.585 8 8.007 8H84.57l-36.3 36.299a8 8 0 00-.001 11.316c3.117 3.117 8.19 3.123 11.316-.003L96 43.196zM32 7.999C32 3.581 35.588 0 40 0h80c4.419 0 8 3.588 8 8v80c0 4.419-3.588 8-8 8H40c-4.419 0-8-3.588-8-8V8z\"/></g></svg>"},"$:/core/images/options-button":{"title":"$:/core/images/options-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-options-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M110.488 76a47.712 47.712 0 01-5.134 12.384l6.724 6.724c3.123 3.123 3.132 8.192.011 11.313l-5.668 5.668c-3.12 3.12-8.186 3.117-11.313-.01l-6.724-6.725c-3.82 2.258-7.98 4-12.384 5.134v9.505c0 4.417-3.578 8.007-7.992 8.007h-8.016C55.58 128 52 124.415 52 119.993v-9.505a47.712 47.712 0 01-12.384-5.134l-6.724 6.725c-3.123 3.122-8.192 3.131-11.313.01l-5.668-5.668c-3.12-3.12-3.116-8.186.01-11.313l6.725-6.724c-2.257-3.82-4-7.98-5.134-12.384H8.007C3.591 76 0 72.422 0 68.01v-8.017C0 55.58 3.585 52 8.007 52h9.505a47.712 47.712 0 015.134-12.383l-6.724-6.725c-3.123-3.122-3.132-8.191-.011-11.312l5.668-5.669c3.12-3.12 8.186-3.116 11.313.01l6.724 6.725c3.82-2.257 7.98-4 12.384-5.134V8.007C52 3.591 55.578 0 59.992 0h8.016C72.42 0 76 3.585 76 8.007v9.505a47.712 47.712 0 0112.384 5.134l6.724-6.724c3.123-3.123 8.192-3.132 11.313-.01l5.668 5.668c3.12 3.12 3.116 8.186-.01 11.312l-6.725 6.725c2.257 3.82 4 7.979 5.134 12.383h9.505c4.416 0 8.007 3.578 8.007 7.992v8.017c0 4.411-3.585 7.991-8.007 7.991h-9.505zM64 96c17.673 0 32-14.327 32-32 0-17.673-14.327-32-32-32-17.673 0-32 14.327-32 32 0 17.673 14.327 32 32 32z\"/></svg>"},"$:/core/images/paint":{"title":"$:/core/images/paint","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-paint tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M83.527 76.19C90.43 69.287 91.892 59 87.91 50.665l37.903-37.902c2.919-2.92 2.913-7.659 0-10.572a7.474 7.474 0 00-10.572 0L77.338 40.093c-8.335-3.982-18.622-2.521-25.526 4.383l31.715 31.715zm-2.643 2.644L49.169 47.119S8.506 81.243 0 80.282c0 0 3.782 5.592 6.827 8.039 14.024-5.69 37.326-24.6 37.326-24.6l.661.66S19.45 90.222 9.18 92.047c1.222 1.44 4.354 4.053 6.247 5.776 5.417-1.488 34.733-28.57 34.733-28.57l.661.66-32.407 31.022 5.285 5.286L56.106 75.2l.662.66s-27.864 30.536-28.684 32.432c0 0 6.032 6.853 7.569 7.824.702-2.836 27.884-33.485 27.884-33.485l.661.66s-20.597 23.755-24.964 36.732c3.21 3.549 7.5 5.137 10.926 6.298-2.19-11.817 30.724-47.487 30.724-47.487z\"/></svg>"},"$:/core/images/palette":{"title":"$:/core/images/palette","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-palette tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M80.247 39.182a93.52 93.52 0 00-16.228-1.4C28.662 37.781 0 57.131 0 81.002c0 9.642 4.676 18.546 12.58 25.735C23.504 91.19 26.34 72.395 36.89 63.562c15.183-12.713 26.538-7.828 26.538-7.828l16.82-16.552zm26.535 9.655c13.049 7.913 21.257 19.392 21.257 32.166 0 9.35.519 17.411-11.874 25.08-10.797 6.681-3.824-6.536-11.844-10.898s-19.946 1.308-18.213 7.906c3.2 12.181 19.422 11.455 6.314 16.658-13.107 5.202-18.202 4.476-28.403 4.476-7.821 0-15.315-.947-22.243-2.68 9.844-4.197 27.88-12.539 33.354-19.456C82.788 92.409 87.37 80 83.324 72.484c-.194-.359 11.215-11.668 23.458-23.647zM1.134 123.867l-.66.002c33.479-14.94 22.161-64.226 58.818-64.226.317 1.418.644 2.944 1.062 4.494-25.907-4.166-23.567 48.031-59.22 59.73zm.713-.007c38.872-.506 78.152-22.347 78.152-44.813-9.27 0-14.073-3.48-16.816-7.942-16.597-7.003-30.365 45.715-61.336 52.755zm65.351-64.008c-4.45 4.115 4.886 16.433 11.318 11.318l45.27-45.27c11.317-11.318 0-22.635-11.318-11.318-11.317 11.318-33.518 34.405-45.27 45.27z\"/></svg>"},"$:/core/images/permalink-button":{"title":"$:/core/images/permalink-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-permalink-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M80.483 48l-7.387 32h-25.58l7.388-32h25.58zm3.694-16l5.624-24.358c.993-4.303 5.29-6.996 9.596-6.002 4.296.992 6.988 5.293 5.994 9.602L100.598 32h3.403c4.41 0 7.999 3.582 7.999 8 0 4.41-3.581 8-8 8h-7.096l-7.387 32H104c4.41 0 7.999 3.582 7.999 8 0 4.41-3.581 8-8 8H85.824l-5.624 24.358c-.993 4.303-5.29 6.996-9.596 6.002-4.296-.992-6.988-5.293-5.994-9.602L69.402 96h-25.58L38.2 120.358c-.993 4.303-5.29 6.996-9.596 6.002-4.296-.992-6.988-5.293-5.994-9.602L27.402 96h-3.403C19.59 96 16 92.418 16 88c0-4.41 3.581-8 8-8h7.096l7.387-32H24C19.59 48 16 44.418 16 40c0-4.41 3.581-8 8-8h18.177l5.624-24.358c.993-4.303 5.29-6.996 9.596-6.002 4.296.992 6.988 5.293 5.994 9.602L58.598 32h25.58z\"/></svg>"},"$:/core/images/permaview-button":{"title":"$:/core/images/permaview-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-permaview-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M81.483 48l-1.846 8h-5.58l1.847-8h5.58zm3.694-16l5.624-24.358c.993-4.303 5.29-6.996 9.596-6.002 4.296.992 6.988 5.293 5.994 9.602L101.598 32h2.403c4.41 0 7.999 3.582 7.999 8 0 4.41-3.581 8-8 8h-6.096l-1.847 8h7.944c4.41 0 7.999 3.582 7.999 8 0 4.41-3.581 8-8 8H92.364l-1.846 8H104c4.41 0 7.999 3.582 7.999 8 0 4.41-3.581 8-8 8H86.824l-5.624 24.358c-.993 4.303-5.29 6.996-9.596 6.002-4.296-.992-6.988-5.293-5.994-9.602L70.402 96h-5.58L59.2 120.358c-.993 4.303-5.29 6.996-9.596 6.002-4.296-.992-6.988-5.293-5.994-9.602L48.402 96h-5.58L37.2 120.358c-.993 4.303-5.29 6.996-9.596 6.002-4.296-.992-6.988-5.293-5.994-9.602L26.402 96h-2.403C19.59 96 16 92.418 16 88c0-4.41 3.581-8 8-8h6.096l1.847-8h-7.944C19.59 72 16 68.418 16 64c0-4.41 3.581-8 8-8h11.637l1.846-8H24C19.59 48 16 44.418 16 40c0-4.41 3.581-8 8-8h17.177l5.624-24.358c.993-4.303 5.29-6.996 9.596-6.002 4.296.992 6.988 5.293 5.994 9.602L57.598 32h5.58L68.8 7.642c.993-4.303 5.29-6.996 9.596-6.002 4.296.992 6.988 5.293 5.994 9.602L79.598 32h5.58zM53.904 48l-1.847 8h5.58l1.846-8h-5.579zm22.039 24l-1.847 8h-5.58l1.847-8h5.58zm-27.58 0l-1.846 8h5.579l1.847-8h-5.58z\"/></svg>"},"$:/core/images/picture":{"title":"$:/core/images/picture","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-picture tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M112 68.233v-48.23A4.001 4.001 0 00107.997 16H20.003A4.001 4.001 0 0016 20.003v38.31l9.241-14.593c2.8-4.422 9.023-5.008 12.6-1.186l18.247 20.613 13.687-6.407a8 8 0 018.903 1.492 264.97 264.97 0 002.92 2.739 249.44 249.44 0 006.798 6.066 166.5 166.5 0 002.106 1.778c2.108 1.747 3.967 3.188 5.482 4.237.748.518 1.383.92 2.044 1.33.444.117 1.046.144 1.809.05 1.873-.233 4.238-1.144 6.723-2.547a36.016 36.016 0 003.205-2.044c.558-.4.93-.686 1.07-.802.376-.31.765-.577 1.165-.806zM0 8.007A8.01 8.01 0 018.007 0h111.986A8.01 8.01 0 01128 8.007v111.986a8.01 8.01 0 01-8.007 8.007H8.007A8.01 8.01 0 010 119.993V8.007zM95 42a8 8 0 100-16 8 8 0 000 16zM32 76c15.859 4.83 20.035 7.244 20.035 12S32 95.471 32 102.347c0 6.876 1.285 4.99 1.285 9.653H68s-13.685-6.625-13.685-10.8c0-7.665 10.615-8.34 10.615-13.2 0-7.357-14.078-8.833-32.93-12z\"/></svg>"},"$:/core/images/plugin-generic-language":{"title":"$:/core/images/plugin-generic-language","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> viewBox=\"0 0 128 128\" class=\"tc-image-plugin-generic-language tc-image-button\"><path fill-rule=\"evenodd\" d=\"M61.207 68.137c-4.324 2.795-6.999 6.656-6.999 10.921 0 7.906 9.19 14.424 21.042 15.336 2.162 3.902 8.598 6.785 16.318 7.01-5.126-1.125-9.117-3.742-10.62-7.01C92.805 93.487 102 86.967 102 79.059c0-8.53-10.699-15.445-23.896-15.445-6.599 0-12.572 1.729-16.897 4.524zm12.794-14.158c-4.324 2.795-10.298 4.524-16.897 4.524-2.619 0-5.14-.272-7.497-.775-3.312 2.25-8.383 3.69-14.067 3.69l-.255-.002c4.119-.892 7.511-2.747 9.478-5.13-6.925-2.704-11.555-7.617-11.555-13.228 0-8.53 10.699-15.445 23.896-15.445C70.301 27.613 81 34.528 81 43.058c0 4.265-2.675 8.126-6.999 10.921zM64 0l54.56 32v64L64 128 9.44 96V32L64 0z\"/></svg>"},"$:/core/images/plugin-generic-plugin":{"title":"$:/core/images/plugin-generic-plugin","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> viewBox=\"0 0 128 128\" class=\"tc-image-plugin-generic-plugin tc-image-button\"><path fill-rule=\"evenodd\" d=\"M40.397 76.446V95.34h14.12l-.001-.005a6.912 6.912 0 005.364-11.593l.046-.023a6.912 6.912 0 119.979.526l.086.055a6.914 6.914 0 004.408 10.948l-.023.092h21.32V75.568l-.15.038a6.912 6.912 0 00-11.593-5.364l-.022-.046a6.912 6.912 0 11.526-9.979l.055-.086a6.914 6.914 0 0010.948-4.408c.079.018.158.038.236.059v-15.74h-21.32l.023-.094a6.914 6.914 0 01-4.408-10.947 10.23 10.23 0 00-.086-.055 6.912 6.912 0 10-9.979-.526l-.046.023a6.912 6.912 0 01-5.364 11.593l.001.005h-14.12v12.847A6.912 6.912 0 0129.5 59.843l-.054.086a6.912 6.912 0 10-.526 9.979l.023.046a6.912 6.912 0 0111.455 6.492zM64 0l54.56 32v64L64 128 9.44 96V32L64 0z\"/></svg>"},"$:/core/images/plugin-generic-theme":{"title":"$:/core/images/plugin-generic-theme","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> viewBox=\"0 0 128 128\" class=\"tc-image-plugin-generic-theme tc-image-button\"><path fill-rule=\"evenodd\" d=\"M29.408 91.472L51.469 69.41l-.004-.005a2.22 2.22 0 01.004-3.146c.87-.87 2.281-.872 3.147-.005l9.465 9.464a2.22 2.22 0 01-.005 3.147c-.87.87-2.28.871-3.147.005l-.005-.005-22.061 22.062a6.686 6.686 0 11-9.455-9.455zM60.802 66.38c-2.436-2.704-4.465-5.091-5.817-6.869-6.855-9.014-10.313-4.268-14.226 0-3.913 4.268 1.03 7.726-2.683 10.741-3.713 3.015-3.484 4.06-9.752-1.455-6.267-5.516-6.7-7.034-3.823-10.181 2.877-3.147 5.281 1.808 11.159-3.785 5.877-5.593.94-10.55.94-10.55s12.237-25.014 28.588-23.167c16.351 1.848-6.186-2.392-11.792 17.226-2.4 8.4.447 6.42 4.998 9.968 1.394 1.086 6.03 4.401 11.794 8.685l20.677-20.676 1.615-4.766 7.84-4.689 3.151 3.152-4.688 7.84-4.766 1.615-20.224 20.223c12.663 9.547 28.312 22.146 28.312 26.709 0 7.217-3.071 11.526-9.535 9.164-4.693-1.715-18.768-15.192-28.753-25.897l-2.893 2.893-3.151-3.152 3.029-3.029zM63.953 0l54.56 32v64l-54.56 32-54.56-32V32l54.56-32z\"/></svg>"},"$:/core/images/plus-button":{"title":"$:/core/images/plus-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-plus-button tc-image-button\" viewBox=\"0 0 128 128\"><path d=\"M64-.333c35.346 0 64 28.654 64 64 0 35.346-28.654 64-64 64-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64zM64 16c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48z\"/><rect width=\"80\" height=\"16\" x=\"24\" y=\"56\" rx=\"8\"/><rect width=\"16\" height=\"80\" x=\"56\" y=\"24\" rx=\"8\"/></svg>"},"$:/core/images/preview-closed":{"title":"$:/core/images/preview-closed","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-preview-closed tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M.088 64a7.144 7.144 0 001.378 5.458C16.246 88.818 39.17 100.414 64 100.414c24.83 0 47.753-11.596 62.534-30.956A7.144 7.144 0 00127.912 64C110.582 78.416 88.304 87.086 64 87.086 39.696 87.086 17.418 78.416.088 64z\"/><rect width=\"4\" height=\"16\" x=\"62\" y=\"96\" rx=\"4\"/><rect width=\"4\" height=\"16\" x=\"78\" y=\"93\" rx=\"4\" transform=\"rotate(-5 80 101)\"/><rect width=\"4\" height=\"16\" x=\"46\" y=\"93\" rx=\"4\" transform=\"rotate(5 48 101)\"/><rect width=\"4\" height=\"16\" x=\"30\" y=\"88\" rx=\"4\" transform=\"rotate(10 32 96)\"/><rect width=\"4\" height=\"16\" x=\"94\" y=\"88\" rx=\"4\" transform=\"rotate(-10 96 96)\"/><rect width=\"4\" height=\"16\" x=\"110\" y=\"80\" rx=\"4\" transform=\"rotate(-20 112 88)\"/><rect width=\"4\" height=\"16\" x=\"14\" y=\"80\" rx=\"4\" transform=\"rotate(20 16 88)\"/></g></svg>"},"$:/core/images/preview-open":{"title":"$:/core/images/preview-open","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-preview-open tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M64.11 99.588c-24.83 0-47.754-11.596-62.534-30.957a7.148 7.148 0 010-8.675C16.356 40.596 39.28 29 64.11 29c24.83 0 47.753 11.596 62.534 30.956a7.148 7.148 0 010 8.675c-14.78 19.36-37.703 30.957-62.534 30.957zm46.104-32.007c1.44-1.524 1.44-3.638 0-5.162C99.326 50.9 82.439 44 64.147 44S28.968 50.9 18.08 62.42c-1.44 1.523-1.44 3.637 0 5.16C28.968 79.1 45.855 86 64.147 86s35.179-6.9 46.067-18.42z\"/><path d=\"M63.5 88C76.479 88 87 77.479 87 64.5S76.479 41 63.5 41 40 51.521 40 64.5 50.521 88 63.5 88z\"/></g></svg>"},"$:/core/images/print-button":{"title":"$:/core/images/print-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-print-button tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M112 71V30.5h-.032c-.035-2-.816-3.99-2.343-5.516L86.998 2.357A7.978 7.978 0 0081 .02V0H24a8 8 0 00-8 8v63h8V8h57v14.5c0 4.422 3.582 8 8 8h15V71h8z\"/><rect width=\"64\" height=\"8\" x=\"32\" y=\"36\" rx=\"4\"/><rect width=\"64\" height=\"8\" x=\"32\" y=\"52\" rx=\"4\"/><rect width=\"40\" height=\"8\" x=\"32\" y=\"20\" rx=\"4\"/><path d=\"M0 80.005C0 71.165 7.156 64 16 64h96c8.836 0 16 7.155 16 16.005v31.99c0 8.84-7.156 16.005-16 16.005H16c-8.836 0-16-7.155-16-16.005v-31.99zM104 96a8 8 0 100-16 8 8 0 000 16z\"/></g></svg>"},"$:/core/images/quote":{"title":"$:/core/images/quote","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-quote tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M51.219 117.713V62.199H27.427c0-8.891 1.683-16.401 5.047-22.53 3.365-6.127 9.613-10.754 18.745-13.878V2c-7.45.961-14.36 3.184-20.728 6.669-6.368 3.484-11.835 7.87-16.401 13.157C9.524 27.113 5.98 33.241 3.456 40.21.933 47.18-.21 54.63.03 62.56v55.153H51.22zm76.781 0V62.199h-23.791c0-8.891 1.682-16.401 5.046-22.53 3.365-6.127 9.613-10.754 18.745-13.878V2c-7.45.961-14.359 3.184-20.727 6.669-6.369 3.484-11.836 7.87-16.402 13.157-4.566 5.287-8.11 11.415-10.634 18.384-2.523 6.97-3.665 14.42-3.424 22.35v55.153H128z\"/></svg>"},"$:/core/images/refresh-button":{"title":"$:/core/images/refresh-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-refresh-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M106.369 39.433c10.16 20.879 6.57 46.764-10.771 64.106-21.87 21.87-57.327 21.87-79.196 0-21.87-21.87-21.87-57.326 0-79.196a8 8 0 1111.314 11.314c-15.621 15.62-15.621 40.947 0 56.568 15.62 15.621 40.947 15.621 56.568 0C97.72 78.79 99.6 58.175 89.924 42.73l-6.44 12.264a8 8 0 11-14.166-7.437L84.435 18.76a8 8 0 0110.838-3.345l28.873 15.345a8 8 0 11-7.51 14.129l-10.267-5.457zm-8.222-12.368c-.167-.19-.336-.38-.506-.57l.96-.296-.454.866z\"/></svg>"},"$:/core/images/right-arrow":{"title":"$:/core/images/right-arrow","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-right-arrow tc-image-button\" viewBox=\"0 0 128 128\"><path d=\"M99.069 64.173c0 2.027-.77 4.054-2.316 5.6l-55.98 55.98a7.92 7.92 0 01-11.196 0c-3.085-3.086-3.092-8.105 0-11.196l50.382-50.382-50.382-50.382a7.92 7.92 0 010-11.195c3.086-3.085 8.104-3.092 11.196 0l55.98 55.98a7.892 7.892 0 012.316 5.595z\"/></svg>"},"$:/core/images/rotate-left":{"title":"$:/core/images/rotate-left","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-rotate-left tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><rect width=\"32\" height=\"80\" rx=\"8\"/><rect width=\"80\" height=\"32\" x=\"48\" y=\"96\" rx=\"8\"/><path d=\"M61.32 36.65c19.743 2.45 35.023 19.287 35.023 39.693a4 4 0 01-8 0c0-15.663-11.254-28.698-26.117-31.46l3.916 3.916a4 4 0 11-5.657 5.657L49.172 43.142a4 4 0 010-5.657l11.313-11.313a4 4 0 115.657 5.656l-4.821 4.822z\"/></g></svg>"},"$:/core/images/save-button-dynamic":{"title":"$:/core/images/save-button-dynamic","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-save-button-dynamic tc-image-button\" viewBox=\"0 0 128 128\">\n<g class=\"tc-image-save-button-dynamic-clean\">\n<path fill-rule=\"evenodd\" d=\"M120.783 34.33c4.641 8.862 7.266 18.948 7.266 29.646 0 35.347-28.653 64-64 64-35.346 0-64-28.653-64-64 0-35.346 28.654-64 64-64 18.808 0 35.72 8.113 47.43 21.03l2.68-2.68c3.13-3.13 8.197-3.132 11.321-.008 3.118 3.118 3.121 8.193-.007 11.32l-4.69 4.691zm-12.058 12.058a47.876 47.876 0 013.324 17.588c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48c14.39 0 27.3 6.332 36.098 16.362L58.941 73.544 41.976 56.578c-3.127-3.127-8.201-3.123-11.32-.005-3.123 3.124-3.119 8.194.006 11.319l22.617 22.617a7.992 7.992 0 005.659 2.347c2.05 0 4.101-.783 5.667-2.349l44.12-44.12z\"/>\n</g>\n<g class=\"tc-image-save-button-dynamic-dirty\">\n<path d=\"M64.856912,0 C100.203136,0 128.856912,28.653776 128.856912,64 C128.856912,99.346224 100.203136,128 64.856912,128 C29.510688,128 0.856911958,99.346224 0.856911958,64 C0.856911958,28.653776 29.510688,0 64.856912,0 Z M64.856912,16 C38.347244,16 16.856912,37.490332 16.856912,64 C16.856912,90.509668 38.347244,112 64.856912,112 C91.3665799,112 112.856912,90.509668 112.856912,64 C112.856912,37.490332 91.3665799,16 64.856912,16 Z\"></path>\n<circle cx=\"65\" cy=\"64\" r=\"32\"></circle>\n</g>\n</svg>"},"$:/core/images/save-button":{"title":"$:/core/images/save-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-save-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M120.783 34.33c4.641 8.862 7.266 18.948 7.266 29.646 0 35.347-28.653 64-64 64-35.346 0-64-28.653-64-64 0-35.346 28.654-64 64-64 18.808 0 35.72 8.113 47.43 21.03l2.68-2.68c3.13-3.13 8.197-3.132 11.321-.008 3.118 3.118 3.121 8.193-.007 11.32l-4.69 4.691zm-12.058 12.058a47.876 47.876 0 013.324 17.588c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48c14.39 0 27.3 6.332 36.098 16.362L58.941 73.544 41.976 56.578c-3.127-3.127-8.201-3.123-11.32-.005-3.123 3.124-3.119 8.194.006 11.319l22.617 22.617a7.992 7.992 0 005.659 2.347c2.05 0 4.101-.783 5.667-2.349l44.12-44.12z\"/></svg>"},"$:/core/images/size":{"title":"$:/core/images/size","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-size tc-image-button\" viewBox=\"0 0 128 128\"><path d=\"M92.343 26l-9.171 9.172a4 4 0 105.656 5.656l16-16a4 4 0 000-5.656l-16-16a4 4 0 10-5.656 5.656L92.343 18H22a4 4 0 00-4 4v70.343l-9.172-9.171a4 4 0 10-5.656 5.656l16 16a4 4 0 005.656 0l16-16a4 4 0 10-5.656-5.656L26 92.343V22l-4 4h70.343zM112 52v64l4-4H52a4 4 0 100 8h64a4 4 0 004-4V52a4 4 0 10-8 0z\"/></svg>"},"$:/core/images/spiral":{"title":"$:/core/images/spiral","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-spiral tc-image-button\" viewBox=\"0 0 128 128\"><path d=\"M64.534 68.348c3.39 0 6.097-2.62 6.476-5.968l-4.755-.538 4.75.583c.377-3.07-1.194-6.054-3.89-7.78-2.757-1.773-6.34-2.01-9.566-.7-3.46 1.403-6.14 4.392-7.35 8.148l-.01.026c-1.3 4.08-.72 8.64 1.58 12.52 2.5 4.2 6.77 7.2 11.76 8.27 5.37 1.15 11.11-.05 15.83-3.31 5.04-3.51 8.46-9.02 9.45-15.3 1.05-6.7-.72-13.63-4.92-19.19l.02.02c-4.42-5.93-11.2-9.82-18.78-10.78-7.96-1.01-16.13 1.31-22.59 6.43-6.81 5.39-11.18 13.41-12.11 22.26-.98 9.27 1.87 18.65 7.93 26.02 6.32 7.69 15.6 12.56 25.74 13.48 10.54.96 21.15-2.42 29.45-9.4l.01-.01c8.58-7.25 13.94-17.78 14.86-29.21.94-11.84-2.96-23.69-10.86-32.9-8.19-9.5-19.95-15.36-32.69-16.27-13.16-.94-26.24 3.49-36.34 12.34l.01-.01c-10.41 9.08-16.78 22.1-17.68 36.15-.93 14.44 4.03 28.77 13.79 39.78 10.03 11.32 24.28 18.2 39.6 19.09 15.73.92 31.31-4.56 43.24-15.234 12.23-10.954 19.61-26.44 20.5-43.074a4.785 4.785 0 00-4.52-5.03 4.778 4.778 0 00-5.03 4.52c-.75 14.1-7 27.2-17.33 36.45-10.03 8.98-23.11 13.58-36.3 12.81-12.79-.75-24.67-6.48-33-15.89-8.07-9.11-12.17-20.94-11.41-32.827.74-11.52 5.942-22.15 14.43-29.54l.01-.01c8.18-7.17 18.74-10.75 29.35-9.998 10.21.726 19.6 5.41 26.11 12.96 6.24 7.273 9.32 16.61 8.573 25.894-.718 8.9-4.88 17.064-11.504 22.66l.01-.007c-6.36 5.342-14.44 7.92-22.425 7.19-7.604-.68-14.52-4.314-19.21-10.027-4.44-5.4-6.517-12.23-5.806-18.94.67-6.3 3.76-11.977 8.54-15.766 4.46-3.54 10.05-5.128 15.44-4.44 5.03.63 9.46 3.18 12.32 7.01l.02.024c2.65 3.5 3.75 7.814 3.1 11.92-.59 3.71-2.58 6.925-5.45 8.924-2.56 1.767-5.61 2.403-8.38 1.81-2.42-.516-4.42-1.92-5.53-3.79-.93-1.56-1.15-3.3-.69-4.75l-4.56-1.446L59.325 65c.36-1.12 1.068-1.905 1.84-2.22.25-.103.48-.14.668-.13.06.006.11.015.14.025.01 0 .01 0-.01-.01a1.047 1.047 0 01-.264-.332c-.15-.29-.23-.678-.18-1.11l-.005.04c.15-1.332 1.38-2.523 3.035-2.523-2.65 0-4.79 2.144-4.79 4.787s2.14 4.785 4.78 4.785z\"/></svg>"},"$:/core/images/stamp":{"title":"$:/core/images/stamp","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-stamp tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M49.733 64H16.01C11.584 64 8 67.583 8 72.003V97h112V72.003A8 8 0 00111.99 64H78.267A22.813 22.813 0 0175.5 53.077c0-6.475 2.687-12.324 7.009-16.497A22.818 22.818 0 0087 22.952C87 10.276 76.703 0 64 0S41 10.276 41 22.952c0 5.103 1.669 9.817 4.491 13.628 4.322 4.173 7.009 10.022 7.009 16.497 0 3.954-1.002 7.675-2.767 10.923zM8 104h112v8H8v-8z\"/></svg>"},"$:/core/images/standard-layout":{"title":"$:/core/images/standard-layout","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-standard-layout tc-image-button\" viewBox=\"0 0 128 128\">\n    <path d=\"M71.93 72A8.07 8.07 0 0 1 80 80.07v7.86A8.071 8.071 0 0 1 71.93 96H8.07A8.067 8.067 0 0 1 0 87.93v-7.86A8.072 8.072 0 0 1 8.07 72h63.86Zm0 32a8.07 8.07 0 0 1 8.07 8.07v7.86a8.071 8.071 0 0 1-8.07 8.07H8.07A8.067 8.067 0 0 1 0 119.93v-7.86A8.072 8.072 0 0 1 8.07 104h63.86Zm0-104A8.068 8.068 0 0 1 80 8.07v47.86A8.073 8.073 0 0 1 71.93 64H8.07A8.07 8.07 0 0 1 0 55.93V8.07A8.072 8.072 0 0 1 8.07 0h63.86Zm48 0c2.14 0 4.193.85 5.706 2.364A8.067 8.067 0 0 1 128 8.07v111.86c0 2.14-.85 4.193-2.364 5.706A8.067 8.067 0 0 1 119.93 128H96.07c-2.14 0-4.193-.85-5.706-2.364A8.067 8.067 0 0 1 88 119.93V8.07c0-2.14.85-4.193 2.364-5.706A8.067 8.067 0 0 1 96.07 0h23.86ZM116 24h-16a3.995 3.995 0 0 0-2.828 1.172 3.995 3.995 0 0 0 0 5.656A3.995 3.995 0 0 0 100 32h16a3.995 3.995 0 0 0 2.828-1.172 3.995 3.995 0 0 0 0-5.656A3.995 3.995 0 0 0 116 24Z\"/>\n</svg>"},"$:/core/images/star-filled":{"title":"$:/core/images/star-filled","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-star-filled tc-image-button\" viewBox=\"0 0 128 128\"><path d=\"M61.836 96.823l37.327 27.287c2.72 1.99 6.379-.69 5.343-3.912L90.29 75.988l-1.26 3.91 37.285-27.345c2.718-1.993 1.32-6.327-2.041-6.33l-46.113-.036 3.3 2.416L67.176 4.416c-1.04-3.221-5.563-3.221-6.604 0L46.29 48.603l3.3-2.416-46.113.036c-3.362.003-4.759 4.337-2.04 6.33L38.72 79.898l-1.26-3.91-14.216 44.21c-1.036 3.223 2.622 5.901 5.343 3.912l37.326-27.287h-4.078z\"/></svg>"},"$:/core/images/storyview-classic":{"title":"$:/core/images/storyview-classic","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-storyview-classic tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M8.007 0A8.01 8.01 0 000 8.007v111.986A8.01 8.01 0 008.007 128h111.986a8.01 8.01 0 008.007-8.007V8.007A8.01 8.01 0 00119.993 0H8.007zm15.992 16C19.581 16 16 19.578 16 23.992v16.016C16 44.422 19.588 48 24 48h80c4.419 0 8-3.578 8-7.992V23.992c0-4.414-3.588-7.992-8-7.992H24zm0 48C19.581 64 16 67.59 16 72c0 4.418 3.588 8 8 8h80c4.419 0 8-3.59 8-8 0-4.418-3.588-8-8-8H24zm0 32C19.581 96 16 99.59 16 104c0 4.418 3.588 8 8 8h80c4.419 0 8-3.59 8-8 0-4.418-3.588-8-8-8H24z\"/></svg>"},"$:/core/images/storyview-pop":{"title":"$:/core/images/storyview-pop","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-storyview-pop tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M8.007 0A8.01 8.01 0 000 8.007v111.986A8.01 8.01 0 008.007 128h111.986a8.01 8.01 0 008.007-8.007V8.007A8.01 8.01 0 00119.993 0H8.007zm15.992 16C19.581 16 16 19.578 16 23.992v16.016C16 44.422 19.588 48 24 48h80c4.419 0 8-3.578 8-7.992V23.992c0-4.414-3.588-7.992-8-7.992H24zm-7.99 40C11.587 56 8 59.578 8 63.992v16.016C8 84.422 11.584 88 16.01 88h95.98c4.424 0 8.01-3.578 8.01-7.992V63.992c0-4.414-3.584-7.992-8.01-7.992H16.01zM24 96C19.581 96 16 99.59 16 104c0 4.418 3.588 8 8 8h80c4.419 0 8-3.59 8-8 0-4.418-3.588-8-8-8H24zm0-32C19.581 64 16 67.59 16 72c0 4.418 3.588 8 8 8h80c4.419 0 8-3.59 8-8 0-4.418-3.588-8-8-8H24z\"/></svg>"},"$:/core/images/storyview-zoomin":{"title":"$:/core/images/storyview-zoomin","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-storyview-zoomin tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M8.007 0A8.01 8.01 0 000 8.007v111.986A8.01 8.01 0 008.007 128h111.986a8.01 8.01 0 008.007-8.007V8.007A8.01 8.01 0 00119.993 0H8.007zm15.992 16A8 8 0 0016 24.009V71.99C16 76.414 19.588 80 24 80h80a8 8 0 008-8.009V24.01c0-4.423-3.588-8.009-8-8.009H24z\"/></svg>"},"$:/core/images/strikethrough":{"title":"$:/core/images/strikethrough","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-strikethrough tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M92.794 38.726h15.422c-.229-6.74-1.514-12.538-3.856-17.393-2.342-4.855-5.54-8.881-9.596-12.08-4.055-3.199-8.767-5.54-14.136-7.025C75.258.743 69.433 0 63.15 0a62.76 62.76 0 00-16.364 2.142C41.474 3.57 36.733 5.74 32.564 8.653c-4.17 2.913-7.511 6.626-10.025 11.138-2.513 4.512-3.77 9.853-3.77 16.022 0 5.597 1.115 10.252 3.342 13.965 2.228 3.712 5.198 6.74 8.91 9.081 3.713 2.342 7.911 4.227 12.595 5.655a194.641 194.641 0 0014.308 3.77c4.855 1.085 9.624 2.142 14.308 3.17 4.683 1.028 8.881 2.37 12.594 4.027 3.713 1.656 6.683 3.798 8.91 6.425 2.228 2.628 3.342 6.055 3.342 10.281 0 4.456-.914 8.111-2.742 10.967a19.953 19.953 0 01-7.197 6.768c-2.97 1.657-6.311 2.828-10.024 3.513a60.771 60.771 0 01-11.052 1.028c-4.57 0-9.025-.571-13.366-1.713-4.34-1.143-8.139-2.913-11.394-5.312-3.256-2.4-5.884-5.455-7.883-9.168-1.999-3.712-2.998-8.139-2.998-13.28H15c0 7.426 1.342 13.852 4.027 19.278 2.684 5.426 6.34 9.881 10.966 13.365 4.627 3.484 9.996 6.083 16.107 7.797 6.112 1.713 12.595 2.57 19.449 2.57 5.597 0 11.223-.657 16.878-1.97 5.655-1.314 10.767-3.428 15.336-6.34 4.57-2.914 8.31-6.683 11.224-11.31 2.913-4.626 4.37-10.195 4.37-16.707 0-6.054-1.115-11.08-3.342-15.079-2.228-3.998-5.198-7.31-8.91-9.938-3.713-2.627-7.911-4.712-12.595-6.254a170.83 170.83 0 00-14.308-4.027 549.669 549.669 0 00-14.308-3.17c-4.683-.971-8.881-2.2-12.594-3.684-3.713-1.485-6.683-3.399-8.91-5.74-2.228-2.342-3.342-5.398-3.342-9.168 0-3.998.771-7.34 2.313-10.024 1.543-2.685 3.599-4.826 6.17-6.426 2.57-1.599 5.51-2.741 8.824-3.427a49.767 49.767 0 0110.11-1.028c8.453 0 15.393 1.97 20.819 5.912 5.426 3.94 8.596 10.31 9.51 19.106z\"/><path d=\"M5 54h118v16H5z\"/></g></svg>"},"$:/core/images/subscript":{"title":"$:/core/images/subscript","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-subscript tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M2.272 16h19.91l21.649 33.675L66.414 16h18.708L53.585 61.969l33.809 49.443H67.082L43.296 74.93l-24.187 36.48H0L33.808 61.97 2.272 16zM127.91 128.412H85.328c.059-5.168 1.306-9.681 3.741-13.542 2.435-3.86 5.761-7.216 9.978-10.066a112.388 112.388 0 016.325-4.321 50.09 50.09 0 006.058-4.499c1.841-1.603 3.356-3.34 4.543-5.211 1.188-1.871 1.812-4.024 1.871-6.46 0-1.128-.133-2.33-.4-3.607a9.545 9.545 0 00-1.56-3.564c-.772-1.098-1.84-2.019-3.207-2.761-1.366-.743-3.148-1.114-5.345-1.114-2.02 0-3.697.4-5.033 1.203-1.337.801-2.406 1.9-3.208 3.296-.801 1.396-1.395 3.044-1.781 4.944-.386 1.9-.609 3.95-.668 6.147H86.486c0-3.445.46-6.637 1.38-9.577.921-2.94 2.302-5.478 4.143-7.617 1.841-2.138 4.083-3.815 6.726-5.033 2.643-1.217 5.716-1.826 9.22-1.826 3.802 0 6.979.623 9.533 1.87 2.554 1.248 4.617 2.822 6.191 4.722 1.574 1.9 2.688 3.965 3.341 6.192.653 2.227.98 4.35.98 6.37 0 2.494-.386 4.75-1.158 6.77a21.803 21.803 0 01-3.118 5.568 31.516 31.516 0 01-4.454 4.677 66.788 66.788 0 01-5.167 4.009 139.198 139.198 0 01-5.346 3.563 79.237 79.237 0 00-4.944 3.386c-1.514 1.128-2.836 2.3-3.964 3.518-1.129 1.218-1.9 2.51-2.317 3.876h30.379v9.087z\"/></svg>"},"$:/core/images/superscript":{"title":"$:/core/images/superscript","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-superscript tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M2.272 16h19.91l21.649 33.675L66.414 16h18.708L53.585 61.969l33.809 49.443H67.082L43.296 74.93l-24.187 36.48H0L33.808 61.97 2.272 16zM127.91 63.412H85.328c.059-5.168 1.306-9.681 3.741-13.542 2.435-3.86 5.761-7.216 9.978-10.066a112.388 112.388 0 016.325-4.321 50.09 50.09 0 006.058-4.499c1.841-1.603 3.356-3.34 4.543-5.211 1.188-1.871 1.812-4.024 1.871-6.46 0-1.128-.133-2.33-.4-3.607a9.545 9.545 0 00-1.56-3.564c-.772-1.098-1.84-2.019-3.207-2.761-1.366-.743-3.148-1.114-5.345-1.114-2.02 0-3.697.4-5.033 1.203-1.337.801-2.406 1.9-3.208 3.296-.801 1.396-1.395 3.044-1.781 4.944-.386 1.9-.609 3.95-.668 6.147H86.486c0-3.445.46-6.637 1.38-9.577.921-2.94 2.302-5.478 4.143-7.617 1.841-2.138 4.083-3.815 6.726-5.033 2.643-1.217 5.716-1.826 9.22-1.826 3.802 0 6.979.623 9.533 1.87 2.554 1.248 4.617 2.822 6.191 4.722 1.574 1.9 2.688 3.965 3.341 6.192.653 2.227.98 4.35.98 6.37 0 2.494-.386 4.75-1.158 6.77a21.803 21.803 0 01-3.118 5.568 31.516 31.516 0 01-4.454 4.677 66.788 66.788 0 01-5.167 4.009 139.198 139.198 0 01-5.346 3.563 79.237 79.237 0 00-4.944 3.386c-1.514 1.128-2.836 2.3-3.964 3.518-1.129 1.218-1.9 2.51-2.317 3.876h30.379v9.087z\"/></svg>"},"$:/core/images/tag-button":{"title":"$:/core/images/tag-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-tag-button tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M18.164 47.66l.004 4.105c.003 3.823 2.19 9.097 4.885 11.792l61.85 61.85c2.697 2.697 7.068 2.69 9.769-.01L125.767 94.3a6.903 6.903 0 00.01-9.77L63.928 22.683c-2.697-2.697-7.976-4.88-11.796-4.881l-27.076-.007a6.902 6.902 0 00-6.91 6.91l.008 9.96.287.033c3.73.411 8.489-.044 13.365-1.153a9.702 9.702 0 0111.14-3.662l.291-.13.128.285a9.7 9.7 0 013.3 2.17c3.796 3.796 3.801 9.945.012 13.734-3.618 3.618-9.386 3.777-13.204.482-5.365 1.122-10.674 1.596-15.309 1.237z\"/><path d=\"M47.633 39.532l.023.051c-9.689 4.356-21.584 6.799-30.396 5.828C5.273 44.089-1.028 36.43 2.443 24.078 5.562 12.976 14.3 4.361 24.047 1.548c10.68-3.083 19.749 1.968 19.749 13.225h-8.623c0-4.859-3.078-6.573-8.735-4.94-6.91 1.995-13.392 8.383-15.694 16.577-1.915 6.818.417 9.653 7.46 10.43 7.126.785 17.531-1.352 25.917-5.121l.027.06.036-.017c1.76-.758 6.266 6.549 3.524 7.74a2.8 2.8 0 01-.075.03z\"/></g></svg>"},"$:/core/images/theme-button":{"title":"$:/core/images/theme-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-theme-button tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M55.854 66.945a122.626 122.626 0 01-3.9-4.819c-11.064-14.548-16.645-6.888-22.96 0-6.315 6.888 1.664 12.47-4.33 17.335-5.993 4.866-5.623 6.552-15.737-2.35-10.115-8.9-10.815-11.351-6.172-16.43 4.644-5.08 8.524 2.918 18.01-6.108 9.485-9.026 1.517-17.026 1.517-17.026S42.03-2.824 68.42.157c26.39 2.982-9.984-3.86-19.031 27.801-3.874 13.556.72 10.362 8.066 16.087 1.707 1.33 6.428 4.732 12.671 9.318-6.129 5.879-11.157 10.669-14.273 13.582zm11.641 12.947c16.013 17.036 37.742 37.726 45.117 40.42 10.432 3.813 15.388-3.141 15.388-14.79 0-7.151-23.83-26.542-43.924-41.769-7.408 7.156-13.376 12.953-16.58 16.139z\"/><path d=\"M11.069 109.828L46.31 74.587a3.56 3.56 0 115.037-5.032l15.098 15.098a3.56 3.56 0 11-5.032 5.037l-35.24 35.241c-4.171 4.17-10.933 4.17-15.104 0-4.17-4.17-4.17-10.933 0-15.103zM124.344 6.622l5.034 5.034-7.49 12.524-7.613 2.58L61.413 79.62l-5.034-5.034 52.861-52.862 2.58-7.614 12.524-7.49z\"/></g></svg>"},"$:/core/images/timestamp-off":{"title":"$:/core/images/timestamp-off","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-timestamp-off tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M58.25 11C26.08 11 0 37.082 0 69.25s26.08 58.25 58.25 58.25c32.175 0 58.25-26.082 58.25-58.25S90.425 11 58.25 11zm0 100.5C34.914 111.5 16 92.586 16 69.25 16 45.92 34.914 27 58.25 27s42.25 18.92 42.25 42.25c0 23.336-18.914 42.25-42.25 42.25zM49.704 10a5 5 0 010-10H66.69a5 5 0 015 5c.006 2.757-2.238 5-5 5H49.705z\"/><path d=\"M58.25 35.88c-18.777 0-33.998 15.224-33.998 33.998 0 18.773 15.22 34.002 33.998 34.002 18.784 0 34.002-15.23 34.002-34.002 0-18.774-15.218-33.998-34.002-33.998zm-3.03 50.123H44.196v-34H55.22v34zm16.976 0H61.17v-34h11.025v34z\"/></g></svg>"},"$:/core/images/timestamp-on":{"title":"$:/core/images/timestamp-on","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-timestamp-on tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M58.25 11C26.08 11 0 37.082 0 69.25s26.08 58.25 58.25 58.25c32.175 0 58.25-26.082 58.25-58.25S90.425 11 58.25 11zm0 100.5C34.914 111.5 16 92.586 16 69.25 16 45.92 34.914 27 58.25 27s42.25 18.92 42.25 42.25c0 23.336-18.914 42.25-42.25 42.25zM49.704 10a5 5 0 010-10H66.69a5 5 0 015 5c.006 2.757-2.238 5-5 5H49.705z\"/><path d=\"M13.41 27.178a5.005 5.005 0 01-7.045-.613 5.008 5.008 0 01.616-7.047l9.95-8.348a5 5 0 016.429 7.661l-9.95 8.348zm89.573 0a5.005 5.005 0 007.045-.613 5.008 5.008 0 00-.616-7.047l-9.95-8.348a5 5 0 00-6.428 7.661l9.95 8.348zM65.097 71.072c0 3.826-3.09 6.928-6.897 6.928-3.804.006-6.9-3.102-6.903-6.928 0 0 4.76-39.072 6.903-39.072s6.897 39.072 6.897 39.072z\"/></g></svg>"},"$:/core/images/tip":{"title":"$:/core/images/tip","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-tip tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M64 128.242c35.346 0 64-28.654 64-64 0-35.346-28.654-64-64-64-35.346 0-64 28.654-64 64 0 35.346 28.654 64 64 64zm11.936-36.789c-.624 4.129-5.73 7.349-11.936 7.349-6.206 0-11.312-3.22-11.936-7.349C54.33 94.05 58.824 95.82 64 95.82c5.175 0 9.67-1.769 11.936-4.366zm0 4.492c-.624 4.13-5.73 7.349-11.936 7.349-6.206 0-11.312-3.22-11.936-7.349 2.266 2.597 6.76 4.366 11.936 4.366 5.175 0 9.67-1.769 11.936-4.366zm0 4.456c-.624 4.129-5.73 7.349-11.936 7.349-6.206 0-11.312-3.22-11.936-7.349 2.266 2.597 6.76 4.366 11.936 4.366 5.175 0 9.67-1.769 11.936-4.366zm0 4.492c-.624 4.13-5.73 7.349-11.936 7.349-6.206 0-11.312-3.22-11.936-7.349 2.266 2.597 6.76 4.366 11.936 4.366 5.175 0 9.67-1.769 11.936-4.366zM64.3 24.242c11.618 0 23.699 7.82 23.699 24.2S75.92 71.754 75.92 83.576c0 5.873-5.868 9.26-11.92 9.26s-12.027-3.006-12.027-9.26C51.973 71.147 40 65.47 40 48.442s12.683-24.2 24.301-24.2z\"/></svg>"},"$:/core/images/transcludify":{"title":"$:/core/images/transcludify","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-transcludify-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M0 59.482c.591 0 1.36-.089 2.306-.266a10.417 10.417 0 002.75-.932 6.762 6.762 0 002.306-1.907c.651-.828.976-1.863.976-3.104V35.709c0-2.01.414-3.74 1.242-5.19.828-1.448 1.833-2.66 3.016-3.636s2.425-1.7 3.726-2.173c1.3-.473 2.424-.71 3.37-.71h8.073v7.451h-4.88c-1.241 0-2.232.207-2.97.621-.74.414-1.302.932-1.686 1.552a4.909 4.909 0 00-.71 1.996c-.089.71-.133 1.39-.133 2.04v16.677c0 1.715-.325 3.134-.976 4.258-.65 1.123-1.434 2.025-2.35 2.705-.917.68-1.863 1.168-2.839 1.464-.976.296-1.818.473-2.528.532v.178c.71.059 1.552.207 2.528.443.976.237 1.922.68 2.839 1.33.916.651 1.7 1.583 2.35 2.795.65 1.212.976 2.853.976 4.923v16.144c0 .65.044 1.33.133 2.04.089.71.325 1.375.71 1.996.384.621.946 1.139 1.685 1.553.74.414 1.73.62 2.972.62h4.879v7.452h-8.073c-.946 0-2.07-.237-3.37-.71-1.301-.473-2.543-1.197-3.726-2.173-1.183-.976-2.188-2.188-3.016-3.637-.828-1.449-1.242-3.179-1.242-5.19V74.119c0-1.42-.325-2.572-.976-3.46-.65-.886-1.419-1.581-2.306-2.084a8.868 8.868 0 00-2.75-1.02C1.36 67.377.591 67.288 0 67.288v-7.806zm24.66 0c.591 0 1.36-.089 2.306-.266a10.417 10.417 0 002.75-.932 6.762 6.762 0 002.306-1.907c.65-.828.976-1.863.976-3.104V35.709c0-2.01.414-3.74 1.242-5.19.828-1.448 1.833-2.66 3.016-3.636s2.425-1.7 3.726-2.173c1.3-.473 2.424-.71 3.37-.71h8.073v7.451h-4.88c-1.241 0-2.232.207-2.97.621-.74.414-1.302.932-1.686 1.552a4.909 4.909 0 00-.71 1.996c-.089.71-.133 1.39-.133 2.04v16.677c0 1.715-.325 3.134-.976 4.258-.65 1.123-1.434 2.025-2.35 2.705-.917.68-1.863 1.168-2.839 1.464-.976.296-1.818.473-2.528.532v.178c.71.059 1.552.207 2.528.443.976.237 1.922.68 2.839 1.33.916.651 1.7 1.583 2.35 2.795.65 1.212.976 2.853.976 4.923v16.144c0 .65.044 1.33.133 2.04.089.71.325 1.375.71 1.996.384.621.946 1.139 1.685 1.553.74.414 1.73.62 2.972.62h4.879v7.452h-8.073c-.946 0-2.07-.237-3.37-.71-1.301-.473-2.543-1.197-3.726-2.173-1.183-.976-2.188-2.188-3.016-3.637-.828-1.449-1.242-3.179-1.242-5.19V74.119c0-1.42-.325-2.572-.976-3.46-.65-.886-1.419-1.581-2.306-2.084a8.868 8.868 0 00-2.75-1.02c-.946-.177-1.715-.266-2.306-.266v-7.806zm43.965-3.538L80.6 52.041l2.306 7.097-12.063 3.903 7.628 10.378-6.12 4.435-7.63-10.467-7.45 10.201-5.943-4.524 7.628-10.023-12.152-4.17 2.306-7.096 12.064 4.17V43.347h7.451v12.596zm34.425 11.344c-.65 0-1.449.089-2.395.266-.946.177-1.863.488-2.75.931a6.356 6.356 0 00-2.262 1.908c-.62.828-.931 1.862-.931 3.104v17.564c0 2.01-.414 3.74-1.242 5.189-.828 1.449-1.833 2.661-3.016 3.637s-2.425 1.7-3.726 2.173c-1.3.473-2.424.71-3.37.71h-8.073v-7.451h4.88c1.241 0 2.232-.207 2.97-.621.74-.414 1.302-.932 1.686-1.553a4.9 4.9 0 00.71-1.995c.089-.71.133-1.39.133-2.04V72.432c0-1.715.325-3.134.976-4.258.65-1.124 1.434-2.01 2.35-2.661.917-.65 1.863-1.124 2.839-1.42.976-.295 1.818-.502 2.528-.62v-.178c-.71-.059-1.552-.207-2.528-.443-.976-.237-1.922-.68-2.839-1.33-.916-.651-1.7-1.583-2.35-2.795-.65-1.212-.976-2.853-.976-4.923V37.66c0-.651-.044-1.331-.133-2.04a4.909 4.909 0 00-.71-1.997c-.384-.62-.946-1.138-1.685-1.552-.74-.414-1.73-.62-2.972-.62h-4.879V24h8.073c.946 0 2.07.237 3.37.71 1.301.473 2.543 1.197 3.726 2.173 1.183.976 2.188 2.188 3.016 3.637.828 1.449 1.242 3.178 1.242 5.189v16.943c0 1.419.31 2.572.931 3.46a6.897 6.897 0 002.262 2.084 8.868 8.868 0 002.75 1.02c.946.177 1.745.266 2.395.266v7.806zm24.66 0c-.65 0-1.449.089-2.395.266-.946.177-1.863.488-2.75.931a6.356 6.356 0 00-2.262 1.908c-.62.828-.931 1.862-.931 3.104v17.564c0 2.01-.414 3.74-1.242 5.189-.828 1.449-1.833 2.661-3.016 3.637s-2.425 1.7-3.726 2.173c-1.3.473-2.424.71-3.37.71h-8.073v-7.451h4.88c1.241 0 2.232-.207 2.97-.621.74-.414 1.302-.932 1.686-1.553a4.9 4.9 0 00.71-1.995c.089-.71.133-1.39.133-2.04V72.432c0-1.715.325-3.134.976-4.258.65-1.124 1.434-2.01 2.35-2.661.917-.65 1.863-1.124 2.839-1.42.976-.295 1.818-.502 2.528-.62v-.178c-.71-.059-1.552-.207-2.528-.443-.976-.237-1.922-.68-2.839-1.33-.916-.651-1.7-1.583-2.35-2.795-.65-1.212-.976-2.853-.976-4.923V37.66c0-.651-.044-1.331-.133-2.04a4.909 4.909 0 00-.71-1.997c-.384-.62-.946-1.138-1.685-1.552-.74-.414-1.73-.62-2.972-.62h-4.879V24h8.073c.946 0 2.07.237 3.37.71 1.301.473 2.543 1.197 3.726 2.173 1.183.976 2.188 2.188 3.016 3.637.828 1.449 1.242 3.178 1.242 5.189v16.943c0 1.419.31 2.572.931 3.46a6.897 6.897 0 002.262 2.084 8.868 8.868 0 002.75 1.02c.946.177 1.745.266 2.395.266v7.806z\"/></svg>"},"$:/core/images/twitter":{"title":"$:/core/images/twitter","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-twitter tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M41.626 115.803A73.376 73.376 0 012 104.235c2.022.238 4.08.36 6.166.36 12.111 0 23.258-4.117 32.105-11.023-11.312-.208-20.859-7.653-24.148-17.883a25.98 25.98 0 0011.674-.441C15.971 72.881 7.061 62.474 7.061 49.997c0-.108 0-.216.002-.323a25.824 25.824 0 0011.709 3.22c-6.936-4.617-11.5-12.5-11.5-21.433 0-4.719 1.274-9.142 3.5-12.945 12.75 15.579 31.797 25.83 53.281 26.904-.44-1.884-.67-3.85-.67-5.868 0-14.22 11.575-25.75 25.852-25.75a25.865 25.865 0 0118.869 8.132 51.892 51.892 0 0016.415-6.248c-1.93 6.012-6.029 11.059-11.366 14.246A51.844 51.844 0 00128 25.878a52.428 52.428 0 01-12.9 13.33c.05 1.104.075 2.214.075 3.33 0 34.028-26 73.265-73.549 73.265\"/></svg>"},"$:/core/images/underline":{"title":"$:/core/images/underline","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-underline tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M7 117.421h114.248V128H7v-10.579zm97.871-18.525V0h-16.26v55.856c0 4.463-.605 8.576-1.816 12.338-1.212 3.762-3.03 7.046-5.452 9.851-2.423 2.806-5.452 4.974-9.086 6.504-3.635 1.53-7.939 2.296-12.912 2.296-6.25 0-11.159-1.786-14.73-5.356-3.57-3.571-5.356-8.417-5.356-14.538V0H23v65.038c0 5.356.542 10.234 1.626 14.633 1.084 4.4 2.965 8.194 5.643 11.382 2.678 3.188 6.185 5.643 10.52 7.365 4.337 1.721 9.756 2.582 16.26 2.582 7.27 0 13.582-1.435 18.938-4.304 5.356-2.87 9.755-7.365 13.199-13.486h.382v15.686h15.303z\"/></svg>"},"$:/core/images/unfold-all-button":{"title":"$:/core/images/unfold-all-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-unfold-all tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><rect width=\"128\" height=\"16\" rx=\"8\"/><rect width=\"128\" height=\"16\" y=\"64\" rx=\"8\"/><path d=\"M63.945 60.624c-2.05 0-4.101-.78-5.666-2.345L35.662 35.662c-3.125-3.125-3.13-8.195-.005-11.319 3.118-3.118 8.192-3.122 11.319.005L63.94 41.314l16.966-16.966c3.124-3.124 8.194-3.129 11.318-.005 3.118 3.118 3.122 8.192-.005 11.319L69.603 58.279a7.986 7.986 0 01-5.663 2.346zM64.004 124.565c-2.05 0-4.102-.78-5.666-2.345L35.721 99.603c-3.125-3.125-3.13-8.195-.005-11.319 3.118-3.118 8.191-3.122 11.318.005L64 105.255l16.966-16.966c3.124-3.124 8.194-3.129 11.318-.005 3.118 3.118 3.122 8.192-.005 11.319L69.662 122.22a7.986 7.986 0 01-5.663 2.346z\"/></g></svg>"},"$:/core/images/unfold-button":{"title":"$:/core/images/unfold-button","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-unfold tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><rect width=\"128\" height=\"16\" rx=\"8\"/><path d=\"M63.945 63.624c-2.05 0-4.101-.78-5.666-2.345L35.662 38.662c-3.125-3.125-3.13-8.195-.005-11.319 3.118-3.118 8.192-3.122 11.319.005L63.94 44.314l16.966-16.966c3.124-3.124 8.194-3.129 11.318-.005 3.118 3.118 3.122 8.192-.005 11.319L69.603 61.279a7.986 7.986 0 01-5.663 2.346zM64.004 105.682c-2.05.001-4.102-.78-5.666-2.344L35.721 80.721c-3.125-3.125-3.13-8.195-.005-11.319 3.118-3.118 8.191-3.122 11.318.005L64 86.373l16.966-16.966c3.124-3.125 8.194-3.13 11.318-.005 3.118 3.118 3.122 8.192-.005 11.319l-22.617 22.617a7.986 7.986 0 01-5.663 2.346z\"/></g></svg>"},"$:/core/images/unlocked-padlock":{"title":"$:/core/images/unlocked-padlock","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-unlocked-padlock tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M48.627 64H105v32.01C105 113.674 90.674 128 73.001 128H56C38.318 128 24 113.677 24 96.01V64h6.136c-10.455-12.651-27.364-35.788-4.3-55.142 24.636-20.672 45.835 4.353 55.777 16.201 9.943 11.85-2.676 22.437-12.457 9.892-9.78-12.545-21.167-24.146-33.207-14.043-12.041 10.104-1.757 22.36 8.813 34.958 2.467 2.94 3.641 5.732 3.865 8.134zm19.105 28.364A8.503 8.503 0 0064.5 76a8.5 8.5 0 00-3.498 16.25l-5.095 22.77H72.8l-5.07-22.656z\"/></svg>"},"$:/core/images/up-arrow":{"title":"$:/core/images/up-arrow","created":"20150316000544368","modified":"20150316000831867","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-up-arrow tc-image-button\" viewBox=\"0 0 128 128\"><path d=\"M63.892.281c2.027 0 4.054.77 5.6 2.316l55.98 55.98a7.92 7.92 0 010 11.196c-3.086 3.085-8.104 3.092-11.196 0L63.894 19.393 13.513 69.774a7.92 7.92 0 01-11.196 0c-3.085-3.086-3.092-8.105 0-11.196l55.98-55.98A7.892 7.892 0 0163.893.28z\"/></svg>"},"$:/core/images/video":{"title":"$:/core/images/video","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-video tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M64 12c-34.91 0-55.273 2.917-58.182 5.833C2.91 20.75 0 41.167 0 64.5c0 23.333 2.91 43.75 5.818 46.667C8.728 114.083 29.091 117 64 117c34.91 0 55.273-2.917 58.182-5.833C125.09 108.25 128 87.833 128 64.5c0-23.333-2.91-43.75-5.818-46.667C119.272 14.917 98.909 12 64 12zm-9.084 32.618c-3.813-2.542-6.905-.879-6.905 3.698v31.368c0 4.585 3.099 6.235 6.905 3.698l22.168-14.779c3.813-2.542 3.806-6.669 0-9.206L54.916 44.618z\"/></svg>"},"$:/core/images/warning":{"title":"$:/core/images/warning","tags":"$:/tags/Image","text":"\\parameters (size:\"22pt\")\n<svg width=<<size>> height=<<size>> class=\"tc-image-warning tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M57.072 11c3.079-5.333 10.777-5.333 13.856 0l55.426 96c3.079 5.333-.77 12-6.928 12H8.574c-6.158 0-10.007-6.667-6.928-12l55.426-96zM64 37c-4.418 0-8 3.582-8 7.994v28.012C56 77.421 59.59 81 64 81c4.418 0 8-3.582 8-7.994V44.994C72 40.579 68.41 37 64 37zm0 67a8 8 0 100-16 8 8 0 000 16z\"/></svg>"},"$:/language/Buttons/AdvancedSearch/Caption":{"title":"$:/language/Buttons/AdvancedSearch/Caption","text":"advanced search"},"$:/language/Buttons/AdvancedSearch/Hint":{"title":"$:/language/Buttons/AdvancedSearch/Hint","text":"Advanced search"},"$:/language/Buttons/Cancel/Caption":{"title":"$:/language/Buttons/Cancel/Caption","text":"cancel"},"$:/language/Buttons/Cancel/Hint":{"title":"$:/language/Buttons/Cancel/Hint","text":"Discard changes to this tiddler"},"$:/language/Buttons/Clone/Caption":{"title":"$:/language/Buttons/Clone/Caption","text":"clone"},"$:/language/Buttons/Clone/Hint":{"title":"$:/language/Buttons/Clone/Hint","text":"Clone this tiddler"},"$:/language/Buttons/Close/Caption":{"title":"$:/language/Buttons/Close/Caption","text":"close"},"$:/language/Buttons/Close/Hint":{"title":"$:/language/Buttons/Close/Hint","text":"Close this tiddler"},"$:/language/Buttons/CloseAll/Caption":{"title":"$:/language/Buttons/CloseAll/Caption","text":"close all"},"$:/language/Buttons/CloseAll/Hint":{"title":"$:/language/Buttons/CloseAll/Hint","text":"Close all tiddlers"},"$:/language/Buttons/CloseOthers/Caption":{"title":"$:/language/Buttons/CloseOthers/Caption","text":"close others"},"$:/language/Buttons/CloseOthers/Hint":{"title":"$:/language/Buttons/CloseOthers/Hint","text":"Close other tiddlers"},"$:/language/Buttons/ControlPanel/Caption":{"title":"$:/language/Buttons/ControlPanel/Caption","text":"control panel"},"$:/language/Buttons/ControlPanel/Hint":{"title":"$:/language/Buttons/ControlPanel/Hint","text":"Open control panel"},"$:/language/Buttons/CopyToClipboard/Caption":{"title":"$:/language/Buttons/CopyToClipboard/Caption","text":"copy to clipboard"},"$:/language/Buttons/CopyToClipboard/Hint":{"title":"$:/language/Buttons/CopyToClipboard/Hint","text":"Copy this text to the clipboard"},"$:/language/Buttons/Delete/Caption":{"title":"$:/language/Buttons/Delete/Caption","text":"delete"},"$:/language/Buttons/Delete/Hint":{"title":"$:/language/Buttons/Delete/Hint","text":"Delete this tiddler"},"$:/language/Buttons/DeleteTiddlers/Caption":{"title":"$:/language/Buttons/DeleteTiddlers/Caption","text":"delete tiddlers"},"$:/language/Buttons/DeleteTiddlers/Hint":{"title":"$:/language/Buttons/DeleteTiddlers/Hint","text":"Delete tiddlers"},"$:/language/Buttons/Edit/Caption":{"title":"$:/language/Buttons/Edit/Caption","text":"edit"},"$:/language/Buttons/Edit/Hint":{"title":"$:/language/Buttons/Edit/Hint","text":"Edit this tiddler"},"$:/language/Buttons/Encryption/Caption":{"title":"$:/language/Buttons/Encryption/Caption","text":"encryption"},"$:/language/Buttons/Encryption/Hint":{"title":"$:/language/Buttons/Encryption/Hint","text":"Set or clear a password for saving this wiki"},"$:/language/Buttons/Encryption/ClearPassword/Caption":{"title":"$:/language/Buttons/Encryption/ClearPassword/Caption","text":"clear password"},"$:/language/Buttons/Encryption/ClearPassword/Hint":{"title":"$:/language/Buttons/Encryption/ClearPassword/Hint","text":"Clear the password and save this wiki without encryption"},"$:/language/Buttons/Encryption/SetPassword/Caption":{"title":"$:/language/Buttons/Encryption/SetPassword/Caption","text":"set password"},"$:/language/Buttons/Encryption/SetPassword/Hint":{"title":"$:/language/Buttons/Encryption/SetPassword/Hint","text":"Set a password for saving this wiki with encryption"},"$:/language/Buttons/EmergencyDownload/Caption":{"title":"$:/language/Buttons/EmergencyDownload/Caption","text":"download tiddlers as json"},"$:/language/Buttons/ExportPage/Caption":{"title":"$:/language/Buttons/ExportPage/Caption","text":"export all"},"$:/language/Buttons/ExportPage/Hint":{"title":"$:/language/Buttons/ExportPage/Hint","text":"Export all tiddlers"},"$:/language/Buttons/ExportTiddler/Caption":{"title":"$:/language/Buttons/ExportTiddler/Caption","text":"export tiddler"},"$:/language/Buttons/ExportTiddler/Hint":{"title":"$:/language/Buttons/ExportTiddler/Hint","text":"Export tiddler"},"$:/language/Buttons/ExportTiddlers/Caption":{"title":"$:/language/Buttons/ExportTiddlers/Caption","text":"export tiddlers"},"$:/language/Buttons/ExportTiddlers/Hint":{"title":"$:/language/Buttons/ExportTiddlers/Hint","text":"Export tiddlers"},"$:/language/Buttons/SidebarSearch/Hint":{"title":"$:/language/Buttons/SidebarSearch/Hint","text":"Select the sidebar search field"},"$:/language/Buttons/Fold/Caption":{"title":"$:/language/Buttons/Fold/Caption","text":"fold tiddler"},"$:/language/Buttons/Fold/Hint":{"title":"$:/language/Buttons/Fold/Hint","text":"Fold the body of this tiddler"},"$:/language/Buttons/Fold/FoldBar/Caption":{"title":"$:/language/Buttons/Fold/FoldBar/Caption","text":"fold-bar"},"$:/language/Buttons/Fold/FoldBar/Hint":{"title":"$:/language/Buttons/Fold/FoldBar/Hint","text":"Optional bars to fold and unfold tiddlers"},"$:/language/Buttons/Unfold/Caption":{"title":"$:/language/Buttons/Unfold/Caption","text":"unfold tiddler"},"$:/language/Buttons/Unfold/Hint":{"title":"$:/language/Buttons/Unfold/Hint","text":"Unfold the body of this tiddler"},"$:/language/Buttons/FoldOthers/Caption":{"title":"$:/language/Buttons/FoldOthers/Caption","text":"fold other tiddlers"},"$:/language/Buttons/FoldOthers/Hint":{"title":"$:/language/Buttons/FoldOthers/Hint","text":"Fold the bodies of other opened tiddlers"},"$:/language/Buttons/FoldAll/Caption":{"title":"$:/language/Buttons/FoldAll/Caption","text":"fold all tiddlers"},"$:/language/Buttons/FoldAll/Hint":{"title":"$:/language/Buttons/FoldAll/Hint","text":"Fold the bodies of all opened tiddlers"},"$:/language/Buttons/UnfoldAll/Caption":{"title":"$:/language/Buttons/UnfoldAll/Caption","text":"unfold all tiddlers"},"$:/language/Buttons/UnfoldAll/Hint":{"title":"$:/language/Buttons/UnfoldAll/Hint","text":"Unfold the bodies of all opened tiddlers"},"$:/language/Buttons/FullScreen/Caption":{"title":"$:/language/Buttons/FullScreen/Caption","text":"full-screen"},"$:/language/Buttons/FullScreen/Hint":{"title":"$:/language/Buttons/FullScreen/Hint","text":"Enter or leave full-screen mode"},"$:/language/Buttons/Help/Caption":{"title":"$:/language/Buttons/Help/Caption","text":"help"},"$:/language/Buttons/Help/Hint":{"title":"$:/language/Buttons/Help/Hint","text":"Show help panel"},"$:/language/Buttons/Import/Caption":{"title":"$:/language/Buttons/Import/Caption","text":"import"},"$:/language/Buttons/Import/Hint":{"title":"$:/language/Buttons/Import/Hint","text":"Import many types of file including text, image, TiddlyWiki or JSON"},"$:/language/Buttons/Info/Caption":{"title":"$:/language/Buttons/Info/Caption","text":"info"},"$:/language/Buttons/Info/Hint":{"title":"$:/language/Buttons/Info/Hint","text":"Show information for this tiddler"},"$:/language/Buttons/Home/Caption":{"title":"$:/language/Buttons/Home/Caption","text":"home"},"$:/language/Buttons/Home/Hint":{"title":"$:/language/Buttons/Home/Hint","text":"Open the default tiddlers"},"$:/language/Buttons/Language/Caption":{"title":"$:/language/Buttons/Language/Caption","text":"language"},"$:/language/Buttons/Language/Hint":{"title":"$:/language/Buttons/Language/Hint","text":"Choose the user interface language"},"$:/language/Buttons/LayoutSwitcher/Hint":{"title":"$:/language/Buttons/LayoutSwitcher/Hint","text":"Open layout switcher"},"$:/language/Buttons/LayoutSwitcher/Caption":{"title":"$:/language/Buttons/LayoutSwitcher/Caption","text":"layout"},"$:/language/Buttons/Manager/Caption":{"title":"$:/language/Buttons/Manager/Caption","text":"tiddler manager"},"$:/language/Buttons/Manager/Hint":{"title":"$:/language/Buttons/Manager/Hint","text":"Open tiddler manager"},"$:/language/Buttons/More/Caption":{"title":"$:/language/Buttons/More/Caption","text":"more"},"$:/language/Buttons/More/Hint":{"title":"$:/language/Buttons/More/Hint","text":"More actions"},"$:/language/Buttons/NewHere/Caption":{"title":"$:/language/Buttons/NewHere/Caption","text":"new here"},"$:/language/Buttons/NewHere/Hint":{"title":"$:/language/Buttons/NewHere/Hint","text":"Create a new tiddler tagged with this one"},"$:/language/Buttons/NetworkActivity/Caption":{"title":"$:/language/Buttons/NetworkActivity/Caption","text":"network activity"},"$:/language/Buttons/NetworkActivity/Hint":{"title":"$:/language/Buttons/NetworkActivity/Hint","text":"Cancel all network activity"},"$:/language/Buttons/NewJournal/Caption":{"title":"$:/language/Buttons/NewJournal/Caption","text":"new journal"},"$:/language/Buttons/NewJournal/Hint":{"title":"$:/language/Buttons/NewJournal/Hint","text":"Create a new journal tiddler"},"$:/language/Buttons/NewJournalHere/Caption":{"title":"$:/language/Buttons/NewJournalHere/Caption","text":"new journal here"},"$:/language/Buttons/NewJournalHere/Hint":{"title":"$:/language/Buttons/NewJournalHere/Hint","text":"Create a new journal tiddler tagged with this one"},"$:/language/Buttons/NewImage/Caption":{"title":"$:/language/Buttons/NewImage/Caption","text":"new image"},"$:/language/Buttons/NewImage/Hint":{"title":"$:/language/Buttons/NewImage/Hint","text":"Create a new image tiddler"},"$:/language/Buttons/NewMarkdown/Caption":{"title":"$:/language/Buttons/NewMarkdown/Caption","text":"new Markdown tiddler"},"$:/language/Buttons/NewMarkdown/Hint":{"title":"$:/language/Buttons/NewMarkdown/Hint","text":"Create a new Markdown tiddler"},"$:/language/Buttons/NewTiddler/Caption":{"title":"$:/language/Buttons/NewTiddler/Caption","text":"new tiddler"},"$:/language/Buttons/NewTiddler/Hint":{"title":"$:/language/Buttons/NewTiddler/Hint","text":"Create a new tiddler"},"$:/language/Buttons/OpenControlPanel/Hint":{"title":"$:/language/Buttons/OpenControlPanel/Hint","text":"Open control panel"},"$:/language/Buttons/OpenWindow/Caption":{"title":"$:/language/Buttons/OpenWindow/Caption","text":"open in new window"},"$:/language/Buttons/OpenWindow/Hint":{"title":"$:/language/Buttons/OpenWindow/Hint","text":"Open tiddler in new window"},"$:/language/Buttons/Palette/Caption":{"title":"$:/language/Buttons/Palette/Caption","text":"palette"},"$:/language/Buttons/Palette/Hint":{"title":"$:/language/Buttons/Palette/Hint","text":"Choose the colour palette"},"$:/language/Buttons/Permalink/Caption":{"title":"$:/language/Buttons/Permalink/Caption","text":"permalink"},"$:/language/Buttons/Permalink/Hint":{"title":"$:/language/Buttons/Permalink/Hint","text":"Set browser address bar to a direct link to this tiddler"},"$:/language/Buttons/Permaview/Caption":{"title":"$:/language/Buttons/Permaview/Caption","text":"permaview"},"$:/language/Buttons/Permaview/Hint":{"title":"$:/language/Buttons/Permaview/Hint","text":"Set browser address bar to a direct link to all the tiddlers in this story"},"$:/language/Buttons/Print/Caption":{"title":"$:/language/Buttons/Print/Caption","text":"print page"},"$:/language/Buttons/Print/Hint":{"title":"$:/language/Buttons/Print/Hint","text":"Print the current page"},"$:/language/Buttons/Refresh/Caption":{"title":"$:/language/Buttons/Refresh/Caption","text":"refresh"},"$:/language/Buttons/Refresh/Hint":{"title":"$:/language/Buttons/Refresh/Hint","text":"Perform a full refresh of the wiki"},"$:/language/Buttons/Save/Caption":{"title":"$:/language/Buttons/Save/Caption","text":"ok"},"$:/language/Buttons/Save/Hint":{"title":"$:/language/Buttons/Save/Hint","text":"Confirm changes to this tiddler"},"$:/language/Buttons/SaveWiki/Caption":{"title":"$:/language/Buttons/SaveWiki/Caption","text":"save changes"},"$:/language/Buttons/SaveWiki/Hint":{"title":"$:/language/Buttons/SaveWiki/Hint","text":"Save changes"},"$:/language/Buttons/StoryView/Caption":{"title":"$:/language/Buttons/StoryView/Caption","text":"storyview"},"$:/language/Buttons/StoryView/Hint":{"title":"$:/language/Buttons/StoryView/Hint","text":"Choose the story visualisation"},"$:/language/Buttons/HideSideBar/Caption":{"title":"$:/language/Buttons/HideSideBar/Caption","text":"hide sidebar"},"$:/language/Buttons/HideSideBar/Hint":{"title":"$:/language/Buttons/HideSideBar/Hint","text":"Hide sidebar"},"$:/language/Buttons/ShowSideBar/Caption":{"title":"$:/language/Buttons/ShowSideBar/Caption","text":"show sidebar"},"$:/language/Buttons/ShowSideBar/Hint":{"title":"$:/language/Buttons/ShowSideBar/Hint","text":"Show sidebar"},"$:/language/Buttons/TagManager/Caption":{"title":"$:/language/Buttons/TagManager/Caption","text":"tag manager"},"$:/language/Buttons/TagManager/Hint":{"title":"$:/language/Buttons/TagManager/Hint","text":"Open tag manager"},"$:/language/Buttons/TestCaseImport/Caption":{"title":"$:/language/Buttons/TestCaseImport/Caption","text":"import tiddlers"},"$:/language/Buttons/TestCaseImport/Hint":{"title":"$:/language/Buttons/TestCaseImport/Hint","text":"Import tiddlers"},"$:/language/Buttons/Timestamp/Caption":{"title":"$:/language/Buttons/Timestamp/Caption","text":"timestamps"},"$:/language/Buttons/Timestamp/Hint":{"title":"$:/language/Buttons/Timestamp/Hint","text":"Choose whether modifications update timestamps"},"$:/language/Buttons/Timestamp/On/Caption":{"title":"$:/language/Buttons/Timestamp/On/Caption","text":"timestamps are on"},"$:/language/Buttons/Timestamp/On/Hint":{"title":"$:/language/Buttons/Timestamp/On/Hint","text":"Update timestamps when tiddlers are modified"},"$:/language/Buttons/Timestamp/Off/Caption":{"title":"$:/language/Buttons/Timestamp/Off/Caption","text":"timestamps are off"},"$:/language/Buttons/Timestamp/Off/Hint":{"title":"$:/language/Buttons/Timestamp/Off/Hint","text":"Don't update timestamps when tiddlers are modified"},"$:/language/Buttons/Theme/Caption":{"title":"$:/language/Buttons/Theme/Caption","text":"theme"},"$:/language/Buttons/Theme/Hint":{"title":"$:/language/Buttons/Theme/Hint","text":"Choose the display theme"},"$:/language/Buttons/Bold/Caption":{"title":"$:/language/Buttons/Bold/Caption","text":"bold"},"$:/language/Buttons/Bold/Hint":{"title":"$:/language/Buttons/Bold/Hint","text":"Apply bold formatting to selection"},"$:/language/Buttons/Clear/Caption":{"title":"$:/language/Buttons/Clear/Caption","text":"clear"},"$:/language/Buttons/Clear/Hint":{"title":"$:/language/Buttons/Clear/Hint","text":"Clear image to solid colour"},"$:/language/Buttons/EditorHeight/Caption":{"title":"$:/language/Buttons/EditorHeight/Caption","text":"editor height"},"$:/language/Buttons/EditorHeight/Caption/Auto":{"title":"$:/language/Buttons/EditorHeight/Caption/Auto","text":"Automatically adjust height to fit content"},"$:/language/Buttons/EditorHeight/Caption/Fixed":{"title":"$:/language/Buttons/EditorHeight/Caption/Fixed","text":"Fixed height:"},"$:/language/Buttons/EditorHeight/Hint":{"title":"$:/language/Buttons/EditorHeight/Hint","text":"Choose the height of the text editor"},"$:/language/Buttons/Excise/Caption":{"title":"$:/language/Buttons/Excise/Caption","text":"excise"},"$:/language/Buttons/Excise/Caption/Excise":{"title":"$:/language/Buttons/Excise/Caption/Excise","text":"Perform excision"},"$:/language/Buttons/Excise/Caption/MacroName":{"title":"$:/language/Buttons/Excise/Caption/MacroName","text":"Macro name:"},"$:/language/Buttons/Excise/Caption/NewTitle":{"title":"$:/language/Buttons/Excise/Caption/NewTitle","text":"Title of new tiddler:"},"$:/language/Buttons/Excise/Caption/Replace":{"title":"$:/language/Buttons/Excise/Caption/Replace","text":"Replace excised text with:"},"$:/language/Buttons/Excise/Caption/Replace/Macro":{"title":"$:/language/Buttons/Excise/Caption/Replace/Macro","text":"macro"},"$:/language/Buttons/Excise/Caption/Replace/Link":{"title":"$:/language/Buttons/Excise/Caption/Replace/Link","text":"link"},"$:/language/Buttons/Excise/Caption/Replace/Transclusion":{"title":"$:/language/Buttons/Excise/Caption/Replace/Transclusion","text":"transclusion"},"$:/language/Buttons/Excise/Caption/Tag":{"title":"$:/language/Buttons/Excise/Caption/Tag","text":"Tag new tiddler with the title of this tiddler"},"$:/language/Buttons/Excise/Caption/TiddlerExists":{"title":"$:/language/Buttons/Excise/Caption/TiddlerExists","text":"Warning: tiddler already exists"},"$:/language/Buttons/Excise/DefaultTitle":{"title":"$:/language/Buttons/Excise/DefaultTitle","text":"New Excision"},"$:/language/Buttons/Excise/Hint":{"title":"$:/language/Buttons/Excise/Hint","text":"Excise the selected text into a new tiddler"},"$:/language/Buttons/Heading1/Caption":{"title":"$:/language/Buttons/Heading1/Caption","text":"heading 1"},"$:/language/Buttons/Heading1/Hint":{"title":"$:/language/Buttons/Heading1/Hint","text":"Apply heading level 1 formatting to lines containing selection"},"$:/language/Buttons/Heading2/Caption":{"title":"$:/language/Buttons/Heading2/Caption","text":"heading 2"},"$:/language/Buttons/Heading2/Hint":{"title":"$:/language/Buttons/Heading2/Hint","text":"Apply heading level 2 formatting to lines containing selection"},"$:/language/Buttons/Heading3/Caption":{"title":"$:/language/Buttons/Heading3/Caption","text":"heading 3"},"$:/language/Buttons/Heading3/Hint":{"title":"$:/language/Buttons/Heading3/Hint","text":"Apply heading level 3 formatting to lines containing selection"},"$:/language/Buttons/Heading4/Caption":{"title":"$:/language/Buttons/Heading4/Caption","text":"heading 4"},"$:/language/Buttons/Heading4/Hint":{"title":"$:/language/Buttons/Heading4/Hint","text":"Apply heading level 4 formatting to lines containing selection"},"$:/language/Buttons/Heading5/Caption":{"title":"$:/language/Buttons/Heading5/Caption","text":"heading 5"},"$:/language/Buttons/Heading5/Hint":{"title":"$:/language/Buttons/Heading5/Hint","text":"Apply heading level 5 formatting to lines containing selection"},"$:/language/Buttons/Heading6/Caption":{"title":"$:/language/Buttons/Heading6/Caption","text":"heading 6"},"$:/language/Buttons/Heading6/Hint":{"title":"$:/language/Buttons/Heading6/Hint","text":"Apply heading level 6 formatting to lines containing selection"},"$:/language/Buttons/Italic/Caption":{"title":"$:/language/Buttons/Italic/Caption","text":"italic"},"$:/language/Buttons/Italic/Hint":{"title":"$:/language/Buttons/Italic/Hint","text":"Apply italic formatting to selection"},"$:/language/Buttons/LineWidth/Caption":{"title":"$:/language/Buttons/LineWidth/Caption","text":"line width"},"$:/language/Buttons/LineWidth/Hint":{"title":"$:/language/Buttons/LineWidth/Hint","text":"Set line width for painting"},"$:/language/Buttons/Link/Caption":{"title":"$:/language/Buttons/Link/Caption","text":"link"},"$:/language/Buttons/Link/Hint":{"title":"$:/language/Buttons/Link/Hint","text":"Create wikitext link"},"$:/language/Buttons/Linkify/Caption":{"title":"$:/language/Buttons/Linkify/Caption","text":"wikilink"},"$:/language/Buttons/Linkify/Hint":{"title":"$:/language/Buttons/Linkify/Hint","text":"Wrap selection in square brackets"},"$:/language/Buttons/ListBullet/Caption":{"title":"$:/language/Buttons/ListBullet/Caption","text":"bulleted list"},"$:/language/Buttons/ListBullet/Hint":{"title":"$:/language/Buttons/ListBullet/Hint","text":"Apply bulleted list formatting to lines containing selection"},"$:/language/Buttons/ListNumber/Caption":{"title":"$:/language/Buttons/ListNumber/Caption","text":"numbered list"},"$:/language/Buttons/ListNumber/Hint":{"title":"$:/language/Buttons/ListNumber/Hint","text":"Apply numbered list formatting to lines containing selection"},"$:/language/Buttons/MonoBlock/Caption":{"title":"$:/language/Buttons/MonoBlock/Caption","text":"monospaced block"},"$:/language/Buttons/MonoBlock/Hint":{"title":"$:/language/Buttons/MonoBlock/Hint","text":"Apply monospaced block formatting to lines containing selection"},"$:/language/Buttons/MonoLine/Caption":{"title":"$:/language/Buttons/MonoLine/Caption","text":"monospaced"},"$:/language/Buttons/MonoLine/Hint":{"title":"$:/language/Buttons/MonoLine/Hint","text":"Apply monospaced character formatting to selection"},"$:/language/Buttons/Opacity/Caption":{"title":"$:/language/Buttons/Opacity/Caption","text":"opacity"},"$:/language/Buttons/Opacity/Hint":{"title":"$:/language/Buttons/Opacity/Hint","text":"Set painting opacity"},"$:/language/Buttons/Paint/Caption":{"title":"$:/language/Buttons/Paint/Caption","text":"paint colour"},"$:/language/Buttons/Paint/Hint":{"title":"$:/language/Buttons/Paint/Hint","text":"Set painting colour"},"$:/language/Buttons/Picture/Caption":{"title":"$:/language/Buttons/Picture/Caption","text":"picture"},"$:/language/Buttons/Picture/Hint":{"title":"$:/language/Buttons/Picture/Hint","text":"Insert picture"},"$:/language/Buttons/Preview/Caption":{"title":"$:/language/Buttons/Preview/Caption","text":"preview"},"$:/language/Buttons/Preview/Hint":{"title":"$:/language/Buttons/Preview/Hint","text":"Show preview pane"},"$:/language/Buttons/PreviewType/Caption":{"title":"$:/language/Buttons/PreviewType/Caption","text":"preview type"},"$:/language/Buttons/PreviewType/Hint":{"title":"$:/language/Buttons/PreviewType/Hint","text":"Choose preview type"},"$:/language/Buttons/Quote/Caption":{"title":"$:/language/Buttons/Quote/Caption","text":"quote"},"$:/language/Buttons/Quote/Hint":{"title":"$:/language/Buttons/Quote/Hint","text":"Apply quoted text formatting to lines containing selection"},"$:/language/Buttons/RotateLeft/Caption":{"title":"$:/language/Buttons/RotateLeft/Caption","text":"rotate left"},"$:/language/Buttons/RotateLeft/Hint":{"title":"$:/language/Buttons/RotateLeft/Hint","text":"Rotate image left by 90 degrees"},"$:/language/Buttons/Size/Caption":{"title":"$:/language/Buttons/Size/Caption","text":"image size"},"$:/language/Buttons/Size/Caption/Height":{"title":"$:/language/Buttons/Size/Caption/Height","text":"Height:"},"$:/language/Buttons/Size/Caption/Resize":{"title":"$:/language/Buttons/Size/Caption/Resize","text":"Resize image"},"$:/language/Buttons/Size/Caption/Width":{"title":"$:/language/Buttons/Size/Caption/Width","text":"Width:"},"$:/language/Buttons/Size/Hint":{"title":"$:/language/Buttons/Size/Hint","text":"Set image size"},"$:/language/Buttons/Stamp/Caption":{"title":"$:/language/Buttons/Stamp/Caption","text":"stamp"},"$:/language/Buttons/Stamp/Caption/New":{"title":"$:/language/Buttons/Stamp/Caption/New","text":"Add your own"},"$:/language/Buttons/Stamp/Hint":{"title":"$:/language/Buttons/Stamp/Hint","text":"Insert a preconfigured snippet of text"},"$:/language/Buttons/Stamp/New/Title":{"title":"$:/language/Buttons/Stamp/New/Title","text":"Name as shown in menu"},"$:/language/Buttons/Stamp/New/Text":{"title":"$:/language/Buttons/Stamp/New/Text","text":"Text of snippet. (Remember to add a descriptive title in the caption field)."},"$:/language/Buttons/Strikethrough/Caption":{"title":"$:/language/Buttons/Strikethrough/Caption","text":"strikethrough"},"$:/language/Buttons/Strikethrough/Hint":{"title":"$:/language/Buttons/Strikethrough/Hint","text":"Apply strikethrough formatting to selection"},"$:/language/Buttons/Subscript/Caption":{"title":"$:/language/Buttons/Subscript/Caption","text":"subscript"},"$:/language/Buttons/Subscript/Hint":{"title":"$:/language/Buttons/Subscript/Hint","text":"Apply subscript formatting to selection"},"$:/language/Buttons/Superscript/Caption":{"title":"$:/language/Buttons/Superscript/Caption","text":"superscript"},"$:/language/Buttons/Superscript/Hint":{"title":"$:/language/Buttons/Superscript/Hint","text":"Apply superscript formatting to selection"},"$:/language/Buttons/ToggleSidebar/Hint":{"title":"$:/language/Buttons/ToggleSidebar/Hint","text":"Toggle the sidebar visibility"},"$:/language/Buttons/Transcludify/Caption":{"title":"$:/language/Buttons/Transcludify/Caption","text":"transclusion"},"$:/language/Buttons/Transcludify/Hint":{"title":"$:/language/Buttons/Transcludify/Hint","text":"Wrap selection in curly brackets"},"$:/language/Buttons/Underline/Caption":{"title":"$:/language/Buttons/Underline/Caption","text":"underline"},"$:/language/Buttons/Underline/Hint":{"title":"$:/language/Buttons/Underline/Hint","text":"Apply underline formatting to selection"},"$:/language/ControlPanel/Advanced/Caption":{"title":"$:/language/ControlPanel/Advanced/Caption","text":"Advanced"},"$:/language/ControlPanel/Advanced/Hint":{"title":"$:/language/ControlPanel/Advanced/Hint","text":"Internal information about this TiddlyWiki"},"$:/language/ControlPanel/Appearance/Caption":{"title":"$:/language/ControlPanel/Appearance/Caption","text":"Appearance"},"$:/language/ControlPanel/Appearance/Hint":{"title":"$:/language/ControlPanel/Appearance/Hint","text":"Ways to customise the appearance of your TiddlyWiki."},"$:/language/ControlPanel/Basics/AnimDuration/Prompt":{"title":"$:/language/ControlPanel/Basics/AnimDuration/Prompt","text":"Animation duration"},"$:/language/ControlPanel/Basics/AutoFocus/Prompt":{"title":"$:/language/ControlPanel/Basics/AutoFocus/Prompt","text":"Default focus field for new tiddlers"},"$:/language/ControlPanel/Basics/Caption":{"title":"$:/language/ControlPanel/Basics/Caption","text":"Basics"},"$:/language/ControlPanel/Basics/DefaultTiddlers/BottomHint":{"title":"$:/language/ControlPanel/Basics/DefaultTiddlers/BottomHint","text":"Use &#91;&#91;double square brackets&#93;&#93; for titles with spaces. Or you can choose to {{retain story ordering||$:/snippets/retain-story-ordering-button}}"},"$:/language/ControlPanel/Basics/DefaultTiddlers/Prompt":{"title":"$:/language/ControlPanel/Basics/DefaultTiddlers/Prompt","text":"Default tiddlers"},"$:/language/ControlPanel/Basics/DefaultTiddlers/TopHint":{"title":"$:/language/ControlPanel/Basics/DefaultTiddlers/TopHint","text":"Choose which tiddlers are displayed at startup"},"$:/language/ControlPanel/Basics/Language/Prompt":{"title":"$:/language/ControlPanel/Basics/Language/Prompt","text":"Hello! Current language:"},"$:/language/ControlPanel/Basics/NewJournal/Title/Prompt":{"title":"$:/language/ControlPanel/Basics/NewJournal/Title/Prompt","text":"Title of new journal tiddlers"},"$:/language/ControlPanel/Basics/NewJournal/Text/Prompt":{"title":"$:/language/ControlPanel/Basics/NewJournal/Text/Prompt","text":"Text for new journal tiddlers"},"$:/language/ControlPanel/Basics/NewJournal/Tags/Prompt":{"title":"$:/language/ControlPanel/Basics/NewJournal/Tags/Prompt","text":"Tags for new journal tiddlers"},"$:/language/ControlPanel/Basics/NewTiddler/Title/Prompt":{"title":"$:/language/ControlPanel/Basics/NewTiddler/Title/Prompt","text":"Title of new tiddlers"},"$:/language/ControlPanel/Basics/NewTiddler/Tags/Prompt":{"title":"$:/language/ControlPanel/Basics/NewTiddler/Tags/Prompt","text":"Tags for new tiddlers"},"$:/language/ControlPanel/Basics/OverriddenShadowTiddlers/Prompt":{"title":"$:/language/ControlPanel/Basics/OverriddenShadowTiddlers/Prompt","text":"Number of overridden shadow tiddlers"},"$:/language/ControlPanel/Basics/RemoveTags":{"title":"$:/language/ControlPanel/Basics/RemoveTags","text":"Update to current format"},"$:/language/ControlPanel/Basics/RemoveTags/Hint":{"title":"$:/language/ControlPanel/Basics/RemoveTags/Hint","text":"Update the tags configuration to the latest format"},"$:/language/ControlPanel/Basics/ShadowTiddlers/Prompt":{"title":"$:/language/ControlPanel/Basics/ShadowTiddlers/Prompt","text":"Number of shadow tiddlers"},"$:/language/ControlPanel/Basics/Subtitle/Prompt":{"title":"$:/language/ControlPanel/Basics/Subtitle/Prompt","text":"Subtitle"},"$:/language/ControlPanel/Basics/SystemTiddlers/Prompt":{"title":"$:/language/ControlPanel/Basics/SystemTiddlers/Prompt","text":"Number of system tiddlers"},"$:/language/ControlPanel/Basics/Tags/Prompt":{"title":"$:/language/ControlPanel/Basics/Tags/Prompt","text":"Number of tags"},"$:/language/ControlPanel/Basics/Tiddlers/Prompt":{"title":"$:/language/ControlPanel/Basics/Tiddlers/Prompt","text":"Number of tiddlers"},"$:/language/ControlPanel/Basics/Title/Prompt":{"title":"$:/language/ControlPanel/Basics/Title/Prompt","text":"Title of this ~TiddlyWiki"},"$:/language/ControlPanel/Basics/Username/Prompt":{"title":"$:/language/ControlPanel/Basics/Username/Prompt","text":"Username for signing edits"},"$:/language/ControlPanel/Basics/Version/Prompt":{"title":"$:/language/ControlPanel/Basics/Version/Prompt","text":"~TiddlyWiki version"},"$:/language/ControlPanel/Cascades/Caption":{"title":"$:/language/ControlPanel/Cascades/Caption","text":"Cascades"},"$:/language/ControlPanel/Cascades/Hint":{"title":"$:/language/ControlPanel/Cascades/Hint","text":"These global rules are used to dynamically choose certain templates. The result of the cascade is the result of the first filter in the sequence that returns a result"},"$:/language/ControlPanel/Cascades/TagPrompt":{"title":"$:/language/ControlPanel/Cascades/TagPrompt","text":"Filters tagged <$macrocall $name=\"tag\" tag=<<currentTiddler>>/>"},"$:/language/ControlPanel/EditorTypes/Caption":{"title":"$:/language/ControlPanel/EditorTypes/Caption","text":"Editor Types"},"$:/language/ControlPanel/EditorTypes/Editor/Caption":{"title":"$:/language/ControlPanel/EditorTypes/Editor/Caption","text":"Editor"},"$:/language/ControlPanel/EditorTypes/Hint":{"title":"$:/language/ControlPanel/EditorTypes/Hint","text":"These tiddlers determine which editor is used to edit specific tiddler types."},"$:/language/ControlPanel/EditorTypes/Type/Caption":{"title":"$:/language/ControlPanel/EditorTypes/Type/Caption","text":"Type"},"$:/language/ControlPanel/EditTemplateBody/Caption":{"title":"$:/language/ControlPanel/EditTemplateBody/Caption","text":"Edit Template Body"},"$:/language/ControlPanel/EditTemplateBody/Hint":{"title":"$:/language/ControlPanel/EditTemplateBody/Hint","text":"This rule cascade is used by the default edit template to dynamically choose the template for editing the body of a tiddler."},"$:/language/ControlPanel/FieldEditor/Caption":{"title":"$:/language/ControlPanel/FieldEditor/Caption","text":"Field Editor"},"$:/language/ControlPanel/FieldEditor/Hint":{"title":"$:/language/ControlPanel/FieldEditor/Hint","text":"This rules cascade is used to dynamically choose the template for rendering a tiddler field based on its name. It is used within the Edit Template."},"$:/language/ControlPanel/Info/Caption":{"title":"$:/language/ControlPanel/Info/Caption","text":"Info"},"$:/language/ControlPanel/Info/Hint":{"title":"$:/language/ControlPanel/Info/Hint","text":"Information about this TiddlyWiki"},"$:/language/ControlPanel/KeyboardShortcuts/Add/Prompt":{"title":"$:/language/ControlPanel/KeyboardShortcuts/Add/Prompt","text":"Type shortcut here"},"$:/language/ControlPanel/KeyboardShortcuts/Add/Caption":{"title":"$:/language/ControlPanel/KeyboardShortcuts/Add/Caption","text":"add shortcut"},"$:/language/ControlPanel/KeyboardShortcuts/Caption":{"title":"$:/language/ControlPanel/KeyboardShortcuts/Caption","text":"Keyboard Shortcuts"},"$:/language/ControlPanel/KeyboardShortcuts/Hint":{"title":"$:/language/ControlPanel/KeyboardShortcuts/Hint","text":"Manage keyboard shortcut assignments"},"$:/language/ControlPanel/KeyboardShortcuts/NoShortcuts/Caption":{"title":"$:/language/ControlPanel/KeyboardShortcuts/NoShortcuts/Caption","text":"No keyboard shortcuts assigned"},"$:/language/ControlPanel/KeyboardShortcuts/Remove/Hint":{"title":"$:/language/ControlPanel/KeyboardShortcuts/Remove/Hint","text":"remove keyboard shortcut"},"$:/language/ControlPanel/KeyboardShortcuts/Platform/All":{"title":"$:/language/ControlPanel/KeyboardShortcuts/Platform/All","text":"All platforms"},"$:/language/ControlPanel/KeyboardShortcuts/Platform/Mac":{"title":"$:/language/ControlPanel/KeyboardShortcuts/Platform/Mac","text":"Macintosh platform only"},"$:/language/ControlPanel/KeyboardShortcuts/Platform/NonMac":{"title":"$:/language/ControlPanel/KeyboardShortcuts/Platform/NonMac","text":"Non-Macintosh platforms only"},"$:/language/ControlPanel/KeyboardShortcuts/Platform/Linux":{"title":"$:/language/ControlPanel/KeyboardShortcuts/Platform/Linux","text":"Linux platform only"},"$:/language/ControlPanel/KeyboardShortcuts/Platform/NonLinux":{"title":"$:/language/ControlPanel/KeyboardShortcuts/Platform/NonLinux","text":"Non-Linux platforms only"},"$:/language/ControlPanel/KeyboardShortcuts/Platform/Windows":{"title":"$:/language/ControlPanel/KeyboardShortcuts/Platform/Windows","text":"Windows platform only"},"$:/language/ControlPanel/KeyboardShortcuts/Platform/NonWindows":{"title":"$:/language/ControlPanel/KeyboardShortcuts/Platform/NonWindows","text":"Non-Windows platforms only"},"$:/language/ControlPanel/LayoutSwitcher/Caption":{"title":"$:/language/ControlPanel/LayoutSwitcher/Caption","text":"Layout"},"$:/language/ControlPanel/LoadedModules/Caption":{"title":"$:/language/ControlPanel/LoadedModules/Caption","text":"Loaded Modules"},"$:/language/ControlPanel/LoadedModules/Hint":{"title":"$:/language/ControlPanel/LoadedModules/Hint","text":"These are the currently loaded tiddler modules linked to their source tiddlers. Any italicised modules lack a source tiddler, typically because they were setup during the boot process."},"$:/language/ControlPanel/Palette/Caption":{"title":"$:/language/ControlPanel/Palette/Caption","text":"Palette"},"$:/language/ControlPanel/Palette/Editor/Clone/Caption":{"title":"$:/language/ControlPanel/Palette/Editor/Clone/Caption","text":"clone"},"$:/language/ControlPanel/Palette/Editor/Clone/Prompt":{"title":"$:/language/ControlPanel/Palette/Editor/Clone/Prompt","text":"It is recommended that you clone this shadow palette before editing it"},"$:/language/ControlPanel/Palette/Editor/Delete/Hint":{"title":"$:/language/ControlPanel/Palette/Editor/Delete/Hint","text":"delete this entry from the current palette"},"$:/language/ControlPanel/Palette/Editor/Names/External/Show":{"title":"$:/language/ControlPanel/Palette/Editor/Names/External/Show","text":"Show color names that are not part of the current palette"},"$:/language/ControlPanel/Palette/Editor/Prompt/Modified":{"title":"$:/language/ControlPanel/Palette/Editor/Prompt/Modified","text":"This shadow palette has been modified"},"$:/language/ControlPanel/Palette/Editor/Prompt":{"title":"$:/language/ControlPanel/Palette/Editor/Prompt","text":"Editing"},"$:/language/ControlPanel/Palette/Editor/Reset/Caption":{"title":"$:/language/ControlPanel/Palette/Editor/Reset/Caption","text":"reset"},"$:/language/ControlPanel/Palette/HideEditor/Caption":{"title":"$:/language/ControlPanel/Palette/HideEditor/Caption","text":"hide editor"},"$:/language/ControlPanel/Palette/Prompt":{"title":"$:/language/ControlPanel/Palette/Prompt","text":"Current palette:"},"$:/language/ControlPanel/Palette/ShowEditor/Caption":{"title":"$:/language/ControlPanel/Palette/ShowEditor/Caption","text":"show editor"},"$:/language/ControlPanel/Parsing/Caption":{"title":"$:/language/ControlPanel/Parsing/Caption","text":"Parsing"},"$:/language/ControlPanel/Parsing/Hint":{"title":"$:/language/ControlPanel/Parsing/Hint","text":"Here you can globally disable/enable wiki parser rules. For changes to take effect, save and reload your wiki. Disabling certain parser rules can prevent <$text text=\"TiddlyWiki\"/> from functioning correctly. Use [[safe mode|https://tiddlywiki.com/#SafeMode]] to restore normal operation."},"$:/language/ControlPanel/Parsing/Block/Caption":{"title":"$:/language/ControlPanel/Parsing/Block/Caption","text":"Block Parse Rules"},"$:/language/ControlPanel/Parsing/Inline/Caption":{"title":"$:/language/ControlPanel/Parsing/Inline/Caption","text":"Inline Parse Rules"},"$:/language/ControlPanel/Parsing/Pragma/Caption":{"title":"$:/language/ControlPanel/Parsing/Pragma/Caption","text":"Pragma Parse Rules"},"$:/language/ControlPanel/Plugins/Add/Caption":{"title":"$:/language/ControlPanel/Plugins/Add/Caption","text":"Get more plugins"},"$:/language/ControlPanel/Plugins/Add/Hint":{"title":"$:/language/ControlPanel/Plugins/Add/Hint","text":"Install plugins from the official library"},"$:/language/ControlPanel/Plugins/AlreadyInstalled/Hint":{"title":"$:/language/ControlPanel/Plugins/AlreadyInstalled/Hint","text":"This plugin is already installed at version <$text text=<<installedVersion>>/>"},"$:/language/ControlPanel/Plugins/AlsoRequires":{"title":"$:/language/ControlPanel/Plugins/AlsoRequires","text":"Also requires:"},"$:/language/ControlPanel/Plugins/Caption":{"title":"$:/language/ControlPanel/Plugins/Caption","text":"Plugins"},"$:/language/ControlPanel/Plugins/Disable/Caption":{"title":"$:/language/ControlPanel/Plugins/Disable/Caption","text":"disable"},"$:/language/ControlPanel/Plugins/Disable/Hint":{"title":"$:/language/ControlPanel/Plugins/Disable/Hint","text":"Disable this plugin when reloading page"},"$:/language/ControlPanel/Plugins/Disabled/Status":{"title":"$:/language/ControlPanel/Plugins/Disabled/Status","text":"(disabled)"},"$:/language/ControlPanel/Plugins/Downgrade/Caption":{"title":"$:/language/ControlPanel/Plugins/Downgrade/Caption","text":"downgrade"},"$:/language/ControlPanel/Plugins/Empty/Hint":{"title":"$:/language/ControlPanel/Plugins/Empty/Hint","text":"None"},"$:/language/ControlPanel/Plugins/Enable/Caption":{"title":"$:/language/ControlPanel/Plugins/Enable/Caption","text":"enable"},"$:/language/ControlPanel/Plugins/Enable/Hint":{"title":"$:/language/ControlPanel/Plugins/Enable/Hint","text":"Enable this plugin when reloading page"},"$:/language/ControlPanel/Plugins/Install/Caption":{"title":"$:/language/ControlPanel/Plugins/Install/Caption","text":"install"},"$:/language/ControlPanel/Plugins/Installed/Hint":{"title":"$:/language/ControlPanel/Plugins/Installed/Hint","text":"Currently installed plugins:"},"$:/language/ControlPanel/Plugins/Languages/Caption":{"title":"$:/language/ControlPanel/Plugins/Languages/Caption","text":"Languages"},"$:/language/ControlPanel/Plugins/Languages/Hint":{"title":"$:/language/ControlPanel/Plugins/Languages/Hint","text":"Language pack plugins"},"$:/language/ControlPanel/Plugins/NoInfoFound/Hint":{"title":"$:/language/ControlPanel/Plugins/NoInfoFound/Hint","text":"No ''\"<$text text=<<currentTab>>/>\"'' found"},"$:/language/ControlPanel/Plugins/NotInstalled/Hint":{"title":"$:/language/ControlPanel/Plugins/NotInstalled/Hint","text":"This plugin is not currently installed"},"$:/language/ControlPanel/Plugins/OpenPluginLibrary":{"title":"$:/language/ControlPanel/Plugins/OpenPluginLibrary","text":"Open plugin library"},"$:/language/ControlPanel/Plugins/ClosePluginLibrary":{"title":"$:/language/ControlPanel/Plugins/ClosePluginLibrary","text":"Close plugin library"},"$:/language/ControlPanel/Plugins/PluginWillRequireReload":{"title":"$:/language/ControlPanel/Plugins/PluginWillRequireReload","text":"(requires reload)"},"$:/language/ControlPanel/Plugins/Plugins/Caption":{"title":"$:/language/ControlPanel/Plugins/Plugins/Caption","text":"Plugins"},"$:/language/ControlPanel/Plugins/Plugins/Hint":{"title":"$:/language/ControlPanel/Plugins/Plugins/Hint","text":"Plugins"},"$:/language/ControlPanel/Plugins/Reinstall/Caption":{"title":"$:/language/ControlPanel/Plugins/Reinstall/Caption","text":"reinstall"},"$:/language/ControlPanel/Plugins/Stability/Deprecated":{"title":"$:/language/ControlPanel/Plugins/Stability/Deprecated","text":"DEPRECATED"},"$:/language/ControlPanel/Plugins/Stability/Experimental":{"title":"$:/language/ControlPanel/Plugins/Stability/Experimental","text":"EXPERIMENTAL"},"$:/language/ControlPanel/Plugins/Stability/Legacy":{"title":"$:/language/ControlPanel/Plugins/Stability/Legacy","text":"LEGACY"},"$:/language/ControlPanel/Plugins/Stability/Stable":{"title":"$:/language/ControlPanel/Plugins/Stability/Stable","text":"STABLE"},"$:/language/ControlPanel/Plugins/Themes/Caption":{"title":"$:/language/ControlPanel/Plugins/Themes/Caption","text":"Themes"},"$:/language/ControlPanel/Plugins/Themes/Hint":{"title":"$:/language/ControlPanel/Plugins/Themes/Hint","text":"Theme plugins"},"$:/language/ControlPanel/Plugins/Update/Caption":{"title":"$:/language/ControlPanel/Plugins/Update/Caption","text":"update"},"$:/language/ControlPanel/Plugins/Updates/Caption":{"title":"$:/language/ControlPanel/Plugins/Updates/Caption","text":"Updates"},"$:/language/ControlPanel/Plugins/Updates/Hint":{"title":"$:/language/ControlPanel/Plugins/Updates/Hint","text":"Available updates to installed plugins"},"$:/language/ControlPanel/Plugins/Updates/UpdateAll/Caption":{"title":"$:/language/ControlPanel/Plugins/Updates/UpdateAll/Caption","text":"Update <<update-count>> plugins"},"$:/language/ControlPanel/Plugins/SubPluginPrompt":{"title":"$:/language/ControlPanel/Plugins/SubPluginPrompt","text":"With <<count>> sub-plugins available"},"$:/language/ControlPanel/Saving/Caption":{"title":"$:/language/ControlPanel/Saving/Caption","text":"Saving"},"$:/language/ControlPanel/Saving/DownloadSaver/AutoSave/Description":{"title":"$:/language/ControlPanel/Saving/DownloadSaver/AutoSave/Description","text":"Permit automatic saving for the download saver"},"$:/language/ControlPanel/Saving/DownloadSaver/AutoSave/Hint":{"title":"$:/language/ControlPanel/Saving/DownloadSaver/AutoSave/Hint","text":"Enable Autosave for Download Saver"},"$:/language/ControlPanel/Saving/DownloadSaver/Caption":{"title":"$:/language/ControlPanel/Saving/DownloadSaver/Caption","text":"Download Saver"},"$:/language/ControlPanel/Saving/DownloadSaver/Hint":{"title":"$:/language/ControlPanel/Saving/DownloadSaver/Hint","text":"These settings apply to the HTML5-compatible download saver"},"$:/language/ControlPanel/Saving/General/Caption":{"title":"$:/language/ControlPanel/Saving/General/Caption","text":"General"},"$:/language/ControlPanel/Saving/General/Hint":{"title":"$:/language/ControlPanel/Saving/General/Hint","text":"These settings apply to all the loaded savers"},"$:/language/ControlPanel/Saving/Hint":{"title":"$:/language/ControlPanel/Saving/Hint","text":"Settings used for saving the entire TiddlyWiki as a single file via a saver module"},"$:/language/ControlPanel/Saving/GitService/Branch":{"title":"$:/language/ControlPanel/Saving/GitService/Branch","text":"Target branch for saving"},"$:/language/ControlPanel/Saving/GitService/CommitMessage":{"title":"$:/language/ControlPanel/Saving/GitService/CommitMessage","text":"Saved by TiddlyWiki"},"$:/language/ControlPanel/Saving/GitService/Description":{"title":"$:/language/ControlPanel/Saving/GitService/Description","text":"These settings are only used when saving to <<service-name>>"},"$:/language/ControlPanel/Saving/GitService/Filename":{"title":"$:/language/ControlPanel/Saving/GitService/Filename","text":"Filename of target file (e.g. `index.html`)"},"$:/language/ControlPanel/Saving/GitService/Path":{"title":"$:/language/ControlPanel/Saving/GitService/Path","text":"Path to target file (e.g. `/wiki/`)"},"$:/language/ControlPanel/Saving/GitService/Repo":{"title":"$:/language/ControlPanel/Saving/GitService/Repo","text":"Target repository (e.g. `Jermolene/TiddlyWiki5`)"},"$:/language/ControlPanel/Saving/GitService/ServerURL":{"title":"$:/language/ControlPanel/Saving/GitService/ServerURL","text":"Server API URL"},"$:/language/ControlPanel/Saving/GitService/UserName":{"title":"$:/language/ControlPanel/Saving/GitService/UserName","text":"Username"},"$:/language/ControlPanel/Saving/GitService/GitHub/Caption":{"title":"$:/language/ControlPanel/Saving/GitService/GitHub/Caption","text":"~GitHub Saver"},"$:/language/ControlPanel/Saving/GitService/GitHub/Password":{"title":"$:/language/ControlPanel/Saving/GitService/GitHub/Password","text":"Password, OAUTH token, or personal access token (see [[GitHub help page|https://help.github.com/en/articles/creating-a-personal-access-token-for-the-command-line]] for details)"},"$:/language/ControlPanel/Saving/GitService/GitLab/Caption":{"title":"$:/language/ControlPanel/Saving/GitService/GitLab/Caption","text":"~GitLab Saver"},"$:/language/ControlPanel/Saving/GitService/GitLab/Password":{"title":"$:/language/ControlPanel/Saving/GitService/GitLab/Password","text":"Personal access token for API (see [[GitLab help page|https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html]] for details)"},"$:/language/ControlPanel/Saving/GitService/Gitea/Caption":{"title":"$:/language/ControlPanel/Saving/GitService/Gitea/Caption","text":"Gitea Saver"},"$:/language/ControlPanel/Saving/GitService/Gitea/Password":{"title":"$:/language/ControlPanel/Saving/GitService/Gitea/Password","text":"Personal access token for API (via Gitea’s web interface: `Settings | Applications | Generate New Token`)"},"$:/language/ControlPanel/Saving/TiddlySpot/Advanced/Heading":{"title":"$:/language/ControlPanel/Saving/TiddlySpot/Advanced/Heading","text":"Advanced Settings"},"$:/language/ControlPanel/Saving/TiddlySpot/BackupDir":{"title":"$:/language/ControlPanel/Saving/TiddlySpot/BackupDir","text":"Backup Directory"},"$:/language/ControlPanel/Saving/TiddlySpot/ControlPanel":{"title":"$:/language/ControlPanel/Saving/TiddlySpot/ControlPanel","text":"~TiddlySpot Control Panel"},"$:/language/ControlPanel/Saving/TiddlySpot/Backups":{"title":"$:/language/ControlPanel/Saving/TiddlySpot/Backups","text":"Backups"},"$:/language/ControlPanel/Saving/TiddlySpot/Caption":{"title":"$:/language/ControlPanel/Saving/TiddlySpot/Caption","text":"~TiddlySpot Saver"},"$:/language/ControlPanel/Saving/TiddlySpot/Description":{"title":"$:/language/ControlPanel/Saving/TiddlySpot/Description","text":"These settings are only used when saving to [[TiddlySpot|http://tiddlyspot.com]], [[TiddlyHost|https://tiddlyhost.com]], or a compatible remote server. See [[here|https://github.com/simonbaird/tiddlyhost/wiki/TiddlySpot-Saver-configuration-for-Tiddlyhost-and-Tiddlyspot]] for information on ~TiddlySpot and ~TiddlyHost saving configuration."},"$:/language/ControlPanel/Saving/TiddlySpot/Filename":{"title":"$:/language/ControlPanel/Saving/TiddlySpot/Filename","text":"Upload Filename"},"$:/language/ControlPanel/Saving/TiddlySpot/Heading":{"title":"$:/language/ControlPanel/Saving/TiddlySpot/Heading","text":"~TiddlySpot"},"$:/language/ControlPanel/Saving/TiddlySpot/Hint":{"title":"$:/language/ControlPanel/Saving/TiddlySpot/Hint","text":"//The server URL defaults to `http://<wikiname>.tiddlyspot.com/store.cgi` and can be changed to use a custom server address, e.g. `http://example.com/store.php`.//"},"$:/language/ControlPanel/Saving/TiddlySpot/Password":{"title":"$:/language/ControlPanel/Saving/TiddlySpot/Password","text":"Password"},"$:/language/ControlPanel/Saving/TiddlySpot/ReadOnly":{"title":"$:/language/ControlPanel/Saving/TiddlySpot/ReadOnly","text":"Note that [[TiddlySpot|http://tiddlyspot.com]] no longer allows the creation of new sites. For new sites, you can use [[TiddlyHost|https://tiddlyhost.com]], a new hosting service that replaces ~TiddlySpot."},"$:/language/ControlPanel/Saving/TiddlySpot/ServerURL":{"title":"$:/language/ControlPanel/Saving/TiddlySpot/ServerURL","text":"Server URL"},"$:/language/ControlPanel/Saving/TiddlySpot/UploadDir":{"title":"$:/language/ControlPanel/Saving/TiddlySpot/UploadDir","text":"Upload Directory"},"$:/language/ControlPanel/Saving/TiddlySpot/UserName":{"title":"$:/language/ControlPanel/Saving/TiddlySpot/UserName","text":"Wiki Name"},"$:/language/ControlPanel/Settings/AutoSave/Caption":{"title":"$:/language/ControlPanel/Settings/AutoSave/Caption","text":"Autosave"},"$:/language/ControlPanel/Settings/AutoSave/Disabled/Description":{"title":"$:/language/ControlPanel/Settings/AutoSave/Disabled/Description","text":"Do not save changes automatically"},"$:/language/ControlPanel/Settings/AutoSave/Enabled/Description":{"title":"$:/language/ControlPanel/Settings/AutoSave/Enabled/Description","text":"Save changes automatically"},"$:/language/ControlPanel/Settings/AutoSave/Hint":{"title":"$:/language/ControlPanel/Settings/AutoSave/Hint","text":"Attempt to automatically save changes during editing when using a supporting saver"},"$:/language/ControlPanel/Settings/CamelCase/Caption":{"title":"$:/language/ControlPanel/Settings/CamelCase/Caption","text":"Camel Case Wiki Links"},"$:/language/ControlPanel/Settings/CamelCase/Hint":{"title":"$:/language/ControlPanel/Settings/CamelCase/Hint","text":"You can globally disable automatic linking of ~CamelCase phrases. Requires reload to take effect"},"$:/language/ControlPanel/Settings/CamelCase/Description":{"title":"$:/language/ControlPanel/Settings/CamelCase/Description","text":"Enable automatic ~CamelCase linking"},"$:/language/ControlPanel/Settings/Caption":{"title":"$:/language/ControlPanel/Settings/Caption","text":"Settings"},"$:/language/ControlPanel/Settings/EditorToolbar/Caption":{"title":"$:/language/ControlPanel/Settings/EditorToolbar/Caption","text":"Editor Toolbar"},"$:/language/ControlPanel/Settings/EditorToolbar/Hint":{"title":"$:/language/ControlPanel/Settings/EditorToolbar/Hint","text":"Enable or disable the editor toolbar:"},"$:/language/ControlPanel/Settings/EditorToolbar/Description":{"title":"$:/language/ControlPanel/Settings/EditorToolbar/Description","text":"Show editor toolbar"},"$:/language/ControlPanel/Settings/InfoPanelMode/Caption":{"title":"$:/language/ControlPanel/Settings/InfoPanelMode/Caption","text":"Tiddler Info Panel Mode"},"$:/language/ControlPanel/Settings/InfoPanelMode/Hint":{"title":"$:/language/ControlPanel/Settings/InfoPanelMode/Hint","text":"Control when the tiddler info panel closes:"},"$:/language/ControlPanel/Settings/InfoPanelMode/Popup/Description":{"title":"$:/language/ControlPanel/Settings/InfoPanelMode/Popup/Description","text":"Tiddler info panel closes automatically"},"$:/language/ControlPanel/Settings/InfoPanelMode/Sticky/Description":{"title":"$:/language/ControlPanel/Settings/InfoPanelMode/Sticky/Description","text":"Tiddler info panel stays open until explicitly closed"},"$:/language/ControlPanel/Settings/Hint":{"title":"$:/language/ControlPanel/Settings/Hint","text":"These settings let you customise the behaviour of TiddlyWiki."},"$:/language/ControlPanel/Settings/NavigationAddressBar/Caption":{"title":"$:/language/ControlPanel/Settings/NavigationAddressBar/Caption","text":"Navigation Address Bar"},"$:/language/ControlPanel/Settings/NavigationAddressBar/Hint":{"title":"$:/language/ControlPanel/Settings/NavigationAddressBar/Hint","text":"Behaviour of the browser address bar when navigating to a tiddler:"},"$:/language/ControlPanel/Settings/NavigationAddressBar/No/Description":{"title":"$:/language/ControlPanel/Settings/NavigationAddressBar/No/Description","text":"Do not update the address bar"},"$:/language/ControlPanel/Settings/NavigationAddressBar/Permalink/Description":{"title":"$:/language/ControlPanel/Settings/NavigationAddressBar/Permalink/Description","text":"Include the target tiddler"},"$:/language/ControlPanel/Settings/NavigationAddressBar/Permaview/Description":{"title":"$:/language/ControlPanel/Settings/NavigationAddressBar/Permaview/Description","text":"Include the target tiddler and the current story sequence"},"$:/language/ControlPanel/Settings/NavigationHistory/Caption":{"title":"$:/language/ControlPanel/Settings/NavigationHistory/Caption","text":"Navigation History"},"$:/language/ControlPanel/Settings/NavigationHistory/Hint":{"title":"$:/language/ControlPanel/Settings/NavigationHistory/Hint","text":"Update browser history when navigating to a tiddler:"},"$:/language/ControlPanel/Settings/NavigationHistory/No/Description":{"title":"$:/language/ControlPanel/Settings/NavigationHistory/No/Description","text":"Do not update history"},"$:/language/ControlPanel/Settings/NavigationHistory/Yes/Description":{"title":"$:/language/ControlPanel/Settings/NavigationHistory/Yes/Description","text":"Update history"},"$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/Caption":{"title":"$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/Caption","text":"Permalink/permaview Mode"},"$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/Hint":{"title":"$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/Hint","text":"Choose how permalink/permaview is handled:"},"$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/CopyToClipboard/Description":{"title":"$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/CopyToClipboard/Description","text":"Copy permalink/permaview URL to clipboard"},"$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/UpdateAddressBar/Description":{"title":"$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/UpdateAddressBar/Description","text":"Update address bar with permalink/permaview URL"},"$:/language/ControlPanel/Settings/PerformanceInstrumentation/Caption":{"title":"$:/language/ControlPanel/Settings/PerformanceInstrumentation/Caption","text":"Performance Instrumentation"},"$:/language/ControlPanel/Settings/PerformanceInstrumentation/Hint":{"title":"$:/language/ControlPanel/Settings/PerformanceInstrumentation/Hint","text":"Displays performance statistics in the browser developer console. Requires reload to take effect"},"$:/language/ControlPanel/Settings/PerformanceInstrumentation/Description":{"title":"$:/language/ControlPanel/Settings/PerformanceInstrumentation/Description","text":"Enable performance instrumentation"},"$:/language/ControlPanel/Settings/RecentLimit/Caption":{"title":"$:/language/ControlPanel/Settings/RecentLimit/Caption","text":"Recent Tab Limit"},"$:/language/ControlPanel/Settings/RecentLimit/Hint":{"title":"$:/language/ControlPanel/Settings/RecentLimit/Hint","text":"Maximum number of tiddlers to be displayed under the sidebar \"Recent\" tab"},"$:/language/ControlPanel/Settings/ToolbarButtonStyle/Caption":{"title":"$:/language/ControlPanel/Settings/ToolbarButtonStyle/Caption","text":"Toolbar Button Style"},"$:/language/ControlPanel/Settings/ToolbarButtonStyle/Hint":{"title":"$:/language/ControlPanel/Settings/ToolbarButtonStyle/Hint","text":"Choose the style for toolbar buttons:"},"$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Borderless":{"title":"$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Borderless","text":"Borderless"},"$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Boxed":{"title":"$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Boxed","text":"Boxed"},"$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Rounded":{"title":"$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Rounded","text":"Rounded"},"$:/language/ControlPanel/Settings/ToolbarButtons/Caption":{"title":"$:/language/ControlPanel/Settings/ToolbarButtons/Caption","text":"Toolbar Buttons"},"$:/language/ControlPanel/Settings/ToolbarButtons/Hint":{"title":"$:/language/ControlPanel/Settings/ToolbarButtons/Hint","text":"Default toolbar button appearance:"},"$:/language/ControlPanel/Settings/ToolbarButtons/Icons/Description":{"title":"$:/language/ControlPanel/Settings/ToolbarButtons/Icons/Description","text":"Include icon"},"$:/language/ControlPanel/Settings/ToolbarButtons/Text/Description":{"title":"$:/language/ControlPanel/Settings/ToolbarButtons/Text/Description","text":"Include text"},"$:/language/ControlPanel/Settings/DefaultSidebarTab/Caption":{"title":"$:/language/ControlPanel/Settings/DefaultSidebarTab/Caption","text":"Default Sidebar Tab"},"$:/language/ControlPanel/Settings/DefaultSidebarTab/Hint":{"title":"$:/language/ControlPanel/Settings/DefaultSidebarTab/Hint","text":"Specify which sidebar tab is displayed by default"},"$:/language/ControlPanel/Settings/DefaultMoreSidebarTab/Caption":{"title":"$:/language/ControlPanel/Settings/DefaultMoreSidebarTab/Caption","text":"Default More Sidebar Tab"},"$:/language/ControlPanel/Settings/DefaultMoreSidebarTab/Hint":{"title":"$:/language/ControlPanel/Settings/DefaultMoreSidebarTab/Hint","text":"Specify which More sidebar tab is displayed by default"},"$:/language/ControlPanel/Settings/LinkToBehaviour/Caption":{"title":"$:/language/ControlPanel/Settings/LinkToBehaviour/Caption","text":"Tiddler Opening Behaviour"},"$:/language/ControlPanel/Settings/LinkToBehaviour/InsideRiver/Hint":{"title":"$:/language/ControlPanel/Settings/LinkToBehaviour/InsideRiver/Hint","text":"Navigation from //within// the story river"},"$:/language/ControlPanel/Settings/LinkToBehaviour/OutsideRiver/Hint":{"title":"$:/language/ControlPanel/Settings/LinkToBehaviour/OutsideRiver/Hint","text":"Navigation from //outside// the story river"},"$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAbove":{"title":"$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAbove","text":"Open above the current tiddler"},"$:/language/ControlPanel/Settings/LinkToBehaviour/OpenBelow":{"title":"$:/language/ControlPanel/Settings/LinkToBehaviour/OpenBelow","text":"Open below the current tiddler"},"$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAtTop":{"title":"$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAtTop","text":"Open at the top of the story river"},"$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAtBottom":{"title":"$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAtBottom","text":"Open at the bottom of the story river"},"$:/language/ControlPanel/Settings/TitleLinks/Caption":{"title":"$:/language/ControlPanel/Settings/TitleLinks/Caption","text":"Tiddler Titles"},"$:/language/ControlPanel/Settings/TitleLinks/Hint":{"title":"$:/language/ControlPanel/Settings/TitleLinks/Hint","text":"Optionally display tiddler titles as links"},"$:/language/ControlPanel/Settings/TitleLinks/No/Description":{"title":"$:/language/ControlPanel/Settings/TitleLinks/No/Description","text":"Do not display tiddler titles as links"},"$:/language/ControlPanel/Settings/TitleLinks/Yes/Description":{"title":"$:/language/ControlPanel/Settings/TitleLinks/Yes/Description","text":"Display tiddler titles as links"},"$:/language/ControlPanel/Settings/MissingLinks/Caption":{"title":"$:/language/ControlPanel/Settings/MissingLinks/Caption","text":"Wiki Links"},"$:/language/ControlPanel/Settings/MissingLinks/Hint":{"title":"$:/language/ControlPanel/Settings/MissingLinks/Hint","text":"Choose whether to link to tiddlers that do not exist yet"},"$:/language/ControlPanel/Settings/MissingLinks/Description":{"title":"$:/language/ControlPanel/Settings/MissingLinks/Description","text":"Enable links to missing tiddlers"},"$:/language/ControlPanel/SocialCard/Caption":{"title":"$:/language/ControlPanel/SocialCard/Caption","text":"Social Media Card"},"$:/language/ControlPanel/SocialCard/Domain/Prompt":{"title":"$:/language/ControlPanel/SocialCard/Domain/Prompt","text":"Domain name to display for the link (for example, ''tiddlywiki.com'')"},"$:/language/ControlPanel/SocialCard/Hint":{"title":"$:/language/ControlPanel/SocialCard/Hint","text":"This information is used by social and messaging services to display a preview card for links to this TiddlyWiki when hosted online"},"$:/language/ControlPanel/SocialCard/PreviewUrl/Prompt":{"title":"$:/language/ControlPanel/SocialCard/PreviewUrl/Prompt","text":"Full URL to preview image for this TiddlyWiki"},"$:/language/ControlPanel/SocialCard/PreviewUrl/Preview":{"title":"$:/language/ControlPanel/SocialCard/PreviewUrl/Preview","text":"Preview image:"},"$:/language/ControlPanel/SocialCard/Url/Prompt":{"title":"$:/language/ControlPanel/SocialCard/Url/Prompt","text":"Full URL of this TiddlyWiki"},"$:/language/ControlPanel/StoryTiddler/Caption":{"title":"$:/language/ControlPanel/StoryTiddler/Caption","text":"Story Tiddler"},"$:/language/ControlPanel/StoryTiddler/Hint":{"title":"$:/language/ControlPanel/StoryTiddler/Hint","text":"This rule cascade is used to dynamically choose the template for displaying a tiddler in the story river."},"$:/language/ControlPanel/StoryView/Caption":{"title":"$:/language/ControlPanel/StoryView/Caption","text":"Story View"},"$:/language/ControlPanel/StoryView/Prompt":{"title":"$:/language/ControlPanel/StoryView/Prompt","text":"Current view:"},"$:/language/ControlPanel/Stylesheets/Caption":{"title":"$:/language/ControlPanel/Stylesheets/Caption","text":"Stylesheets"},"$:/language/ControlPanel/Stylesheets/Expand/Caption":{"title":"$:/language/ControlPanel/Stylesheets/Expand/Caption","text":"Expand All"},"$:/language/ControlPanel/Stylesheets/Hint":{"title":"$:/language/ControlPanel/Stylesheets/Hint","text":"This is the rendered CSS of the current stylesheet tiddlers tagged with <<tag \"$:/tags/Stylesheet\">>"},"$:/language/ControlPanel/Stylesheets/Restore/Caption":{"title":"$:/language/ControlPanel/Stylesheets/Restore/Caption","text":"Restore"},"$:/language/ControlPanel/TestCases/Caption":{"title":"$:/language/ControlPanel/TestCases/Caption","text":"Test Cases"},"$:/language/ControlPanel/TestCases/Hint":{"title":"$:/language/ControlPanel/TestCases/Hint","text":"Test cases are self contained examples for testing and learning"},"$:/language/ControlPanel/TestCases/All/Caption":{"title":"$:/language/ControlPanel/TestCases/All/Caption","text":"All Test Cases"},"$:/language/ControlPanel/TestCases/All/Hint":{"title":"$:/language/ControlPanel/TestCases/All/Hint","text":"All Test Cases"},"$:/language/ControlPanel/TestCases/Failed/Caption":{"title":"$:/language/ControlPanel/TestCases/Failed/Caption","text":"Failed Test Cases"},"$:/language/ControlPanel/TestCases/Failed/Hint":{"title":"$:/language/ControlPanel/TestCases/Failed/Hint","text":"Only Failed Test Cases"},"$:/language/ControlPanel/Theme/Caption":{"title":"$:/language/ControlPanel/Theme/Caption","text":"Theme"},"$:/language/ControlPanel/Theme/Prompt":{"title":"$:/language/ControlPanel/Theme/Prompt","text":"Current theme:"},"$:/language/ControlPanel/TiddlerFields/Caption":{"title":"$:/language/ControlPanel/TiddlerFields/Caption","text":"Tiddler Fields"},"$:/language/ControlPanel/TiddlerFields/Hint":{"title":"$:/language/ControlPanel/TiddlerFields/Hint","text":"This is the full set of TiddlerFields in use in this wiki (including system tiddlers but excluding shadow tiddlers)."},"$:/language/ControlPanel/TiddlerColour/Caption":{"title":"$:/language/ControlPanel/TiddlerColour/Caption","text":"Tiddler Colour"},"$:/language/ControlPanel/TiddlerColour/Hint":{"title":"$:/language/ControlPanel/TiddlerColour/Hint","text":"This rules cascade is used to dynamically choose the colour for a tiddler (used for the icon and the associated tag pill)."},"$:/language/ControlPanel/TiddlerIcon/Caption":{"title":"$:/language/ControlPanel/TiddlerIcon/Caption","text":"Tiddler Icon"},"$:/language/ControlPanel/TiddlerIcon/Hint":{"title":"$:/language/ControlPanel/TiddlerIcon/Hint","text":"This rules cascade is used to dynamically choose the icon for a tiddler."},"$:/language/ControlPanel/Toolbars/Caption":{"title":"$:/language/ControlPanel/Toolbars/Caption","text":"Toolbars"},"$:/language/ControlPanel/Toolbars/EditToolbar/Caption":{"title":"$:/language/ControlPanel/Toolbars/EditToolbar/Caption","text":"Edit Toolbar"},"$:/language/ControlPanel/Toolbars/EditToolbar/Hint":{"title":"$:/language/ControlPanel/Toolbars/EditToolbar/Hint","text":"Choose which buttons are displayed for tiddlers in edit mode. Drag and drop to change the ordering"},"$:/language/ControlPanel/Toolbars/Hint":{"title":"$:/language/ControlPanel/Toolbars/Hint","text":"Select which toolbar buttons are displayed"},"$:/language/ControlPanel/Toolbars/PageControls/Caption":{"title":"$:/language/ControlPanel/Toolbars/PageControls/Caption","text":"Page Toolbar"},"$:/language/ControlPanel/Toolbars/PageControls/Hint":{"title":"$:/language/ControlPanel/Toolbars/PageControls/Hint","text":"Choose which buttons are displayed on the main page toolbar. Drag and drop to change the ordering"},"$:/language/ControlPanel/Toolbars/EditorToolbar/Caption":{"title":"$:/language/ControlPanel/Toolbars/EditorToolbar/Caption","text":"Editor Toolbar"},"$:/language/ControlPanel/Toolbars/EditorToolbar/Hint":{"title":"$:/language/ControlPanel/Toolbars/EditorToolbar/Hint","text":"Choose which buttons are displayed in the editor toolbar. Note that some buttons will only appear when editing tiddlers of a certain type. Drag and drop to change the ordering"},"$:/language/ControlPanel/Toolbars/ViewToolbar/Caption":{"title":"$:/language/ControlPanel/Toolbars/ViewToolbar/Caption","text":"View Toolbar"},"$:/language/ControlPanel/Toolbars/ViewToolbar/Hint":{"title":"$:/language/ControlPanel/Toolbars/ViewToolbar/Hint","text":"Choose which buttons are displayed for tiddlers in view mode. Drag and drop to change the ordering"},"$:/language/ControlPanel/Tools/Download/Full/Caption":{"title":"$:/language/ControlPanel/Tools/Download/Full/Caption","text":"Download full wiki"},"$:/language/ControlPanel/ViewTemplateBody/Caption":{"title":"$:/language/ControlPanel/ViewTemplateBody/Caption","text":"View Template Body"},"$:/language/ControlPanel/ViewTemplateBody/Hint":{"title":"$:/language/ControlPanel/ViewTemplateBody/Hint","text":"This rule cascade is used by the default view template to dynamically choose the template for displaying the body of a tiddler."},"$:/language/ControlPanel/ViewTemplateTitle/Caption":{"title":"$:/language/ControlPanel/ViewTemplateTitle/Caption","text":"View Template Title"},"$:/language/ControlPanel/ViewTemplateTitle/Hint":{"title":"$:/language/ControlPanel/ViewTemplateTitle/Hint","text":"This rule cascade is used by the default view template to dynamically choose the template for displaying the title of a tiddler."},"$:/language/ControlPanel/ViewTemplateSubtitle/Caption":{"title":"$:/language/ControlPanel/ViewTemplateSubtitle/Caption","text":"View Template Subtitle"},"$:/language/ControlPanel/ViewTemplateSubtitle/Hint":{"title":"$:/language/ControlPanel/ViewTemplateSubtitle/Hint","text":"This rule cascade is used by the default view template to dynamically choose the template for displaying the subtitle of a tiddler."},"$:/language/ControlPanel/ViewTemplateTags/Caption":{"title":"$:/language/ControlPanel/ViewTemplateTags/Caption","text":"View Template Tags"},"$:/language/ControlPanel/ViewTemplateTags/Hint":{"title":"$:/language/ControlPanel/ViewTemplateTags/Hint","text":"This rule cascade is used by the default view template to dynamically choose the template for displaying the tags area of a tiddler."},"$:/language/Date/DaySuffix/1":{"title":"$:/language/Date/DaySuffix/1","text":"st"},"$:/language/Date/DaySuffix/2":{"title":"$:/language/Date/DaySuffix/2","text":"nd"},"$:/language/Date/DaySuffix/3":{"title":"$:/language/Date/DaySuffix/3","text":"rd"},"$:/language/Date/DaySuffix/4":{"title":"$:/language/Date/DaySuffix/4","text":"th"},"$:/language/Date/DaySuffix/5":{"title":"$:/language/Date/DaySuffix/5","text":"th"},"$:/language/Date/DaySuffix/6":{"title":"$:/language/Date/DaySuffix/6","text":"th"},"$:/language/Date/DaySuffix/7":{"title":"$:/language/Date/DaySuffix/7","text":"th"},"$:/language/Date/DaySuffix/8":{"title":"$:/language/Date/DaySuffix/8","text":"th"},"$:/language/Date/DaySuffix/9":{"title":"$:/language/Date/DaySuffix/9","text":"th"},"$:/language/Date/DaySuffix/10":{"title":"$:/language/Date/DaySuffix/10","text":"th"},"$:/language/Date/DaySuffix/11":{"title":"$:/language/Date/DaySuffix/11","text":"th"},"$:/language/Date/DaySuffix/12":{"title":"$:/language/Date/DaySuffix/12","text":"th"},"$:/language/Date/DaySuffix/13":{"title":"$:/language/Date/DaySuffix/13","text":"th"},"$:/language/Date/DaySuffix/14":{"title":"$:/language/Date/DaySuffix/14","text":"th"},"$:/language/Date/DaySuffix/15":{"title":"$:/language/Date/DaySuffix/15","text":"th"},"$:/language/Date/DaySuffix/16":{"title":"$:/language/Date/DaySuffix/16","text":"th"},"$:/language/Date/DaySuffix/17":{"title":"$:/language/Date/DaySuffix/17","text":"th"},"$:/language/Date/DaySuffix/18":{"title":"$:/language/Date/DaySuffix/18","text":"th"},"$:/language/Date/DaySuffix/19":{"title":"$:/language/Date/DaySuffix/19","text":"th"},"$:/language/Date/DaySuffix/20":{"title":"$:/language/Date/DaySuffix/20","text":"th"},"$:/language/Date/DaySuffix/21":{"title":"$:/language/Date/DaySuffix/21","text":"st"},"$:/language/Date/DaySuffix/22":{"title":"$:/language/Date/DaySuffix/22","text":"nd"},"$:/language/Date/DaySuffix/23":{"title":"$:/language/Date/DaySuffix/23","text":"rd"},"$:/language/Date/DaySuffix/24":{"title":"$:/language/Date/DaySuffix/24","text":"th"},"$:/language/Date/DaySuffix/25":{"title":"$:/language/Date/DaySuffix/25","text":"th"},"$:/language/Date/DaySuffix/26":{"title":"$:/language/Date/DaySuffix/26","text":"th"},"$:/language/Date/DaySuffix/27":{"title":"$:/language/Date/DaySuffix/27","text":"th"},"$:/language/Date/DaySuffix/28":{"title":"$:/language/Date/DaySuffix/28","text":"th"},"$:/language/Date/DaySuffix/29":{"title":"$:/language/Date/DaySuffix/29","text":"th"},"$:/language/Date/DaySuffix/30":{"title":"$:/language/Date/DaySuffix/30","text":"th"},"$:/language/Date/DaySuffix/31":{"title":"$:/language/Date/DaySuffix/31","text":"st"},"$:/language/Date/Long/Day/0":{"title":"$:/language/Date/Long/Day/0","text":"Sunday"},"$:/language/Date/Long/Day/1":{"title":"$:/language/Date/Long/Day/1","text":"Monday"},"$:/language/Date/Long/Day/2":{"title":"$:/language/Date/Long/Day/2","text":"Tuesday"},"$:/language/Date/Long/Day/3":{"title":"$:/language/Date/Long/Day/3","text":"Wednesday"},"$:/language/Date/Long/Day/4":{"title":"$:/language/Date/Long/Day/4","text":"Thursday"},"$:/language/Date/Long/Day/5":{"title":"$:/language/Date/Long/Day/5","text":"Friday"},"$:/language/Date/Long/Day/6":{"title":"$:/language/Date/Long/Day/6","text":"Saturday"},"$:/language/Date/Long/Month/1":{"title":"$:/language/Date/Long/Month/1","text":"January"},"$:/language/Date/Long/Month/2":{"title":"$:/language/Date/Long/Month/2","text":"February"},"$:/language/Date/Long/Month/3":{"title":"$:/language/Date/Long/Month/3","text":"March"},"$:/language/Date/Long/Month/4":{"title":"$:/language/Date/Long/Month/4","text":"April"},"$:/language/Date/Long/Month/5":{"title":"$:/language/Date/Long/Month/5","text":"May"},"$:/language/Date/Long/Month/6":{"title":"$:/language/Date/Long/Month/6","text":"June"},"$:/language/Date/Long/Month/7":{"title":"$:/language/Date/Long/Month/7","text":"July"},"$:/language/Date/Long/Month/8":{"title":"$:/language/Date/Long/Month/8","text":"August"},"$:/language/Date/Long/Month/9":{"title":"$:/language/Date/Long/Month/9","text":"September"},"$:/language/Date/Long/Month/10":{"title":"$:/language/Date/Long/Month/10","text":"October"},"$:/language/Date/Long/Month/11":{"title":"$:/language/Date/Long/Month/11","text":"November"},"$:/language/Date/Long/Month/12":{"title":"$:/language/Date/Long/Month/12","text":"December"},"$:/language/Date/Period/am":{"title":"$:/language/Date/Period/am","text":"am"},"$:/language/Date/Period/pm":{"title":"$:/language/Date/Period/pm","text":"pm"},"$:/language/Date/Short/Day/0":{"title":"$:/language/Date/Short/Day/0","text":"Sun"},"$:/language/Date/Short/Day/1":{"title":"$:/language/Date/Short/Day/1","text":"Mon"},"$:/language/Date/Short/Day/2":{"title":"$:/language/Date/Short/Day/2","text":"Tue"},"$:/language/Date/Short/Day/3":{"title":"$:/language/Date/Short/Day/3","text":"Wed"},"$:/language/Date/Short/Day/4":{"title":"$:/language/Date/Short/Day/4","text":"Thu"},"$:/language/Date/Short/Day/5":{"title":"$:/language/Date/Short/Day/5","text":"Fri"},"$:/language/Date/Short/Day/6":{"title":"$:/language/Date/Short/Day/6","text":"Sat"},"$:/language/Date/Short/Month/1":{"title":"$:/language/Date/Short/Month/1","text":"Jan"},"$:/language/Date/Short/Month/2":{"title":"$:/language/Date/Short/Month/2","text":"Feb"},"$:/language/Date/Short/Month/3":{"title":"$:/language/Date/Short/Month/3","text":"Mar"},"$:/language/Date/Short/Month/4":{"title":"$:/language/Date/Short/Month/4","text":"Apr"},"$:/language/Date/Short/Month/5":{"title":"$:/language/Date/Short/Month/5","text":"May"},"$:/language/Date/Short/Month/6":{"title":"$:/language/Date/Short/Month/6","text":"Jun"},"$:/language/Date/Short/Month/7":{"title":"$:/language/Date/Short/Month/7","text":"Jul"},"$:/language/Date/Short/Month/8":{"title":"$:/language/Date/Short/Month/8","text":"Aug"},"$:/language/Date/Short/Month/9":{"title":"$:/language/Date/Short/Month/9","text":"Sep"},"$:/language/Date/Short/Month/10":{"title":"$:/language/Date/Short/Month/10","text":"Oct"},"$:/language/Date/Short/Month/11":{"title":"$:/language/Date/Short/Month/11","text":"Nov"},"$:/language/Date/Short/Month/12":{"title":"$:/language/Date/Short/Month/12","text":"Dec"},"$:/language/RelativeDate/Future/Days":{"title":"$:/language/RelativeDate/Future/Days","text":"<<period>> days from now"},"$:/language/RelativeDate/Future/Hours":{"title":"$:/language/RelativeDate/Future/Hours","text":"<<period>> hours from now"},"$:/language/RelativeDate/Future/Minutes":{"title":"$:/language/RelativeDate/Future/Minutes","text":"<<period>> minutes from now"},"$:/language/RelativeDate/Future/Months":{"title":"$:/language/RelativeDate/Future/Months","text":"<<period>> months from now"},"$:/language/RelativeDate/Future/Second":{"title":"$:/language/RelativeDate/Future/Second","text":"1 second from now"},"$:/language/RelativeDate/Future/Seconds":{"title":"$:/language/RelativeDate/Future/Seconds","text":"<<period>> seconds from now"},"$:/language/RelativeDate/Future/Years":{"title":"$:/language/RelativeDate/Future/Years","text":"<<period>> years from now"},"$:/language/RelativeDate/Past/Days":{"title":"$:/language/RelativeDate/Past/Days","text":"<<period>> days ago"},"$:/language/RelativeDate/Past/Hours":{"title":"$:/language/RelativeDate/Past/Hours","text":"<<period>> hours ago"},"$:/language/RelativeDate/Past/Minutes":{"title":"$:/language/RelativeDate/Past/Minutes","text":"<<period>> minutes ago"},"$:/language/RelativeDate/Past/Months":{"title":"$:/language/RelativeDate/Past/Months","text":"<<period>> months ago"},"$:/language/RelativeDate/Past/Second":{"title":"$:/language/RelativeDate/Past/Second","text":"1 second ago"},"$:/language/RelativeDate/Past/Seconds":{"title":"$:/language/RelativeDate/Past/Seconds","text":"<<period>> seconds ago"},"$:/language/RelativeDate/Past/Years":{"title":"$:/language/RelativeDate/Past/Years","text":"<<period>> years ago"},"$:/language/Docs/ModuleTypes/allfilteroperator":{"title":"$:/language/Docs/ModuleTypes/allfilteroperator","text":"A sub-operator for the ''all'' filter operator."},"$:/language/Docs/ModuleTypes/animation":{"title":"$:/language/Docs/ModuleTypes/animation","text":"Animations that may be used with the RevealWidget."},"$:/language/Docs/ModuleTypes/authenticator":{"title":"$:/language/Docs/ModuleTypes/authenticator","text":"Defines how requests are authenticated by the built-in HTTP server."},"$:/language/Docs/ModuleTypes/bitmapeditoroperation":{"title":"$:/language/Docs/ModuleTypes/bitmapeditoroperation","text":"A bitmap editor toolbar operation."},"$:/language/Docs/ModuleTypes/command":{"title":"$:/language/Docs/ModuleTypes/command","text":"Commands that can be executed under Node.js."},"$:/language/Docs/ModuleTypes/config":{"title":"$:/language/Docs/ModuleTypes/config","text":"Data to be inserted into `$tw.config`."},"$:/language/Docs/ModuleTypes/filteroperator":{"title":"$:/language/Docs/ModuleTypes/filteroperator","text":"Individual filter operator methods."},"$:/language/Docs/ModuleTypes/global":{"title":"$:/language/Docs/ModuleTypes/global","text":"Global data to be inserted into `$tw`."},"$:/language/Docs/ModuleTypes/info":{"title":"$:/language/Docs/ModuleTypes/info","text":"Publishes system information via the [[$:/temp/info-plugin]] pseudo-plugin."},"$:/language/Docs/ModuleTypes/isfilteroperator":{"title":"$:/language/Docs/ModuleTypes/isfilteroperator","text":"Parameters for the ''is'' filter operator."},"$:/language/Docs/ModuleTypes/library":{"title":"$:/language/Docs/ModuleTypes/library","text":"Generic module type for general purpose JavaScript modules."},"$:/language/Docs/ModuleTypes/macro":{"title":"$:/language/Docs/ModuleTypes/macro","text":"JavaScript macro definitions."},"$:/language/Docs/ModuleTypes/parser":{"title":"$:/language/Docs/ModuleTypes/parser","text":"Parsers for different content types."},"$:/language/Docs/ModuleTypes/route":{"title":"$:/language/Docs/ModuleTypes/route","text":"Defines how individual URL patterns are handled by the built-in HTTP server."},"$:/language/Docs/ModuleTypes/saver":{"title":"$:/language/Docs/ModuleTypes/saver","text":"Savers handle different methods for saving files from the browser."},"$:/language/Docs/ModuleTypes/startup":{"title":"$:/language/Docs/ModuleTypes/startup","text":"Startup functions."},"$:/language/Docs/ModuleTypes/storyview":{"title":"$:/language/Docs/ModuleTypes/storyview","text":"Story views customise the animation and behaviour of list widgets."},"$:/language/Docs/ModuleTypes/texteditoroperation":{"title":"$:/language/Docs/ModuleTypes/texteditoroperation","text":"A text editor toolbar operation."},"$:/language/Docs/ModuleTypes/tiddlerdeserializer":{"title":"$:/language/Docs/ModuleTypes/tiddlerdeserializer","text":"Converts different content types into tiddlers."},"$:/language/Docs/ModuleTypes/tiddlerfield":{"title":"$:/language/Docs/ModuleTypes/tiddlerfield","text":"Defines the behaviour of an individual tiddler field."},"$:/language/Docs/ModuleTypes/tiddlermethod":{"title":"$:/language/Docs/ModuleTypes/tiddlermethod","text":"Adds methods to the `$tw.Tiddler` prototype."},"$:/language/Docs/ModuleTypes/upgrader":{"title":"$:/language/Docs/ModuleTypes/upgrader","text":"Applies upgrade processing to tiddlers during an upgrade/import."},"$:/language/Docs/ModuleTypes/utils":{"title":"$:/language/Docs/ModuleTypes/utils","text":"Adds methods to `$tw.utils`."},"$:/language/Docs/ModuleTypes/utils-browser":{"title":"$:/language/Docs/ModuleTypes/utils-browser","text":"Adds browser-specific methods to `$tw.utils`."},"$:/language/Docs/ModuleTypes/utils-node":{"title":"$:/language/Docs/ModuleTypes/utils-node","text":"Adds Node.js-specific methods to `$tw.utils`."},"$:/language/Docs/ModuleTypes/widget":{"title":"$:/language/Docs/ModuleTypes/widget","text":"Widgets encapsulate DOM rendering and refreshing."},"$:/language/Docs/ModuleTypes/wikimethod":{"title":"$:/language/Docs/ModuleTypes/wikimethod","text":"Adds methods to `$tw.Wiki`."},"$:/language/Docs/ModuleTypes/wikirule":{"title":"$:/language/Docs/ModuleTypes/wikirule","text":"Individual parser rules for the main WikiText parser."},"$:/language/Docs/PaletteColours/alert-background":{"title":"$:/language/Docs/PaletteColours/alert-background","text":"Alert background"},"$:/language/Docs/PaletteColours/alert-border":{"title":"$:/language/Docs/PaletteColours/alert-border","text":"Alert border"},"$:/language/Docs/PaletteColours/alert-highlight":{"title":"$:/language/Docs/PaletteColours/alert-highlight","text":"Alert highlight"},"$:/language/Docs/PaletteColours/alert-muted-foreground":{"title":"$:/language/Docs/PaletteColours/alert-muted-foreground","text":"Alert muted foreground"},"$:/language/Docs/PaletteColours/background":{"title":"$:/language/Docs/PaletteColours/background","text":"General background"},"$:/language/Docs/PaletteColours/blockquote-bar":{"title":"$:/language/Docs/PaletteColours/blockquote-bar","text":"Blockquote bar"},"$:/language/Docs/PaletteColours/button-background":{"title":"$:/language/Docs/PaletteColours/button-background","text":"Default button background"},"$:/language/Docs/PaletteColours/button-border":{"title":"$:/language/Docs/PaletteColours/button-border","text":"Default button border"},"$:/language/Docs/PaletteColours/button-foreground":{"title":"$:/language/Docs/PaletteColours/button-foreground","text":"Default button foreground"},"$:/language/Docs/PaletteColours/dirty-indicator":{"title":"$:/language/Docs/PaletteColours/dirty-indicator","text":"Unsaved changes indicator"},"$:/language/Docs/PaletteColours/code-background":{"title":"$:/language/Docs/PaletteColours/code-background","text":"Code background"},"$:/language/Docs/PaletteColours/code-border":{"title":"$:/language/Docs/PaletteColours/code-border","text":"Code border"},"$:/language/Docs/PaletteColours/code-foreground":{"title":"$:/language/Docs/PaletteColours/code-foreground","text":"Code foreground"},"$:/language/Docs/PaletteColours/download-background":{"title":"$:/language/Docs/PaletteColours/download-background","text":"Download button background"},"$:/language/Docs/PaletteColours/download-foreground":{"title":"$:/language/Docs/PaletteColours/download-foreground","text":"Download button foreground"},"$:/language/Docs/PaletteColours/dragger-background":{"title":"$:/language/Docs/PaletteColours/dragger-background","text":"Dragger background"},"$:/language/Docs/PaletteColours/dragger-foreground":{"title":"$:/language/Docs/PaletteColours/dragger-foreground","text":"Dragger foreground"},"$:/language/Docs/PaletteColours/dropdown-background":{"title":"$:/language/Docs/PaletteColours/dropdown-background","text":"Dropdown background"},"$:/language/Docs/PaletteColours/dropdown-border":{"title":"$:/language/Docs/PaletteColours/dropdown-border","text":"Dropdown border"},"$:/language/Docs/PaletteColours/dropdown-tab-background-selected":{"title":"$:/language/Docs/PaletteColours/dropdown-tab-background-selected","text":"Dropdown tab background for selected tabs"},"$:/language/Docs/PaletteColours/dropdown-tab-background":{"title":"$:/language/Docs/PaletteColours/dropdown-tab-background","text":"Dropdown tab background"},"$:/language/Docs/PaletteColours/dropzone-background":{"title":"$:/language/Docs/PaletteColours/dropzone-background","text":"Dropzone background"},"$:/language/Docs/PaletteColours/external-link-background-hover":{"title":"$:/language/Docs/PaletteColours/external-link-background-hover","text":"External link background hover"},"$:/language/Docs/PaletteColours/external-link-background-visited":{"title":"$:/language/Docs/PaletteColours/external-link-background-visited","text":"External link background visited"},"$:/language/Docs/PaletteColours/external-link-background":{"title":"$:/language/Docs/PaletteColours/external-link-background","text":"External link background"},"$:/language/Docs/PaletteColours/external-link-foreground-hover":{"title":"$:/language/Docs/PaletteColours/external-link-foreground-hover","text":"External link foreground hover"},"$:/language/Docs/PaletteColours/external-link-foreground-visited":{"title":"$:/language/Docs/PaletteColours/external-link-foreground-visited","text":"External link foreground visited"},"$:/language/Docs/PaletteColours/external-link-foreground":{"title":"$:/language/Docs/PaletteColours/external-link-foreground","text":"External link foreground"},"$:/language/Docs/PaletteColours/foreground":{"title":"$:/language/Docs/PaletteColours/foreground","text":"General foreground"},"$:/language/Docs/PaletteColours/menubar-background":{"title":"$:/language/Docs/PaletteColours/menubar-background","text":"Menu bar background"},"$:/language/Docs/PaletteColours/menubar-foreground":{"title":"$:/language/Docs/PaletteColours/menubar-foreground","text":"Menu bar foreground"},"$:/language/Docs/PaletteColours/message-background":{"title":"$:/language/Docs/PaletteColours/message-background","text":"Message box background"},"$:/language/Docs/PaletteColours/message-border":{"title":"$:/language/Docs/PaletteColours/message-border","text":"Message box border"},"$:/language/Docs/PaletteColours/message-foreground":{"title":"$:/language/Docs/PaletteColours/message-foreground","text":"Message box foreground"},"$:/language/Docs/PaletteColours/modal-backdrop":{"title":"$:/language/Docs/PaletteColours/modal-backdrop","text":"Modal backdrop"},"$:/language/Docs/PaletteColours/modal-background":{"title":"$:/language/Docs/PaletteColours/modal-background","text":"Modal background"},"$:/language/Docs/PaletteColours/modal-border":{"title":"$:/language/Docs/PaletteColours/modal-border","text":"Modal border"},"$:/language/Docs/PaletteColours/modal-footer-background":{"title":"$:/language/Docs/PaletteColours/modal-footer-background","text":"Modal footer background"},"$:/language/Docs/PaletteColours/modal-footer-border":{"title":"$:/language/Docs/PaletteColours/modal-footer-border","text":"Modal footer border"},"$:/language/Docs/PaletteColours/modal-header-border":{"title":"$:/language/Docs/PaletteColours/modal-header-border","text":"Modal header border"},"$:/language/Docs/PaletteColours/muted-foreground":{"title":"$:/language/Docs/PaletteColours/muted-foreground","text":"General muted foreground"},"$:/language/Docs/PaletteColours/notification-background":{"title":"$:/language/Docs/PaletteColours/notification-background","text":"Notification background"},"$:/language/Docs/PaletteColours/notification-border":{"title":"$:/language/Docs/PaletteColours/notification-border","text":"Notification border"},"$:/language/Docs/PaletteColours/page-background":{"title":"$:/language/Docs/PaletteColours/page-background","text":"Page background"},"$:/language/Docs/PaletteColours/pre-background":{"title":"$:/language/Docs/PaletteColours/pre-background","text":"Preformatted code background"},"$:/language/Docs/PaletteColours/pre-border":{"title":"$:/language/Docs/PaletteColours/pre-border","text":"Preformatted code border"},"$:/language/Docs/PaletteColours/primary":{"title":"$:/language/Docs/PaletteColours/primary","text":"General primary"},"$:/language/Docs/PaletteColours/select-tag-background":{"title":"$:/language/Docs/PaletteColours/select-tag-background","text":"`<select>` element background"},"$:/language/Docs/PaletteColours/select-tag-foreground":{"title":"$:/language/Docs/PaletteColours/select-tag-foreground","text":"`<select>` element text"},"$:/language/Docs/PaletteColours/sidebar-button-foreground":{"title":"$:/language/Docs/PaletteColours/sidebar-button-foreground","text":"Sidebar button foreground"},"$:/language/Docs/PaletteColours/sidebar-controls-foreground-hover":{"title":"$:/language/Docs/PaletteColours/sidebar-controls-foreground-hover","text":"Sidebar controls foreground hover"},"$:/language/Docs/PaletteColours/sidebar-controls-foreground":{"title":"$:/language/Docs/PaletteColours/sidebar-controls-foreground","text":"Sidebar controls foreground"},"$:/language/Docs/PaletteColours/sidebar-foreground-shadow":{"title":"$:/language/Docs/PaletteColours/sidebar-foreground-shadow","text":"Sidebar foreground shadow"},"$:/language/Docs/PaletteColours/sidebar-foreground":{"title":"$:/language/Docs/PaletteColours/sidebar-foreground","text":"Sidebar foreground"},"$:/language/Docs/PaletteColours/sidebar-muted-foreground-hover":{"title":"$:/language/Docs/PaletteColours/sidebar-muted-foreground-hover","text":"Sidebar muted foreground hover"},"$:/language/Docs/PaletteColours/sidebar-muted-foreground":{"title":"$:/language/Docs/PaletteColours/sidebar-muted-foreground","text":"Sidebar muted foreground"},"$:/language/Docs/PaletteColours/sidebar-tab-background-selected":{"title":"$:/language/Docs/PaletteColours/sidebar-tab-background-selected","text":"Sidebar tab background for selected tabs"},"$:/language/Docs/PaletteColours/sidebar-tab-background":{"title":"$:/language/Docs/PaletteColours/sidebar-tab-background","text":"Sidebar tab background"},"$:/language/Docs/PaletteColours/sidebar-tab-border-selected":{"title":"$:/language/Docs/PaletteColours/sidebar-tab-border-selected","text":"Sidebar tab border for selected tabs"},"$:/language/Docs/PaletteColours/sidebar-tab-border":{"title":"$:/language/Docs/PaletteColours/sidebar-tab-border","text":"Sidebar tab border"},"$:/language/Docs/PaletteColours/sidebar-tab-divider":{"title":"$:/language/Docs/PaletteColours/sidebar-tab-divider","text":"Sidebar tab divider"},"$:/language/Docs/PaletteColours/sidebar-tab-foreground-selected":{"title":"$:/language/Docs/PaletteColours/sidebar-tab-foreground-selected","text":"Sidebar tab foreground for selected tabs"},"$:/language/Docs/PaletteColours/sidebar-tab-foreground":{"title":"$:/language/Docs/PaletteColours/sidebar-tab-foreground","text":"Sidebar tab foreground"},"$:/language/Docs/PaletteColours/sidebar-tiddler-link-foreground-hover":{"title":"$:/language/Docs/PaletteColours/sidebar-tiddler-link-foreground-hover","text":"Sidebar tiddler link foreground hover"},"$:/language/Docs/PaletteColours/sidebar-tiddler-link-foreground":{"title":"$:/language/Docs/PaletteColours/sidebar-tiddler-link-foreground","text":"Sidebar tiddler link foreground"},"$:/language/Docs/PaletteColours/stability-stable":{"title":"$:/language/Docs/PaletteColours/stability-stable","text":"Badge for stability level \"stable\""},"$:/language/Docs/PaletteColours/stability-experimental":{"title":"$:/language/Docs/PaletteColours/stability-experimental","text":"Badge for stability level \"experimental\""},"$:/language/Docs/PaletteColours/stability-deprecated":{"title":"$:/language/Docs/PaletteColours/stability-deprecated","text":"Badge for stability level \"deprecated\""},"$:/language/Docs/PaletteColours/stability-legacy":{"title":"$:/language/Docs/PaletteColours/stability-legacy","text":"Badge for stability level \"legacy\""},"$:/language/Docs/PaletteColours/testcase-accent-level-1":{"title":"$:/language/Docs/PaletteColours/testcase-accent-level-1","text":"Test case accent colour with no nesting"},"$:/language/Docs/PaletteColours/testcase-accent-level-2":{"title":"$:/language/Docs/PaletteColours/testcase-accent-level-2","text":"Test case accent colour with 2nd level nesting"},"$:/language/Docs/PaletteColours/testcase-accent-level-3":{"title":"$:/language/Docs/PaletteColours/testcase-accent-level-3","text":"Test case accent colour with 3rd level nesting or higher"},"$:/language/Docs/PaletteColours/site-title-foreground":{"title":"$:/language/Docs/PaletteColours/site-title-foreground","text":"Site title foreground"},"$:/language/Docs/PaletteColours/static-alert-foreground":{"title":"$:/language/Docs/PaletteColours/static-alert-foreground","text":"Static alert foreground"},"$:/language/Docs/PaletteColours/tab-background-selected":{"title":"$:/language/Docs/PaletteColours/tab-background-selected","text":"Tab background for selected tabs"},"$:/language/Docs/PaletteColours/tab-background":{"title":"$:/language/Docs/PaletteColours/tab-background","text":"Tab background"},"$:/language/Docs/PaletteColours/tab-border-selected":{"title":"$:/language/Docs/PaletteColours/tab-border-selected","text":"Tab border for selected tabs"},"$:/language/Docs/PaletteColours/tab-border":{"title":"$:/language/Docs/PaletteColours/tab-border","text":"Tab border"},"$:/language/Docs/PaletteColours/tab-divider":{"title":"$:/language/Docs/PaletteColours/tab-divider","text":"Tab divider"},"$:/language/Docs/PaletteColours/tab-foreground-selected":{"title":"$:/language/Docs/PaletteColours/tab-foreground-selected","text":"Tab foreground for selected tabs"},"$:/language/Docs/PaletteColours/tab-foreground":{"title":"$:/language/Docs/PaletteColours/tab-foreground","text":"Tab foreground"},"$:/language/Docs/PaletteColours/table-border":{"title":"$:/language/Docs/PaletteColours/table-border","text":"Table border"},"$:/language/Docs/PaletteColours/table-footer-background":{"title":"$:/language/Docs/PaletteColours/table-footer-background","text":"Table footer background"},"$:/language/Docs/PaletteColours/table-header-background":{"title":"$:/language/Docs/PaletteColours/table-header-background","text":"Table header background"},"$:/language/Docs/PaletteColours/tag-background":{"title":"$:/language/Docs/PaletteColours/tag-background","text":"Tag background"},"$:/language/Docs/PaletteColours/tag-foreground":{"title":"$:/language/Docs/PaletteColours/tag-foreground","text":"Tag foreground"},"$:/language/Docs/PaletteColours/tiddler-background":{"title":"$:/language/Docs/PaletteColours/tiddler-background","text":"Tiddler background"},"$:/language/Docs/PaletteColours/tiddler-border":{"title":"$:/language/Docs/PaletteColours/tiddler-border","text":"Tiddler border"},"$:/language/Docs/PaletteColours/tiddler-controls-foreground-hover":{"title":"$:/language/Docs/PaletteColours/tiddler-controls-foreground-hover","text":"Tiddler controls foreground hover"},"$:/language/Docs/PaletteColours/tiddler-controls-foreground-selected":{"title":"$:/language/Docs/PaletteColours/tiddler-controls-foreground-selected","text":"Tiddler controls foreground for selected controls"},"$:/language/Docs/PaletteColours/tiddler-controls-foreground":{"title":"$:/language/Docs/PaletteColours/tiddler-controls-foreground","text":"Tiddler controls foreground"},"$:/language/Docs/PaletteColours/tiddler-editor-background":{"title":"$:/language/Docs/PaletteColours/tiddler-editor-background","text":"Tiddler editor background"},"$:/language/Docs/PaletteColours/tiddler-editor-border-image":{"title":"$:/language/Docs/PaletteColours/tiddler-editor-border-image","text":"Tiddler editor border image"},"$:/language/Docs/PaletteColours/tiddler-editor-border":{"title":"$:/language/Docs/PaletteColours/tiddler-editor-border","text":"Tiddler editor border"},"$:/language/Docs/PaletteColours/tiddler-editor-fields-even":{"title":"$:/language/Docs/PaletteColours/tiddler-editor-fields-even","text":"Tiddler editor background for even fields"},"$:/language/Docs/PaletteColours/tiddler-editor-fields-odd":{"title":"$:/language/Docs/PaletteColours/tiddler-editor-fields-odd","text":"Tiddler editor background for odd fields"},"$:/language/Docs/PaletteColours/tiddler-info-background":{"title":"$:/language/Docs/PaletteColours/tiddler-info-background","text":"Tiddler info panel background"},"$:/language/Docs/PaletteColours/tiddler-info-border":{"title":"$:/language/Docs/PaletteColours/tiddler-info-border","text":"Tiddler info panel border"},"$:/language/Docs/PaletteColours/tiddler-info-tab-background":{"title":"$:/language/Docs/PaletteColours/tiddler-info-tab-background","text":"Tiddler info panel tab background"},"$:/language/Docs/PaletteColours/tiddler-link-background":{"title":"$:/language/Docs/PaletteColours/tiddler-link-background","text":"Tiddler link background"},"$:/language/Docs/PaletteColours/tiddler-link-foreground":{"title":"$:/language/Docs/PaletteColours/tiddler-link-foreground","text":"Tiddler link foreground"},"$:/language/Docs/PaletteColours/tiddler-subtitle-foreground":{"title":"$:/language/Docs/PaletteColours/tiddler-subtitle-foreground","text":"Tiddler subtitle foreground"},"$:/language/Docs/PaletteColours/tiddler-title-foreground":{"title":"$:/language/Docs/PaletteColours/tiddler-title-foreground","text":"Tiddler title foreground"},"$:/language/Docs/PaletteColours/toolbar-new-button":{"title":"$:/language/Docs/PaletteColours/toolbar-new-button","text":"Toolbar 'new tiddler' button foreground"},"$:/language/Docs/PaletteColours/toolbar-options-button":{"title":"$:/language/Docs/PaletteColours/toolbar-options-button","text":"Toolbar 'options' button foreground"},"$:/language/Docs/PaletteColours/toolbar-save-button":{"title":"$:/language/Docs/PaletteColours/toolbar-save-button","text":"Toolbar 'save' button foreground"},"$:/language/Docs/PaletteColours/toolbar-info-button":{"title":"$:/language/Docs/PaletteColours/toolbar-info-button","text":"Toolbar 'info' button foreground"},"$:/language/Docs/PaletteColours/toolbar-edit-button":{"title":"$:/language/Docs/PaletteColours/toolbar-edit-button","text":"Toolbar 'edit' button foreground"},"$:/language/Docs/PaletteColours/toolbar-close-button":{"title":"$:/language/Docs/PaletteColours/toolbar-close-button","text":"Toolbar 'close' button foreground"},"$:/language/Docs/PaletteColours/toolbar-delete-button":{"title":"$:/language/Docs/PaletteColours/toolbar-delete-button","text":"Toolbar 'delete' button foreground"},"$:/language/Docs/PaletteColours/toolbar-cancel-button":{"title":"$:/language/Docs/PaletteColours/toolbar-cancel-button","text":"Toolbar 'cancel' button foreground"},"$:/language/Docs/PaletteColours/toolbar-done-button":{"title":"$:/language/Docs/PaletteColours/toolbar-done-button","text":"Toolbar 'done' button foreground"},"$:/language/Docs/PaletteColours/untagged-background":{"title":"$:/language/Docs/PaletteColours/untagged-background","text":"Untagged pill background"},"$:/language/Docs/PaletteColours/very-muted-foreground":{"title":"$:/language/Docs/PaletteColours/very-muted-foreground","text":"Very muted foreground"},"$:/language/EditTemplate/Caption":{"title":"$:/language/EditTemplate/Caption","text":"Editor"},"$:/language/EditTemplate/Body/External/Hint":{"title":"$:/language/EditTemplate/Body/External/Hint","text":"This tiddler shows content stored outside of the main TiddlyWiki file. You can edit the tags and fields but cannot directly edit the content itself"},"$:/language/EditTemplate/Body/Placeholder":{"title":"$:/language/EditTemplate/Body/Placeholder","text":"Type the text for this tiddler"},"$:/language/EditTemplate/Body/Preview/Type/Output":{"title":"$:/language/EditTemplate/Body/Preview/Type/Output","text":"output"},"$:/language/EditTemplate/Body/Preview/Type/DiffShadow":{"title":"$:/language/EditTemplate/Body/Preview/Type/DiffShadow","text":"differences from shadow (if any)"},"$:/language/EditTemplate/Body/Preview/Type/DiffCurrent":{"title":"$:/language/EditTemplate/Body/Preview/Type/DiffCurrent","text":"differences from current"},"$:/language/EditTemplate/Field/Remove/Caption":{"title":"$:/language/EditTemplate/Field/Remove/Caption","text":"remove field"},"$:/language/EditTemplate/Field/Remove/Hint":{"title":"$:/language/EditTemplate/Field/Remove/Hint","text":"Remove field"},"$:/language/EditTemplate/Field/Dropdown/Caption":{"title":"$:/language/EditTemplate/Field/Dropdown/Caption","text":"field list"},"$:/language/EditTemplate/Field/Dropdown/Hint":{"title":"$:/language/EditTemplate/Field/Dropdown/Hint","text":"Show field list"},"$:/language/EditTemplate/Fields/Add/Button":{"title":"$:/language/EditTemplate/Fields/Add/Button","text":"add"},"$:/language/EditTemplate/Fields/Add/Button/Hint":{"title":"$:/language/EditTemplate/Fields/Add/Button/Hint","text":"Add the new field to the tiddler"},"$:/language/EditTemplate/Fields/Add/Name/Placeholder":{"title":"$:/language/EditTemplate/Fields/Add/Name/Placeholder","text":"field name"},"$:/language/EditTemplate/Fields/Add/Prompt":{"title":"$:/language/EditTemplate/Fields/Add/Prompt","text":"Add a new field:"},"$:/language/EditTemplate/Fields/Add/Value/Placeholder":{"title":"$:/language/EditTemplate/Fields/Add/Value/Placeholder","text":"field value"},"$:/language/EditTemplate/Fields/Add/Dropdown/System":{"title":"$:/language/EditTemplate/Fields/Add/Dropdown/System","text":"System fields"},"$:/language/EditTemplate/Fields/Add/Dropdown/User":{"title":"$:/language/EditTemplate/Fields/Add/Dropdown/User","text":"User fields"},"$:/language/EditTemplate/Shadow/Warning":{"title":"$:/language/EditTemplate/Shadow/Warning","text":"This is a shadow tiddler. Any changes you make will override the default version from the plugin <<pluginLink>>"},"$:/language/EditTemplate/Shadow/OverriddenWarning":{"title":"$:/language/EditTemplate/Shadow/OverriddenWarning","text":"This is a modified shadow tiddler. You can revert to the default version in the plugin <<pluginLink>> by deleting this tiddler"},"$:/language/EditTemplate/Tags/Add/Button":{"title":"$:/language/EditTemplate/Tags/Add/Button","text":"add"},"$:/language/EditTemplate/Tags/Add/Button/Hint":{"title":"$:/language/EditTemplate/Tags/Add/Button/Hint","text":"add tag"},"$:/language/EditTemplate/Tags/Add/Placeholder":{"title":"$:/language/EditTemplate/Tags/Add/Placeholder","text":"tag name"},"$:/language/EditTemplate/Tags/ClearInput/Caption":{"title":"$:/language/EditTemplate/Tags/ClearInput/Caption","text":"clear input"},"$:/language/EditTemplate/Tags/ClearInput/Hint":{"title":"$:/language/EditTemplate/Tags/ClearInput/Hint","text":"Clear tag input"},"$:/language/EditTemplate/Tags/Dropdown/Caption":{"title":"$:/language/EditTemplate/Tags/Dropdown/Caption","text":"tag list"},"$:/language/EditTemplate/Tags/Dropdown/Hint":{"title":"$:/language/EditTemplate/Tags/Dropdown/Hint","text":"Show tag list"},"$:/language/EditTemplate/Tags/EmptyMessage":{"title":"$:/language/EditTemplate/Tags/EmptyMessage","text":"No tags found"},"$:/language/EditTemplate/Tags/EmptyMessage/System":{"title":"$:/language/EditTemplate/Tags/EmptyMessage/System","text":"No system tags found"},"$:/language/EditTemplate/Title/BadCharacterWarning":{"title":"$:/language/EditTemplate/Title/BadCharacterWarning","text":"Warning: avoid using any of the characters <<bad-chars>> in tiddler titles"},"$:/language/EditTemplate/Title/Exists/Prompt":{"title":"$:/language/EditTemplate/Title/Exists/Prompt","text":"Target tiddler already exists"},"$:/language/EditTemplate/Title/Relink/Prompt":{"title":"$:/language/EditTemplate/Title/Relink/Prompt","text":"Update ''<$text text=<<fromTitle>>/>'' to ''<$text text=<<toTitle>>/>'' in the //tags// and //list// fields of other tiddlers"},"$:/language/EditTemplate/Title/References/Prompt":{"title":"$:/language/EditTemplate/Title/References/Prompt","text":"The following references to this tiddler will not be automatically updated:"},"$:/language/EditTemplate/Type/Dropdown/Caption":{"title":"$:/language/EditTemplate/Type/Dropdown/Caption","text":"content type list"},"$:/language/EditTemplate/Type/Dropdown/Hint":{"title":"$:/language/EditTemplate/Type/Dropdown/Hint","text":"Show content type list"},"$:/language/EditTemplate/Type/Delete/Caption":{"title":"$:/language/EditTemplate/Type/Delete/Caption","text":"delete content type"},"$:/language/EditTemplate/Type/Delete/Hint":{"title":"$:/language/EditTemplate/Type/Delete/Hint","text":"Delete content type"},"$:/language/EditTemplate/Type/Placeholder":{"title":"$:/language/EditTemplate/Type/Placeholder","text":"content type"},"$:/language/EditTemplate/Type/Prompt":{"title":"$:/language/EditTemplate/Type/Prompt","text":"Type:"},"$:/language/Exporters/StaticRiver":{"title":"$:/language/Exporters/StaticRiver","text":"Static HTML"},"$:/language/Exporters/JsonFile":{"title":"$:/language/Exporters/JsonFile","text":"JSON file"},"$:/language/Exporters/CsvFile":{"title":"$:/language/Exporters/CsvFile","text":"CSV file"},"$:/language/Exporters/TidFile":{"title":"$:/language/Exporters/TidFile","text":"TID text file"},"$:/language/Docs/Fields/_canonical_uri":{"title":"$:/language/Docs/Fields/_canonical_uri","text":"The full URI of an external image tiddler"},"$:/language/Docs/Fields/author":{"title":"$:/language/Docs/Fields/author","text":"Name of the author of a plugin"},"$:/language/Docs/Fields/bag":{"title":"$:/language/Docs/Fields/bag","text":"The name of the bag from which a tiddler came"},"$:/language/Docs/Fields/caption":{"title":"$:/language/Docs/Fields/caption","text":"The text to be displayed on a tab or button"},"$:/language/Docs/Fields/class":{"title":"$:/language/Docs/Fields/class","text":"The CSS class applied to a tiddler when rendering it - see [[Custom styles by user-class]].  Also used for [[Modals]]"},"$:/language/Docs/Fields/code-body":{"title":"$:/language/Docs/Fields/code-body","text":"The view template will display the tiddler as code if set to ''yes''"},"$:/language/Docs/Fields/color":{"title":"$:/language/Docs/Fields/color","text":"The CSS color value associated with a tiddler"},"$:/language/Docs/Fields/component":{"title":"$:/language/Docs/Fields/component","text":"The name of the component responsible for an [[alert tiddler|AlertMechanism]]"},"$:/language/Docs/Fields/core-version":{"title":"$:/language/Docs/Fields/core-version","text":"For a plugin, indicates what version of TiddlyWiki with which it is compatible"},"$:/language/Docs/Fields/current-tiddler":{"title":"$:/language/Docs/Fields/current-tiddler","text":"Used to cache the top tiddler in a [[history list|HistoryMechanism]]"},"$:/language/Docs/Fields/created":{"title":"$:/language/Docs/Fields/created","text":"The date a tiddler was created"},"$:/language/Docs/Fields/creator":{"title":"$:/language/Docs/Fields/creator","text":"The name of the person who created a tiddler"},"$:/language/Docs/Fields/dependents":{"title":"$:/language/Docs/Fields/dependents","text":"For a plugin, lists the dependent plugin titles"},"$:/language/Docs/Fields/description":{"title":"$:/language/Docs/Fields/description","text":"The descriptive text for a plugin, or a modal dialogue"},"$:/language/Docs/Fields/draft.of":{"title":"$:/language/Docs/Fields/draft.of","text":"For draft tiddlers, contains the title of the tiddler of which this is a draft"},"$:/language/Docs/Fields/draft.title":{"title":"$:/language/Docs/Fields/draft.title","text":"For draft tiddlers, contains the proposed new title of the tiddler"},"$:/language/Docs/Fields/footer":{"title":"$:/language/Docs/Fields/footer","text":"The footer text for a modal"},"$:/language/Docs/Fields/hide-body":{"title":"$:/language/Docs/Fields/hide-body","text":"The view template will hide bodies of tiddlers if set to ''yes''"},"$:/language/Docs/Fields/icon":{"title":"$:/language/Docs/Fields/icon","text":"The title of the tiddler containing the icon associated with a tiddler"},"$:/language/Docs/Fields/library":{"title":"$:/language/Docs/Fields/library","text":"Indicates that a tiddler should be saved as a JavaScript library if set to ''yes''"},"$:/language/Docs/Fields/list":{"title":"$:/language/Docs/Fields/list","text":"An ordered list of tiddler titles associated with a tiddler"},"$:/language/Docs/Fields/list-before":{"title":"$:/language/Docs/Fields/list-before","text":"If set, the title of a tiddler before which this tiddler should be added to the ordered list of tiddler titles, or at the start of the list if this field is present but empty"},"$:/language/Docs/Fields/list-after":{"title":"$:/language/Docs/Fields/list-after","text":"If set, the title of the tiddler after which this tiddler should be added to the ordered list of tiddler titles, or at the end of the list if this field is present but empty"},"$:/language/Docs/Fields/modified":{"title":"$:/language/Docs/Fields/modified","text":"The date and time at which a tiddler was last modified"},"$:/language/Docs/Fields/modifier":{"title":"$:/language/Docs/Fields/modifier","text":"The tiddler title associated with the person who last modified a tiddler"},"$:/language/Docs/Fields/module-type":{"title":"$:/language/Docs/Fields/module-type","text":"For javascript tiddlers, specifies what kind of module it is"},"$:/language/Docs/Fields/name":{"title":"$:/language/Docs/Fields/name","text":"The human readable name associated with a plugin tiddler"},"$:/language/Docs/Fields/parent-plugin":{"title":"$:/language/Docs/Fields/parent-plugin","text":"For a plugin, specifies which plugin of which it is a sub-plugin"},"$:/language/Docs/Fields/plugin-priority":{"title":"$:/language/Docs/Fields/plugin-priority","text":"A numerical value indicating the priority of a plugin tiddler"},"$:/language/Docs/Fields/plugin-type":{"title":"$:/language/Docs/Fields/plugin-type","text":"The type of plugin in a plugin tiddler"},"$:/language/Docs/Fields/stability":{"title":"$:/language/Docs/Fields/stability","text":"The development status of a plugin: deprecated, experimental, stable, or legacy"},"$:/language/Docs/Fields/revision":{"title":"$:/language/Docs/Fields/revision","text":"The revision of the tiddler held at the server"},"$:/language/Docs/Fields/released":{"title":"$:/language/Docs/Fields/released","text":"Date of a TiddlyWiki release"},"$:/language/Docs/Fields/source":{"title":"$:/language/Docs/Fields/source","text":"The source URL associated with a tiddler"},"$:/language/Docs/Fields/subtitle":{"title":"$:/language/Docs/Fields/subtitle","text":"The subtitle text for a modal"},"$:/language/Docs/Fields/tags":{"title":"$:/language/Docs/Fields/tags","text":"A list of tags associated with a tiddler"},"$:/language/Docs/Fields/text":{"title":"$:/language/Docs/Fields/text","text":"The body text of a tiddler"},"$:/language/Docs/Fields/throttle.refresh":{"title":"$:/language/Docs/Fields/throttle.refresh","text":"If present, throttles refreshes of this tiddler"},"$:/language/Docs/Fields/title":{"title":"$:/language/Docs/Fields/title","text":"The unique name of a tiddler"},"$:/language/Docs/Fields/toc-link":{"title":"$:/language/Docs/Fields/toc-link","text":"Suppresses the tiddler's link in a Table of Contents tree if set to ''no''"},"$:/language/Docs/Fields/type":{"title":"$:/language/Docs/Fields/type","text":"The content type of a tiddler"},"$:/language/Docs/Fields/version":{"title":"$:/language/Docs/Fields/version","text":"Version information for a plugin"},"$:/language/Docs/Fields/_is_skinny":{"title":"$:/language/Docs/Fields/_is_skinny","text":"If present, indicates that the tiddler text field must be loaded from the server"},"$:/language/Filters/AllTiddlers":{"title":"$:/language/Filters/AllTiddlers","text":"All tiddlers except system tiddlers"},"$:/language/Filters/RecentSystemTiddlers":{"title":"$:/language/Filters/RecentSystemTiddlers","text":"Recently modified tiddlers, including system tiddlers"},"$:/language/Filters/RecentTiddlers":{"title":"$:/language/Filters/RecentTiddlers","text":"Recently modified tiddlers"},"$:/language/Filters/AllTags":{"title":"$:/language/Filters/AllTags","text":"All tags except system tags"},"$:/language/Filters/Missing":{"title":"$:/language/Filters/Missing","text":"Missing tiddlers"},"$:/language/Filters/Drafts":{"title":"$:/language/Filters/Drafts","text":"Draft tiddlers"},"$:/language/Filters/Orphans":{"title":"$:/language/Filters/Orphans","text":"Orphan tiddlers"},"$:/language/Filters/SystemTiddlers":{"title":"$:/language/Filters/SystemTiddlers","text":"System tiddlers"},"$:/language/Filters/ShadowTiddlers":{"title":"$:/language/Filters/ShadowTiddlers","text":"Shadow tiddlers"},"$:/language/Filters/OverriddenShadowTiddlers":{"title":"$:/language/Filters/OverriddenShadowTiddlers","text":"Overridden shadow tiddlers"},"$:/language/Filters/SessionTiddlers":{"title":"$:/language/Filters/SessionTiddlers","text":"Tiddlers modified since the wiki was loaded"},"$:/language/Filters/SystemTags":{"title":"$:/language/Filters/SystemTags","text":"System tags"},"$:/language/Filters/StoryList":{"title":"$:/language/Filters/StoryList","text":"Tiddlers in the story river, excluding <$text text=\"$:/AdvancedSearch\"/>"},"$:/language/Filters/TypedTiddlers":{"title":"$:/language/Filters/TypedTiddlers","text":"Non wiki-text tiddlers"},"GettingStarted":{"title":"GettingStarted","text":"\\define lingo-base() $:/language/ControlPanel/Basics/\nWelcome to ~TiddlyWiki and the ~TiddlyWiki community\n\nBefore you start storing important information in ~TiddlyWiki it is vital to make sure that you can reliably save changes. See https://tiddlywiki.com/#GettingStarted for details\n\n!! Set up this ~TiddlyWiki\n\n<div class=\"tc-control-panel\">\n\n|tc-table-no-border tc-first-col-min-width tc-first-link-nowrap|k\n| <$link to=\"$:/SiteTitle\"><<lingo Title/Prompt>></$link>|<$edit-text tiddler=\"$:/SiteTitle\" default=\"\" tag=\"input\"/> |\n| <$link to=\"$:/SiteSubtitle\"><<lingo Subtitle/Prompt>></$link>|<$edit-text tiddler=\"$:/SiteSubtitle\" default=\"\" tag=\"input\"/> |\n|^ <$link to=\"$:/DefaultTiddlers\"><<lingo DefaultTiddlers/Prompt>></$link><br><<lingo DefaultTiddlers/TopHint>>|<$edit tag=\"textarea\" tiddler=\"$:/DefaultTiddlers\"/><br>//<<lingo DefaultTiddlers/BottomHint>>// |\n</div>\n\nSee the [[control panel|$:/ControlPanel]] for more options.\n"},"$:/language/Help/build":{"title":"$:/language/Help/build","description":"Automatically run configured commands","text":"Build the specified build targets for the current wiki. If no build targets are specified then all available targets will be built.\n\n```\n--build <target> [<target> ...]\n```\n\nBuild targets are defined in the `tiddlywiki.info` file of a wiki folder.\n\n"},"$:/language/Help/clearpassword":{"title":"$:/language/Help/clearpassword","description":"Clear a password for subsequent crypto operations","text":"Clear the password for subsequent crypto operations\n\n```\n--clearpassword\n```\n"},"$:/language/Help/commands":{"title":"$:/language/Help/commands","description":"Run commands returned from a filter","text":"Sequentially run the command tokens returned from a filter\n\n```\n--commands <filter>\n```\n\nExamples\n\n```\n--commands \"[enlist:raw{$:/build-commands-as-text}]\"\n```\n\n```\n--commands \"[{$:/build-commands-as-json}jsonindexes[]] :map[{$:/build-commands-as-json}jsonget<currentTiddler>]\"\n```\n"},"$:/language/Help/default":{"title":"$:/language/Help/default","text":"\\define commandTitle()\n$:/language/Help/$(command)$\n\\end\n\\whitespace trim\n```\nusage: tiddlywiki [<wikifolder>] [--<command> [<args>...]...]\n```\n\nAvailable commands:\n\n<ul>\n<$list filter=\"[commands[]sort[title]]\" variable=\"command\">\n<li><$link to=<<commandTitle>>><$macrocall $name=\"command\" $type=\"text/plain\" $output=\"text/plain\"/></$link>:\n&#32;\n<$transclude tiddler=<<commandTitle>> field=\"description\"/></li>\n</$list>\n</ul>\n\nTo get detailed help on a command:\n\n```\ntiddlywiki --help <command>\n```\n"},"$:/language/Help/deletetiddlers":{"title":"$:/language/Help/deletetiddlers","description":"Deletes a group of tiddlers","text":"<<.from-version \"5.1.20\">> Deletes a group of tiddlers identified by a filter.\n\n```\n--deletetiddlers <filter>\n```\n"},"$:/language/Help/editions":{"title":"$:/language/Help/editions","description":"Lists the available editions of TiddlyWiki","text":"Lists the names and descriptions of the available editions. You can create a new wiki of a specified edition with the `--init` command.\n\n```\n--editions\n```\n"},"$:/language/Help/fetch":{"title":"$:/language/Help/fetch","description":"Fetch tiddlers from wiki by URL","text":"Fetch one or more files over HTTP/HTTPS, and import the tiddlers matching a filter, optionally transforming the incoming titles.\n\n```\n--fetch file <url> <import-filter> <transform-filter>\n--fetch files <url-filter> <import-filter> <transform-filter>\n--fetch raw-file <url> <transform-filter>\n--fetch raw-files <url-filter> <transform-filter>\n```\n\nThe \"file\" and \"files\" variants fetch the specified files and attempt to import the tiddlers within them (the same processing as if the files were dragged into the browser window). The \"raw-file\" and \"raw-files\" variants fetch the specified files and then store the raw file data in tiddlers, without applying the import logic.\n\nWith the \"file\" and \"raw-file\" variants only a single file is fetched and the first parameter is the URL of the file to read.\n\nWith the \"files\" and \"raw-files\" variants, multiple files are fetched and the first parameter is a filter yielding a list of URLs of the files to read. For example, given a set of tiddlers tagged \"remote-server\" that have a field \"url\" the filter `[tag[remote-server]get[url]]` will retrieve all the available URLs.\n\nFor the \"file\" and \"files\" variants, the `<import-filter>` parameter specifies a filter determining which tiddlers are imported. It defaults to `[all[tiddlers]]` if not provided.\n\nFor all variants, the `<transform-filter>` parameter specifies an optional filter that transforms the titles of the imported tiddlers. For example, `[addprefix[$:/myimports/]]` would add the prefix `$:/myimports/` to each title.\n\nPreceding the `--fetch` command with `--verbose` will output progress information during the import.\n\nNote that TiddlyWiki will not fetch an older version of an already loaded plugin.\n\nThe following example retrieves all the non-system tiddlers from https://tiddlywiki.com and saves them to a JSON file:\n\n```\ntiddlywiki --verbose --fetch file \"https://tiddlywiki.com/\" \"[!is[system]]\" \"\" --rendertiddler \"$:/core/templates/exporters/JsonFile\" output.json text/plain \"\" exportFilter \"[!is[system]]\"\n```\n\nThe following example retrieves the \"favicon\" file from tiddlywiki.com and saves it in a file called \"output.ico\". Note that the intermediate tiddler \"Icon Tiddler\" is quoted in the \"--fetch\" command because it is being used as a transformation filter to replace the default title, while there are no quotes for the \"--savetiddler\" command because it is being used directly as a title.\n\n```\ntiddlywiki --verbose --fetch raw-file \"https://tiddlywiki.com/favicon.ico\" \"[[Icon Tiddler]]\" --savetiddler \"Icon Tiddler\" output.ico\n```\n\n"},"$:/language/Help/help":{"title":"$:/language/Help/help","description":"Display help for TiddlyWiki commands","text":"Displays help text for a command:\n\n```\n--help [<command>]\n```\n\nIf the command name is omitted then a list of available commands is displayed.\n"},"$:/language/Help/import":{"title":"$:/language/Help/import","description":"Import tiddlers from a file","text":"Import tiddlers from TiddlyWiki (`.html`), `.tiddler`, `.tid`, `.json` or other local files. The deserializer must be explicitly specified, unlike the `load` command which infers the deserializer from the file extension.\n\n```\n--import <filepath> <deserializer> [<title>] [<encoding>]\n```\n\nThe deserializers in the core include:\n\n* application/javascript\n* application/json\n* application/x-tiddler\n* application/x-tiddler-html-div\n* application/x-tiddlers\n* text/html\n* text/plain\n\nThe title of the imported tiddler defaults to the filename.\n\nThe encoding defaults to \"utf8\", but can be \"base64\" for importing binary files.\n\nNote that TiddlyWiki will not import an older version of an already loaded plugin.\n"},"$:/language/Help/init":{"title":"$:/language/Help/init","description":"Initialise a new wiki folder","text":"Initialise an empty [[WikiFolder|WikiFolders]] with a copy of the specified edition.\n\n```\n--init <edition> [<edition> ...]\n```\n\nFor example:\n\n```\ntiddlywiki ./MyWikiFolder --init empty\n```\n\nNote:\n\n* The wiki folder directory will be created if necessary\n* The \"edition\" defaults to ''empty''\n* The init command will fail if the wiki folder is not empty\n* The init command removes any `includeWikis` definitions in the edition's `tiddlywiki.info` file\n* When multiple editions are specified, editions initialised later will overwrite any files shared with earlier editions (so, the final `tiddlywiki.info` file will be copied from the last edition)\n* `--editions` returns a list of available editions\n"},"$:/language/Help/listen":{"title":"$:/language/Help/listen","description":"Provides an HTTP server interface to TiddlyWiki","text":"Serves a wiki over HTTP.\n\nThe listen command uses NamedCommandParameters:\n\n```\n--listen [<name>=<value>]...\n```\n\nAll parameters are optional with safe defaults, and can be specified in any order. The recognised parameters are:\n\n* ''host'' - optional hostname to serve from (defaults to \"127.0.0.1\" aka \"localhost\")\n* ''path-prefix'' - optional prefix for paths\n* ''port'' - port number on which to listen; non-numeric values are interpreted as a system environment variable from which the port number is extracted (defaults to \"8080\")\n* ''credentials'' - pathname of credentials CSV file (relative to wiki folder)\n* ''anon-username'' - the username for signing edits for anonymous users\n* ''username'' - optional username for basic authentication\n* ''password'' - optional password for basic authentication\n* ''authenticated-user-header'' - optional name of request header to be used for trusted authentication.\n* ''readers'' - comma-separated list of principals allowed to read from this wiki\n* ''writers'' - comma-separated list of principals allowed to write to this wiki\n* ''csrf-disable'' - set to \"yes\" to disable CSRF checks (defaults to \"no\")\n* ''root-tiddler'' - the tiddler to serve at the root (defaults to \"$:/core/save/all\")\n* ''root-render-type'' - the content type to which the root tiddler should be rendered (defaults to \"text/plain\")\n* ''root-serve-type'' - the content type with which the root tiddler should be served (defaults to \"text/html\")\n* ''tls-cert'' - pathname of TLS certificate file (relative to wiki folder)\n* ''tls-key'' - pathname of TLS key file (relative to wiki folder)\n* ''debug-level'' - optional debug level; set to \"debug\" to view request details (defaults to \"none\")\n* ''gzip'' - set to \"yes\" to enable gzip compression for some http endpoints (defaults to \"no\")\n* ''use-browser-cache'' - set to \"yes\" to allow the browser to cache responses to save bandwidth (defaults to \"no\")\n\nFor information on opening up your instance to the entire local network, and possible security concerns, see the WebServer tiddler at TiddlyWiki.com.\n\n"},"$:/language/Help/load":{"title":"$:/language/Help/load","description":"Load tiddlers from a file","text":"Load tiddlers from TiddlyWiki (`.html`), `.tiddler`, `.tid`, `.json` or other local files. The processing applied to incoming files is determined by the file extension. Use the alternative `import` command if you need to specify the deserializer and encoding explicitly.\n\n```\n--load <filepath> [noerror]\n--load <dirpath> [noerror]\n```\n\nBy default, the load command raises an error if no tiddlers are found. The error can be suppressed by providing the optional \"noerror\" parameter.\n\nTo load tiddlers from an encrypted TiddlyWiki file you should first specify the password with the PasswordCommand. For example:\n\n```\ntiddlywiki ./MyWiki --password pa55w0rd --load my_encrypted_wiki.html\n```\n\nNote that TiddlyWiki will not load an older version of an already loaded plugin.\n"},"$:/language/Help/makelibrary":{"title":"$:/language/Help/makelibrary","description":"Construct library plugin required by upgrade process","text":"Constructs the `$:/UpgradeLibrary` tiddler for the upgrade process.\n\nThe upgrade library is formatted as an ordinary plugin tiddler with the plugin type `library`. It contains a copy of each of the plugins, themes and language packs available within the TiddlyWiki5 repository.\n\nThis command is intended for internal use; it is only relevant to users constructing a custom upgrade procedure.\n\n```\n--makelibrary <title>\n```\n\nThe title argument defaults to `$:/UpgradeLibrary`.\n"},"$:/language/Help/notfound":{"title":"$:/language/Help/notfound","text":"No such help item"},"$:/language/Help/output":{"title":"$:/language/Help/output","description":"Set the base output directory for subsequent commands","text":"Sets the base output directory for subsequent commands. The default output directory is the `output` subdirectory of the edition directory.\n\n```\n--output <pathname>\n```\n\nIf the specified pathname is relative then it is resolved relative to the current working directory. For example `--output .` sets the output directory to the current working directory.\n\n"},"$:/language/Help/password":{"title":"$:/language/Help/password","description":"Set a password for subsequent crypto operations","text":"Set a password for subsequent crypto operations\n\n```\n--password <password>\n```\n\n''Note'': This should not be used for serving TiddlyWiki with password protection. Instead, see the password option under the [[ServerCommand]].\n"},"$:/language/Help/render":{"title":"$:/language/Help/render","description":"Renders individual tiddlers to files","text":"Render individual tiddlers identified by a filter and save the results to the specified files.\n\nOptionally, the title of a template tiddler can be specified. In this case, instead of directly rendering each tiddler, the template tiddler is rendered with the \"currentTiddler\" variable set to the title of the tiddler that is being rendered.\n\nA name and value for an additional variable may optionally also be specified.\n\n```\n--render <tiddler-filter> [<filename-filter>] [<render-type>] [<template>] [ [<name>] [<value>] ]*\n```\n\n* ''tiddler-filter'': A filter identifying the tiddler(s) to be rendered\n* ''filename-filter'': Optional filter transforming tiddler titles into pathnames. If omitted, defaults to `[is[tiddler]addsuffix[.html]]`, which uses the unchanged tiddler title as the filename\n* ''render-type'': Optional render type: `text/html` (the default) returns the full HTML text and `text/plain` just returns the text content (ie it ignores HTML tags and other unprintable material)\n* ''template'': Optional template through which each tiddler is rendered\n* ''name'': Name of optional variables\n* ''value'': Value of optional variables\n\nBy default, the filename is resolved relative to the `output` subdirectory of the edition directory. The `--output` command can be used to direct output to a different directory.\n\nNotes:\n\n* The output directory is not cleared of any existing files\n* Any missing directories in the path to the filename are automatically created.\n* When referring to a tiddler with spaces in its title, take care to use both the quotes required by your shell and also TiddlyWiki's double square brackets: `--render \"[[Motovun Jack.jpg]]\"`\n* The filename filter is evaluated with the selected items being set to the title of the tiddler currently being rendered, allowing the title to be used as the basis for computing the filename. For example `[encodeuricomponent[]addprefix[static/]]` applies URI encoding to each title, and then adds the prefix `static/`\n* Multiple ''name''/''value'' pairs can be used to pass more than one variable\n* The `--render` command is a more flexible replacement for both the `--rendertiddler` and `--rendertiddlers` commands, which are deprecated\n\nExamples:\n\n* `--render '[!is[system]]' '[encodeuricomponent[]addprefix[tiddlers/]addsuffix[.html]]'` -- renders all non-system tiddlers as files in the subdirectory \"tiddlers\" with URL-encoded titles and the extension HTML\n* `--render '.' 'tiddlers.json' 'text/plain' '$:/core/templates/exporters/JsonFile' 'exportFilter' '[tag[HelloThere]]'` -- renders the tiddlers tagged \"HelloThere\" to a JSON file named \"tiddlers.json\"\n"},"$:/language/Help/rendertiddler":{"title":"$:/language/Help/rendertiddler","description":"Render an individual tiddler as a specified ContentType","text":"(Note: The `--rendertiddler` command is deprecated in favour of the new, more flexible `--render` command)\n\nRender an individual tiddler as a specified ContentType, defaulting to `text/html` and save it to the specified filename.\n\nOptionally the title of a template tiddler can be specified, in which case the template tiddler is rendered with the \"currentTiddler\" variable set to the tiddler that is being rendered (the first parameter value).\n\nA name and value for an additional variable may optionally also be specified.\n\n```\n--rendertiddler <title> <filename> [<type>] [<template>] [<name>] [<value>]\n```\n\nBy default, the filename is resolved relative to the `output` subdirectory of the edition directory. The `--output` command can be used to direct output to a different directory.\n\nAny missing directories in the path to the filename are automatically created.\n\nFor example, the following command saves all tiddlers matching the filter `[tag[done]]` to a JSON file titled `output.json` by employing the core template `$:/core/templates/exporters/JsonFile`.\n\n```\n--rendertiddler \"$:/core/templates/exporters/JsonFile\" output.json text/plain \"\" exportFilter \"[tag[done]]\"\n```\n"},"$:/language/Help/rendertiddlers":{"title":"$:/language/Help/rendertiddlers","description":"Render tiddlers matching a filter to a specified ContentType","text":"(Note: The `--rendertiddlers` command is deprecated in favour of the new, more flexible `--render` command)\n\nRender a set of tiddlers matching a filter to separate files of a specified ContentType (defaults to `text/html`) and extension (defaults to `.html`).\n\n```\n--rendertiddlers '<filter>' <template> <pathname> [<type>] [<extension>] [\"noclean\"]\n```\n\nFor example:\n\n```\n--rendertiddlers '[!is[system]]' $:/core/templates/static.tiddler.html ./static text/plain\n```\n\nBy default, the pathname is resolved relative to the `output` subdirectory of the edition directory. The `--output` command can be used to direct output to a different directory.\n\nAny files in the target directory are deleted unless the ''noclean'' flag is specified. The target directory is recursively created if it is missing.\n"},"$:/language/Help/save":{"title":"$:/language/Help/save","description":"Saves individual raw tiddlers to files","text":"Saves individual tiddlers identified by a filter in their raw text or binary format to the specified files.\n\n```\n--save <tiddler-filter> <filename-filter>\n```\n\n* ''tiddler-filter'': A filter identifying the tiddler(s) to be saved\n* ''filename-filter'': Optional filter transforming tiddler titles into pathnames. If omitted, defaults to `[is[tiddler]]`, which uses the unchanged tiddler title as the filename\n\nBy default, the filename is resolved relative to the `output` subdirectory of the edition directory. The `--output` command can be used to direct output to a different directory.\n\nNotes:\n\n* The output directory is not cleared of any existing files\n* Any missing directories in the path to the filename are automatically created.\n* When saving a tiddler with spaces in its title, take care to use both the quotes required by your shell and also TiddlyWiki's double square brackets: `--save \"[[Motovun Jack.jpg]]\"`\n* The filename filter is evaluated with the selected items being set to the title of the tiddler currently being saved, allowing the title to be used as the basis for computing the filename. For example `[encodeuricomponent[]addprefix[static/]]` applies URI encoding to each title, and then adds the prefix `static/`\n* The `--save` command is a more flexible replacement for both the `--savetiddler` and `--savetiddlers` commands, which are deprecated\n\nExamples:\n\n* `--save \"[!is[system]is[image]]\" \"[encodeuricomponent[]addprefix[tiddlers/]]\"` -- saves all non-system image tiddlers as files in the subdirectory \"tiddlers\" with URL-encoded titles\n"},"$:/language/Help/savetiddler":{"title":"$:/language/Help/savetiddler","description":"Saves a raw tiddler to a file","text":"(Note: The `--savetiddler` command is deprecated in favour of the new, more flexible `--save` command)\n\nSaves an individual tiddler in its raw text or binary format to the specified filename.\n\n```\n--savetiddler <title> <filename>\n```\n\nBy default, the filename is resolved relative to the `output` subdirectory of the edition directory. The `--output` command can be used to direct output to a different directory.\n\nAny missing directories in the path to the filename are automatically created.\n"},"$:/language/Help/savetiddlers":{"title":"$:/language/Help/savetiddlers","description":"Saves a group of raw tiddlers to a directory","text":"(Note: The `--savetiddlers` command is deprecated in favour of the new, more flexible `--save` command)\n\nSaves a group of tiddlers in their raw text or binary format to the specified directory.\n\n```\n--savetiddlers <filter> <pathname> [\"noclean\"]\n```\n\nBy default, the pathname is resolved relative to the `output` subdirectory of the edition directory. The `--output` command can be used to direct output to a different directory.\n\nThe output directory is cleared of existing files before saving the specified files. The deletion can be disabled by specifying the ''noclean'' flag.\n\nAny missing directories in the pathname are automatically created.\n"},"$:/language/Help/savewikifolder":{"title":"$:/language/Help/savewikifolder","description":"Saves a wiki to a new wiki folder","text":"<<.from-version \"5.1.20\">> Saves the current wiki as a wiki folder, including tiddlers, plugins and configuration:\n\n```\n--savewikifolder <wikifolderpath> [<filter>] [ [<name>=<value>] ]*\n```\n\n* The target wiki folder must be empty or non-existent\n* The filter specifies which tiddlers should be included. It is optional, defaulting to `[all[tiddlers]]`\n* Plugins from the official plugin library are replaced with references to those plugins in the `tiddlywiki.info` file\n* Custom plugins are unpacked into their own folder\n\nThe following options are supported:\n\n* ''filter'': a filter expression that defines the tiddlers to include in the output.\n* ''explodePlugins'': defaults to \"yes\"\n** ''yes'' will \"explode\" plugins into separate tiddler files and save them to the plugin directory within the wiki folder\n** ''no'' will suppress exploding plugins into their constituent tiddler files. It will save the plugin as a single JSON tiddler in the tiddlers folder\n\nNote that both ''explodePlugins'' options will produce wiki folders that build the exact same original wiki. The difference lies in how plugins are represented in the wiki folder.\n\nA common usage is to convert a TiddlyWiki HTML file into a wiki folder:\n\n```\ntiddlywiki --load ./mywiki.html --savewikifolder ./mywikifolder\n```\n\nSave the plugin to the tiddlers directory of the target wiki folder:\n\n```\ntiddlywiki --load ./mywiki.html --savewikifolder ./mywikifolder explodePlugins=no\n```\n"},"$:/language/Help/server":{"title":"$:/language/Help/server","description":"(deprecated: see 'listen' command) Provides an HTTP server interface to TiddlyWiki","text":"Legacy command to serve a wiki over HTTP.\n\n```\n--server <port> <root-tiddler> <root-render-type> <root-serve-type> <username> <password> <host> <path-prefix> <debug-level>\n```\n\nThe parameters are:\n\n* ''port'' - port number on which to listen; non-numeric values are interpreted as a system environment variable from which the port number is extracted (defaults to \"8080\")\n* ''root-tiddler'' - the tiddler to serve at the root (defaults to \"$:/core/save/all\")\n* ''root-render-type'' - the content type to which the root tiddler should be rendered (defaults to \"text/plain\")\n* ''root-serve-type'' - the content type with which the root tiddler should be served (defaults to \"text/html\")\n* ''username'' - the default username for signing edits\n* ''password'' - optional password for basic authentication\n* ''host'' - optional hostname to serve from (defaults to \"127.0.0.1\" aka \"localhost\")\n* ''path-prefix'' - optional prefix for paths\n* ''debug-level'' - optional debug level; set to \"debug\" to view request details (defaults to \"none\")\n\nIf the password parameter is specified then the browser will prompt the user for the username and password. Note that the password is transmitted in plain text so this implementation should only be used on a trusted network or over HTTPS.\n\nFor example:\n\n```\n--server 8080 $:/core/save/all text/plain text/html MyUserName passw0rd\n```\n\nThe username and password can be specified as empty strings if you need to set the hostname or pathprefix and don't want to require a password.\n\n\n```\n--server 8080 $:/core/save/all text/plain text/html \"\" \"\" 192.168.0.245\n```\n\nUsing an address like this exposes your system to the local network. For information on opening up your instance to the entire local network, and possible security concerns, see the WebServer tiddler at TiddlyWiki.com.\n\nTo run multiple TiddlyWiki servers at the same time you'll need to put each one on a different port. It can be useful to use an environment variable to pass the port number to the Node.js process. This example references an environment variable called \"MY_PORT_NUMBER\":\n\n```\n--server MY_PORT_NUMBER $:/core/save/all text/plain text/html MyUserName passw0rd\n```\n"},"$:/language/Help/setfield":{"title":"$:/language/Help/setfield","description":"Prepares external tiddlers for use","text":"//Note that this command is experimental and may change or be replaced before being finalised//\n\nSets the specified field of a group of tiddlers to the result of wikifying a template tiddler with the `currentTiddler` variable set to the tiddler.\n\n```\n--setfield <filter> <fieldname> <templatetitle> <rendertype>\n```\n\nThe parameters are:\n\n* ''filter'' - filter identifying the tiddlers to be affected\n* ''fieldname'' - the field to modify (defaults to \"text\")\n* ''templatetitle'' - the tiddler to wikify into the specified field. If blank or missing then the specified field is deleted\n* ''rendertype'' - the text type to render (defaults to \"text/plain\"; \"text/html\" can be used to include HTML tags)\n"},"$:/language/Help/unpackplugin":{"title":"$:/language/Help/unpackplugin","description":"Unpack the payload tiddlers from a plugin","text":"Extract the payload tiddlers from a plugin, creating them as ordinary tiddlers:\n\n```\n--unpackplugin <title>\n```\n"},"$:/language/Help/verbose":{"title":"$:/language/Help/verbose","description":"Triggers verbose output mode","text":"Triggers verbose output, useful for debugging\n\n```\n--verbose\n```\n"},"$:/language/Help/version":{"title":"$:/language/Help/version","description":"Displays the version number of TiddlyWiki","text":"Displays the version number of TiddlyWiki.\n\n```\n--version\n```\n"},"$:/language/Import/Editor/Import/Heading":{"title":"$:/language/Import/Editor/Import/Heading","text":"Import images and insert them into the editor."},"$:/language/Import/Imported/Hint":{"title":"$:/language/Import/Imported/Hint","text":"The following tiddlers were imported:"},"$:/language/Import/Listing/Cancel/Caption":{"title":"$:/language/Import/Listing/Cancel/Caption","text":"Cancel"},"$:/language/Import/Listing/Cancel/Warning":{"title":"$:/language/Import/Listing/Cancel/Warning","text":"Do you wish to cancel the import?"},"$:/language/Import/Listing/Hint":{"title":"$:/language/Import/Listing/Hint","text":"These tiddlers are ready to import:"},"$:/language/Import/Listing/Import/Caption":{"title":"$:/language/Import/Listing/Import/Caption","text":"Import"},"$:/language/Import/Listing/Select/Caption":{"title":"$:/language/Import/Listing/Select/Caption","text":"Select"},"$:/language/Import/Listing/Status/Caption":{"title":"$:/language/Import/Listing/Status/Caption","text":"Status"},"$:/language/Import/Listing/Title/Caption":{"title":"$:/language/Import/Listing/Title/Caption","text":"Title"},"$:/language/Import/Listing/Preview":{"title":"$:/language/Import/Listing/Preview","text":"Preview:"},"$:/language/Import/Listing/Preview/Text":{"title":"$:/language/Import/Listing/Preview/Text","text":"Text"},"$:/language/Import/Listing/Preview/TextRaw":{"title":"$:/language/Import/Listing/Preview/TextRaw","text":"Text (Raw)"},"$:/language/Import/Listing/Preview/Fields":{"title":"$:/language/Import/Listing/Preview/Fields","text":"Fields"},"$:/language/Import/Listing/Preview/Diff":{"title":"$:/language/Import/Listing/Preview/Diff","text":"Diff"},"$:/language/Import/Listing/Preview/DiffFields":{"title":"$:/language/Import/Listing/Preview/DiffFields","text":"Diff (Fields)"},"$:/language/Import/Listing/Rename/Tooltip":{"title":"$:/language/Import/Listing/Rename/Tooltip","text":"Rename tiddler before importing"},"$:/language/Import/Listing/Rename/Prompt":{"title":"$:/language/Import/Listing/Rename/Prompt","text":"Rename to:"},"$:/language/Import/Listing/Rename/ConfirmRename":{"title":"$:/language/Import/Listing/Rename/ConfirmRename","text":"Rename tiddler"},"$:/language/Import/Listing/Rename/CancelRename":{"title":"$:/language/Import/Listing/Rename/CancelRename","text":"Cancel"},"$:/language/Import/Listing/Rename/OverwriteWarning":{"title":"$:/language/Import/Listing/Rename/OverwriteWarning","text":"A tiddler with this title already exists."},"$:/language/Import/Upgrader/Plugins/Suppressed/Incompatible":{"title":"$:/language/Import/Upgrader/Plugins/Suppressed/Incompatible","text":"Blocked incompatible or obsolete plugin."},"$:/language/Import/Upgrader/Plugins/Suppressed/Version":{"title":"$:/language/Import/Upgrader/Plugins/Suppressed/Version","text":"Blocked plugin (due to incoming <<incoming>> not being newer than existing <<existing>>)."},"$:/language/Import/Upgrader/Plugins/Upgraded":{"title":"$:/language/Import/Upgrader/Plugins/Upgraded","text":"Upgraded plugin from <<incoming>> to <<upgraded>>."},"$:/language/Import/Upgrader/State/Suppressed":{"title":"$:/language/Import/Upgrader/State/Suppressed","text":"Blocked temporary state tiddler."},"$:/language/Import/Upgrader/System/Disabled":{"title":"$:/language/Import/Upgrader/System/Disabled","text":"Disabled system tiddler."},"$:/language/Import/Upgrader/System/Suppressed":{"title":"$:/language/Import/Upgrader/System/Suppressed","text":"Blocked system tiddler."},"$:/language/Import/Upgrader/System/Warning":{"title":"$:/language/Import/Upgrader/System/Warning","text":"Core module tiddler."},"$:/language/Import/Upgrader/System/Alert":{"title":"$:/language/Import/Upgrader/System/Alert","text":"You are about to import a tiddler that will overwrite a core module tiddler. This is not recommended as it may make the system unstable."},"$:/language/Import/Upgrader/ThemeTweaks/Created":{"title":"$:/language/Import/Upgrader/ThemeTweaks/Created","text":"Migrated theme tweak from <$text text=<<from>>/>."},"$:/language/Import/Upgrader/Tiddler/Disabled":{"title":"$:/language/Import/Upgrader/Tiddler/Disabled","text":"Disabled tiddler."},"$:/language/Import/Upgrader/Tiddler/Selected":{"title":"$:/language/Import/Upgrader/Tiddler/Selected","text":"Selected tiddler."},"$:/language/Import/Upgrader/Tiddler/Unselected":{"title":"$:/language/Import/Upgrader/Tiddler/Unselected","text":"Unselected tiddler."},"$:/language/AboveStory/ClassicPlugin/Warning":{"title":"$:/language/AboveStory/ClassicPlugin/Warning","text":"It looks like you are trying to load a plugin designed for ~TiddlyWiki Classic. Please note that [[these plugins do not work with TiddlyWiki version 5.x.x|https://tiddlywiki.com/#TiddlyWikiClassic]]. ~TiddlyWiki Classic plugins detected:"},"$:/language/BinaryWarning/Prompt":{"title":"$:/language/BinaryWarning/Prompt","text":"This tiddler contains binary data"},"$:/language/ClassicWarning/Hint":{"title":"$:/language/ClassicWarning/Hint","text":"This tiddler is written in TiddlyWiki Classic wiki text format, which is not fully compatible with TiddlyWiki version 5. See https://tiddlywiki.com/static/Upgrading.html for more details."},"$:/language/ClassicWarning/Upgrade/Caption":{"title":"$:/language/ClassicWarning/Upgrade/Caption","text":"upgrade"},"$:/language/CloseAll/Button":{"title":"$:/language/CloseAll/Button","text":"close all"},"$:/language/ColourPicker/Recent":{"title":"$:/language/ColourPicker/Recent","text":"Recent:"},"$:/language/ConfirmCancelTiddler":{"title":"$:/language/ConfirmCancelTiddler","text":"Do you wish to discard changes to the tiddler \"<$text text=<<title>>/>\"?"},"$:/language/ConfirmDeleteTiddler":{"title":"$:/language/ConfirmDeleteTiddler","text":"Do you wish to delete the tiddler \"<$text text=<<title>>/>\"?"},"$:/language/ConfirmDeleteTiddlers":{"title":"$:/language/ConfirmDeleteTiddlers","text":"Are you sure you wish to delete <<resultCount>> tiddler(s)?"},"$:/language/ConfirmOverwriteTiddler":{"title":"$:/language/ConfirmOverwriteTiddler","text":"Do you wish to overwrite the tiddler \"<$text text=<<title>>/>\"?"},"$:/language/ConfirmEditShadowTiddler":{"title":"$:/language/ConfirmEditShadowTiddler","text":"You are about to edit a ShadowTiddler. Any changes will override the default system making future upgrades non-trivial. Are you sure you want to edit \"<$text text=<<title>>/>\"?"},"$:/language/ConfirmAction":{"title":"$:/language/ConfirmAction","text":"Do you wish to proceed?"},"$:/language/Count":{"title":"$:/language/Count","text":"count"},"$:/language/DefaultNewTiddlerTitle":{"title":"$:/language/DefaultNewTiddlerTitle","text":"New Tiddler"},"$:/language/Diffs/CountMessage":{"title":"$:/language/Diffs/CountMessage","text":"<<diff-count>> differences"},"$:/language/DropMessage":{"title":"$:/language/DropMessage","text":"Drop now (or use the 'Escape' key to cancel)"},"$:/language/Encryption/Cancel":{"title":"$:/language/Encryption/Cancel","text":"Cancel"},"$:/language/Encryption/ConfirmClearPassword":{"title":"$:/language/Encryption/ConfirmClearPassword","text":"Do you wish to clear the password? This will remove the encryption applied when saving this wiki"},"$:/language/Encryption/PromptSetPassword":{"title":"$:/language/Encryption/PromptSetPassword","text":"Set a new password for this TiddlyWiki"},"$:/language/Encryption/Username":{"title":"$:/language/Encryption/Username","text":"Username"},"$:/language/Encryption/Password":{"title":"$:/language/Encryption/Password","text":"Password"},"$:/language/Encryption/RepeatPassword":{"title":"$:/language/Encryption/RepeatPassword","text":"Repeat password"},"$:/language/Encryption/PasswordNoMatch":{"title":"$:/language/Encryption/PasswordNoMatch","text":"Passwords do not match"},"$:/language/Encryption/SetPassword":{"title":"$:/language/Encryption/SetPassword","text":"Set password"},"$:/language/Error/Caption":{"title":"$:/language/Error/Caption","text":"Error"},"$:/language/Error/DeserializeOperator/MissingOperand":{"title":"$:/language/Error/DeserializeOperator/MissingOperand","text":"Filter Error: Missing operand for 'deserialize' operator"},"$:/language/Error/DeserializeOperator/UnknownDeserializer":{"title":"$:/language/Error/DeserializeOperator/UnknownDeserializer","text":"Filter Error: Unknown deserializer provided as operand for the 'deserialize' operator"},"$:/language/Error/Filter":{"title":"$:/language/Error/Filter","text":"Filter error"},"$:/language/Error/FilterSyntax":{"title":"$:/language/Error/FilterSyntax","text":"Syntax error in filter expression"},"$:/language/Error/FilterRunPrefix":{"title":"$:/language/Error/FilterRunPrefix","text":"Filter Error: Unknown prefix for filter run"},"$:/language/Error/IsFilterOperator":{"title":"$:/language/Error/IsFilterOperator","text":"Filter Error: Unknown parameter for the 'is' filter operator"},"$:/language/Error/FormatFilterOperator":{"title":"$:/language/Error/FormatFilterOperator","text":"Filter Error: Unknown suffix for the 'format' filter operator"},"$:/language/Error/LoadingPluginLibrary":{"title":"$:/language/Error/LoadingPluginLibrary","text":"Error loading plugin library"},"$:/language/Error/NetworkErrorAlert":{"title":"$:/language/Error/NetworkErrorAlert","text":"`<h2>''Network Error''</h2>It looks like the connection to the server has been lost. This may indicate a problem with your network connection. Please attempt to restore network connectivity before continuing.<br><br>''Any unsaved changes will be automatically synchronised when connectivity is restored''.`"},"$:/language/Error/PutEditConflict":{"title":"$:/language/Error/PutEditConflict","text":"File changed on server"},"$:/language/Error/PutForbidden":{"title":"$:/language/Error/PutForbidden","text":"Permission denied"},"$:/language/Error/PutUnauthorized":{"title":"$:/language/Error/PutUnauthorized","text":"Authentication required"},"$:/language/Error/RecursiveTransclusion":{"title":"$:/language/Error/RecursiveTransclusion","text":"Recursive transclusion error in transclude widget"},"$:/language/Error/RetrievingSkinny":{"title":"$:/language/Error/RetrievingSkinny","text":"Error retrieving skinny tiddler list"},"$:/language/Error/SavingToTWEdit":{"title":"$:/language/Error/SavingToTWEdit","text":"Error saving to TWEdit"},"$:/language/Error/WhileSaving":{"title":"$:/language/Error/WhileSaving","text":"Error while saving"},"$:/language/Error/XMLHttpRequest":{"title":"$:/language/Error/XMLHttpRequest","text":"XMLHttpRequest error code"},"$:/language/Error/ZoominTextNode":{"title":"$:/language/Error/ZoominTextNode","text":"Story View Error: It appears you tried to interact with a tiddler that displays in a custom container. This is most likely caused by using `$:/tags/StoryTiddlerTemplateFilter` with a template that contains text or whitespace at the start. Please use the pragma `\\whitespace trim` and ensure the whole contents of the tiddler is wrapped in a single HTML element. The text that caused this issue:"},"$:/language/InternalJavaScriptError/Title":{"title":"$:/language/InternalJavaScriptError/Title","text":"Internal JavaScript Error"},"$:/language/InternalJavaScriptError/Hint":{"title":"$:/language/InternalJavaScriptError/Hint","text":"Well, this is embarrassing. It is recommended that you restart TiddlyWiki by refreshing your browser"},"$:/language/LayoutSwitcher/Description":{"title":"$:/language/LayoutSwitcher/Description","text":"Open the layout switcher"},"$:/language/LazyLoadingWarning":{"title":"$:/language/LazyLoadingWarning","text":"<p>Trying to load external content from ''<$text text={{!!_canonical_uri}}/>''</p><p>If this message doesn't disappear, either the tiddler content type doesn't match the type of the external content, or you may be using a browser that doesn't support external content for wikis loaded as standalone files. See https://tiddlywiki.com/#ExternalText</p>"},"$:/language/LoginToTiddlySpace":{"title":"$:/language/LoginToTiddlySpace","text":"Login to TiddlySpace"},"$:/language/Manager/Controls/FilterByTag/None":{"title":"$:/language/Manager/Controls/FilterByTag/None","text":"(none)"},"$:/language/Manager/Controls/FilterByTag/Prompt":{"title":"$:/language/Manager/Controls/FilterByTag/Prompt","text":"Filter by tag:"},"$:/language/Manager/Controls/Order/Prompt":{"title":"$:/language/Manager/Controls/Order/Prompt","text":"Reverse order"},"$:/language/Manager/Controls/Search/Placeholder":{"title":"$:/language/Manager/Controls/Search/Placeholder","text":"Search"},"$:/language/Manager/Controls/Search/Prompt":{"title":"$:/language/Manager/Controls/Search/Prompt","text":"Search:"},"$:/language/Manager/Controls/Show/Option/Tags":{"title":"$:/language/Manager/Controls/Show/Option/Tags","text":"tags"},"$:/language/Manager/Controls/Show/Option/Tiddlers":{"title":"$:/language/Manager/Controls/Show/Option/Tiddlers","text":"tiddlers"},"$:/language/Manager/Controls/Show/Prompt":{"title":"$:/language/Manager/Controls/Show/Prompt","text":"Show:"},"$:/language/Manager/Controls/Sort/Prompt":{"title":"$:/language/Manager/Controls/Sort/Prompt","text":"Sort by:"},"$:/language/Manager/Item/Colour":{"title":"$:/language/Manager/Item/Colour","text":"Colour"},"$:/language/Manager/Item/Fields":{"title":"$:/language/Manager/Item/Fields","text":"Fields"},"$:/language/Manager/Item/Icon/None":{"title":"$:/language/Manager/Item/Icon/None","text":"(none)"},"$:/language/Manager/Item/Icon":{"title":"$:/language/Manager/Item/Icon","text":"Icon"},"$:/language/Manager/Item/RawText":{"title":"$:/language/Manager/Item/RawText","text":"Raw text"},"$:/language/Manager/Item/Tags":{"title":"$:/language/Manager/Item/Tags","text":"Tags"},"$:/language/Manager/Item/Tools":{"title":"$:/language/Manager/Item/Tools","text":"Tools"},"$:/language/Manager/Item/WikifiedText":{"title":"$:/language/Manager/Item/WikifiedText","text":"Wikified text"},"$:/language/MissingTiddler/Hint":{"title":"$:/language/MissingTiddler/Hint","text":"Missing tiddler \"<$text text=<<currentTiddler>>/>\" -- click {{||$:/core/ui/Buttons/edit}} to create"},"$:/language/No":{"title":"$:/language/No","text":"No"},"$:/language/OfficialPluginLibrary":{"title":"$:/language/OfficialPluginLibrary","text":"Official ~TiddlyWiki Plugin Library"},"$:/language/OfficialPluginLibrary/Hint":{"title":"$:/language/OfficialPluginLibrary/Hint","text":"The official ~TiddlyWiki plugin library at tiddlywiki.com. Plugins, themes and language packs are maintained by the core team."},"$:/language/PageTemplate/Description":{"title":"$:/language/PageTemplate/Description","text":"the default ~TiddlyWiki layout"},"$:/language/PageTemplate/Name":{"title":"$:/language/PageTemplate/Name","text":"Standard Layout"},"$:/language/PluginReloadWarning":{"title":"$:/language/PluginReloadWarning","text":"Please save {{$:/core/ui/Buttons/save-wiki}} and reload {{$:/core/ui/Buttons/refresh}} to allow changes to ~JavaScript plugins to take effect"},"$:/language/RecentChanges/DateFormat":{"title":"$:/language/RecentChanges/DateFormat","text":"DDth MMM YYYY"},"$:/language/Shortcuts/Input/AdvancedSearch/Hint":{"title":"$:/language/Shortcuts/Input/AdvancedSearch/Hint","text":"Open the ~AdvancedSearch panel from within the sidebar search field"},"$:/language/Shortcuts/Input/Accept/Hint":{"title":"$:/language/Shortcuts/Input/Accept/Hint","text":"Accept the selected item"},"$:/language/Shortcuts/Input/AcceptVariant/Hint":{"title":"$:/language/Shortcuts/Input/AcceptVariant/Hint","text":"Accept the selected item (variant)"},"$:/language/Shortcuts/Input/Cancel/Hint":{"title":"$:/language/Shortcuts/Input/Cancel/Hint","text":"Clear the input field"},"$:/language/Shortcuts/Input/Down/Hint":{"title":"$:/language/Shortcuts/Input/Down/Hint","text":"Select the next item"},"$:/language/Shortcuts/Input/Tab-Left/Hint":{"title":"$:/language/Shortcuts/Input/Tab-Left/Hint","text":"Select the previous Tab"},"$:/language/Shortcuts/Input/Tab-Right/Hint":{"title":"$:/language/Shortcuts/Input/Tab-Right/Hint","text":"Select the next Tab"},"$:/language/Shortcuts/Input/Up/Hint":{"title":"$:/language/Shortcuts/Input/Up/Hint","text":"Select the previous item"},"$:/language/Shortcuts/SidebarLayout/Hint":{"title":"$:/language/Shortcuts/SidebarLayout/Hint","text":"Change the sidebar layout"},"$:/language/Switcher/Subtitle/theme":{"title":"$:/language/Switcher/Subtitle/theme","text":"Switch Theme"},"$:/language/Switcher/Subtitle/layout":{"title":"$:/language/Switcher/Subtitle/layout","text":"Switch Layout"},"$:/language/Switcher/Subtitle/language":{"title":"$:/language/Switcher/Subtitle/language","text":"Switch Language"},"$:/language/Switcher/Subtitle/palette":{"title":"$:/language/Switcher/Subtitle/palette","text":"Switch Palette"},"$:/language/SystemTiddler/Tooltip":{"title":"$:/language/SystemTiddler/Tooltip","text":"This is a system tiddler"},"$:/language/SystemTiddlers/Include/Prompt":{"title":"$:/language/SystemTiddlers/Include/Prompt","text":"Include system tiddlers"},"$:/language/TagManager/Colour/Heading":{"title":"$:/language/TagManager/Colour/Heading","text":"Colour"},"$:/language/TagManager/Count/Heading":{"title":"$:/language/TagManager/Count/Heading","text":"Count"},"$:/language/TagManager/Icon/Heading":{"title":"$:/language/TagManager/Icon/Heading","text":"Icon"},"$:/language/TagManager/Icons/None":{"title":"$:/language/TagManager/Icons/None","text":"None"},"$:/language/TagManager/Info/Heading":{"title":"$:/language/TagManager/Info/Heading","text":"Info"},"$:/language/TagManager/Tag/Heading":{"title":"$:/language/TagManager/Tag/Heading","text":"Tag"},"$:/language/Tiddler/DateFormat":{"title":"$:/language/Tiddler/DateFormat","text":"DDth MMM YYYY at hh12:0mmam"},"$:/language/UnsavedChangesWarning":{"title":"$:/language/UnsavedChangesWarning","text":"You have unsaved changes in TiddlyWiki"},"$:/language/Yes":{"title":"$:/language/Yes","text":"Yes"},"$:/language/Modals/Download":{"title":"$:/language/Modals/Download","subtitle":"Download changes","footer":"<$button message=\"tm-close-tiddler\">Close</$button>","help":"https://tiddlywiki.com/static/DownloadingChanges.html","text":"Your browser only supports manual saving.\n\nTo save your modified wiki, right click on the download link below and select \"Download file\" or \"Save file\", and then choose the folder and filename.\n\n//You can marginally speed things up by clicking the link with the control key (Windows) or the options/alt key (Mac OS X). You will not be prompted for the folder or filename, but your browser is likely to give it an unrecognisable name -- you may need to rename the file to include an `.html` extension before you can do anything useful with it.//\n\nOn smartphones that do not allow files to be downloaded you can instead bookmark the link, and then sync your bookmarks to a desktop computer from where the wiki can be saved normally.\n"},"$:/config/NewJournal/Title":{"title":"$:/config/NewJournal/Title","text":"DDth MMM YYYY"},"$:/config/NewJournal/Text":{"title":"$:/config/NewJournal/Text","text":""},"$:/config/NewJournal/Tags":{"title":"$:/config/NewJournal/Tags","text":"Journal\n"},"$:/language/Notifications/Save/Done":{"title":"$:/language/Notifications/Save/Done","text":"Saved wiki"},"$:/language/Notifications/Save/Starting":{"title":"$:/language/Notifications/Save/Starting","text":"Starting to save wiki"},"$:/language/Notifications/CopiedToClipboard/Succeeded":{"title":"$:/language/Notifications/CopiedToClipboard/Succeeded","text":"Copied to clipboard!"},"$:/language/Notifications/CopiedToClipboard/Failed":{"title":"$:/language/Notifications/CopiedToClipboard/Failed","text":"Failed to copy to clipboard!"},"$:/language/Search/DefaultResults/Caption":{"title":"$:/language/Search/DefaultResults/Caption","text":"List"},"$:/language/Search/Filter/Caption":{"title":"$:/language/Search/Filter/Caption","text":"Filter"},"$:/language/Search/Filter/Hint":{"title":"$:/language/Search/Filter/Hint","text":"Search via a [[filter expression|https://tiddlywiki.com/static/Filters.html]]"},"$:/language/Search/Filter/Matches":{"title":"$:/language/Search/Filter/Matches","text":"//<small><<resultCount>> matches</small>//"},"$:/language/Search/Matches":{"title":"$:/language/Search/Matches","text":"//<small><<resultCount>> matches</small>//"},"$:/language/Search/Matches/All":{"title":"$:/language/Search/Matches/All","text":"All matches:"},"$:/language/Search/Matches/NoMatch":{"title":"$:/language/Search/Matches/NoMatch","text":"//No match//"},"$:/language/Search/Matches/NoResult":{"title":"$:/language/Search/Matches/NoResult","text":"//No search result//"},"$:/language/Search/Matches/Title":{"title":"$:/language/Search/Matches/Title","text":"Title matches:"},"$:/language/Search/Search":{"title":"$:/language/Search/Search","text":"Search"},"$:/language/Search/Search/TooShort":{"title":"$:/language/Search/Search/TooShort","text":"Search text too short"},"$:/language/Search/Shadows/Caption":{"title":"$:/language/Search/Shadows/Caption","text":"Shadows"},"$:/language/Search/Shadows/Hint":{"title":"$:/language/Search/Shadows/Hint","text":"Search for shadow tiddlers"},"$:/language/Search/Shadows/Matches":{"title":"$:/language/Search/Shadows/Matches","text":"//<small><<resultCount>> matches</small>//"},"$:/language/Search/Standard/Caption":{"title":"$:/language/Search/Standard/Caption","text":"Standard"},"$:/language/Search/Standard/Hint":{"title":"$:/language/Search/Standard/Hint","text":"Search for standard tiddlers"},"$:/language/Search/Standard/Matches":{"title":"$:/language/Search/Standard/Matches","text":"//<small><<resultCount>> matches</small>//"},"$:/language/Search/System/Caption":{"title":"$:/language/Search/System/Caption","text":"System"},"$:/language/Search/System/Hint":{"title":"$:/language/Search/System/Hint","text":"Search for system tiddlers"},"$:/language/Search/System/Matches":{"title":"$:/language/Search/System/Matches","text":"//<small><<resultCount>> matches</small>//"},"$:/language/SideBar/Caption":{"title":"$:/language/SideBar/Caption","text":"Sidebar"},"$:/language/SideBar/All/Caption":{"title":"$:/language/SideBar/All/Caption","text":"All"},"$:/language/SideBar/Contents/Caption":{"title":"$:/language/SideBar/Contents/Caption","text":"Contents"},"$:/language/SideBar/Drafts/Caption":{"title":"$:/language/SideBar/Drafts/Caption","text":"Drafts"},"$:/language/SideBar/Explorer/Caption":{"title":"$:/language/SideBar/Explorer/Caption","text":"Explorer"},"$:/language/SideBar/Missing/Caption":{"title":"$:/language/SideBar/Missing/Caption","text":"Missing"},"$:/language/SideBar/More/Caption":{"title":"$:/language/SideBar/More/Caption","text":"More"},"$:/language/SideBar/Open/Caption":{"title":"$:/language/SideBar/Open/Caption","text":"Open"},"$:/language/SideBar/Orphans/Caption":{"title":"$:/language/SideBar/Orphans/Caption","text":"Orphans"},"$:/language/SideBar/Recent/Caption":{"title":"$:/language/SideBar/Recent/Caption","text":"Recent"},"$:/language/SideBar/Shadows/Caption":{"title":"$:/language/SideBar/Shadows/Caption","text":"Shadows"},"$:/language/SideBar/System/Caption":{"title":"$:/language/SideBar/System/Caption","text":"System"},"$:/language/SideBar/Tags/Caption":{"title":"$:/language/SideBar/Tags/Caption","text":"Tags"},"$:/language/SideBar/Tags/Untagged/Caption":{"title":"$:/language/SideBar/Tags/Untagged/Caption","text":"untagged"},"$:/language/SideBar/Tools/Caption":{"title":"$:/language/SideBar/Tools/Caption","text":"Tools"},"$:/language/SideBar/Types/Caption":{"title":"$:/language/SideBar/Types/Caption","text":"Types"},"$:/SiteSubtitle":{"title":"$:/SiteSubtitle","text":"a non-linear personal web notebook"},"$:/SiteTitle":{"title":"$:/SiteTitle","text":"My TiddlyWiki"},"$:/language/Snippets/FunctionDefinition":{"title":"$:/language/Snippets/FunctionDefinition","tags":"$:/tags/TextEditor/Snippet","caption":"Function definition","text":"\\function f.name(param1,param2:\"default value\") [<param1>!is[blank]else<param2>]\n\n<<f.name>>\n"},"$:/language/Snippets/ListByTag":{"title":"$:/language/Snippets/ListByTag","tags":"$:/tags/TextEditor/Snippet","caption":"List of tiddlers by tag","text":"<<list-links \"[tag[task]sort[title]]\">>\n"},"$:/language/Snippets/MacroDefinition":{"title":"$:/language/Snippets/MacroDefinition","tags":"$:/tags/TextEditor/Snippet","caption":"Macro definition","text":"\\define macroName(param1:\"default value\",param2)\nText of the macro\n\\end\n"},"$:/language/Snippets/ProcedureDefinition":{"title":"$:/language/Snippets/ProcedureDefinition","tags":"$:/tags/TextEditor/Snippet","caption":"Procedure definition","text":"\\procedure procName(param1:\"default value\",param2)\nYour text comes here.\n\\end\n"},"$:/language/Snippets/Table4x3":{"title":"$:/language/Snippets/Table4x3","tags":"$:/tags/TextEditor/Snippet","caption":"Table with 4 columns by 3 rows","text":"|! |!Alpha |!Beta |!Gamma |!Delta |\n|!One | | | | |\n|!Two | | | | |\n|!Three | | | | |\n"},"$:/language/Snippets/TableOfContents":{"title":"$:/language/Snippets/TableOfContents","tags":"$:/tags/TextEditor/Snippet","caption":"Table of Contents","text":"<div class=\"tc-table-of-contents\">\n\n<<toc-selective-expandable 'TableOfContents'>>\n\n</div>"},"$:/language/ThemeTweaks/ThemeTweaks":{"title":"$:/language/ThemeTweaks/ThemeTweaks","text":"Theme Tweaks"},"$:/language/ThemeTweaks/ThemeTweaks/Hint":{"title":"$:/language/ThemeTweaks/ThemeTweaks/Hint","text":"You can tweak certain aspects of the ''Vanilla'' theme."},"$:/language/ThemeTweaks/Options":{"title":"$:/language/ThemeTweaks/Options","text":"Options"},"$:/language/ThemeTweaks/Options/SidebarLayout":{"title":"$:/language/ThemeTweaks/Options/SidebarLayout","text":"Sidebar layout"},"$:/language/ThemeTweaks/Options/SidebarLayout/Fixed-Fluid":{"title":"$:/language/ThemeTweaks/Options/SidebarLayout/Fixed-Fluid","text":"Fixed story, fluid sidebar"},"$:/language/ThemeTweaks/Options/SidebarLayout/Fluid-Fixed":{"title":"$:/language/ThemeTweaks/Options/SidebarLayout/Fluid-Fixed","text":"Fluid story, fixed sidebar"},"$:/language/ThemeTweaks/Options/StickyTitles":{"title":"$:/language/ThemeTweaks/Options/StickyTitles","text":"Sticky titles"},"$:/language/ThemeTweaks/Options/StickyTitles/Hint":{"title":"$:/language/ThemeTweaks/Options/StickyTitles/Hint","text":"Causes tiddler titles to \"stick\" to the top of the browser window"},"$:/language/ThemeTweaks/Options/CodeWrapping":{"title":"$:/language/ThemeTweaks/Options/CodeWrapping","text":"Wrap long lines in code blocks"},"$:/language/ThemeTweaks/Settings":{"title":"$:/language/ThemeTweaks/Settings","text":"Settings"},"$:/language/ThemeTweaks/Settings/FontFamily":{"title":"$:/language/ThemeTweaks/Settings/FontFamily","text":"Font family"},"$:/language/ThemeTweaks/Settings/CodeFontFamily":{"title":"$:/language/ThemeTweaks/Settings/CodeFontFamily","text":"Code font family"},"$:/language/ThemeTweaks/Settings/EditorFontFamily":{"title":"$:/language/ThemeTweaks/Settings/EditorFontFamily","text":"Editor font family"},"$:/language/ThemeTweaks/Settings/BackgroundImage":{"title":"$:/language/ThemeTweaks/Settings/BackgroundImage","text":"Page background image"},"$:/language/ThemeTweaks/Settings/BackgroundImageAttachment":{"title":"$:/language/ThemeTweaks/Settings/BackgroundImageAttachment","text":"Page background image attachment"},"$:/language/ThemeTweaks/Settings/BackgroundImageAttachment/Scroll":{"title":"$:/language/ThemeTweaks/Settings/BackgroundImageAttachment/Scroll","text":"Scroll with tiddlers"},"$:/language/ThemeTweaks/Settings/BackgroundImageAttachment/Fixed":{"title":"$:/language/ThemeTweaks/Settings/BackgroundImageAttachment/Fixed","text":"Fixed to window"},"$:/language/ThemeTweaks/Settings/BackgroundImageSize":{"title":"$:/language/ThemeTweaks/Settings/BackgroundImageSize","text":"Page background image size"},"$:/language/ThemeTweaks/Settings/BackgroundImageSize/Auto":{"title":"$:/language/ThemeTweaks/Settings/BackgroundImageSize/Auto","text":"Auto"},"$:/language/ThemeTweaks/Settings/BackgroundImageSize/Cover":{"title":"$:/language/ThemeTweaks/Settings/BackgroundImageSize/Cover","text":"Cover"},"$:/language/ThemeTweaks/Settings/BackgroundImageSize/Contain":{"title":"$:/language/ThemeTweaks/Settings/BackgroundImageSize/Contain","text":"Contain"},"$:/language/ThemeTweaks/Metrics":{"title":"$:/language/ThemeTweaks/Metrics","text":"Sizes"},"$:/language/ThemeTweaks/Metrics/FontSize":{"title":"$:/language/ThemeTweaks/Metrics/FontSize","text":"Font size"},"$:/language/ThemeTweaks/Metrics/LineHeight":{"title":"$:/language/ThemeTweaks/Metrics/LineHeight","text":"Line height"},"$:/language/ThemeTweaks/Metrics/BodyFontSize":{"title":"$:/language/ThemeTweaks/Metrics/BodyFontSize","text":"Font size for tiddler body"},"$:/language/ThemeTweaks/Metrics/BodyLineHeight":{"title":"$:/language/ThemeTweaks/Metrics/BodyLineHeight","text":"Line height for tiddler body"},"$:/language/ThemeTweaks/Metrics/StoryLeft":{"title":"$:/language/ThemeTweaks/Metrics/StoryLeft","text":"Story left position"},"$:/language/ThemeTweaks/Metrics/StoryLeft/Hint":{"title":"$:/language/ThemeTweaks/Metrics/StoryLeft/Hint","text":"how far the left margin of the story river<br>(tiddler area) is from the left of the page"},"$:/language/ThemeTweaks/Metrics/StoryTop":{"title":"$:/language/ThemeTweaks/Metrics/StoryTop","text":"Story top position"},"$:/language/ThemeTweaks/Metrics/StoryTop/Hint":{"title":"$:/language/ThemeTweaks/Metrics/StoryTop/Hint","text":"how far the top margin of the story river<br>is from the top of the page"},"$:/language/ThemeTweaks/Metrics/StoryRight":{"title":"$:/language/ThemeTweaks/Metrics/StoryRight","text":"Story right"},"$:/language/ThemeTweaks/Metrics/StoryRight/Hint":{"title":"$:/language/ThemeTweaks/Metrics/StoryRight/Hint","text":"how far the left margin of the sidebar <br>is from the left of the page"},"$:/language/ThemeTweaks/Metrics/StoryWidth":{"title":"$:/language/ThemeTweaks/Metrics/StoryWidth","text":"Story width"},"$:/language/ThemeTweaks/Metrics/StoryWidth/Hint":{"title":"$:/language/ThemeTweaks/Metrics/StoryWidth/Hint","text":"the overall width of the story river"},"$:/language/ThemeTweaks/Metrics/TiddlerWidth":{"title":"$:/language/ThemeTweaks/Metrics/TiddlerWidth","text":"Tiddler width"},"$:/language/ThemeTweaks/Metrics/TiddlerWidth/Hint":{"title":"$:/language/ThemeTweaks/Metrics/TiddlerWidth/Hint","text":"within the story river"},"$:/language/ThemeTweaks/Metrics/SidebarBreakpoint":{"title":"$:/language/ThemeTweaks/Metrics/SidebarBreakpoint","text":"Sidebar breakpoint"},"$:/language/ThemeTweaks/Metrics/SidebarBreakpoint/Hint":{"title":"$:/language/ThemeTweaks/Metrics/SidebarBreakpoint/Hint","text":"the minimum page width at which the story<br>river and sidebar will appear side by side"},"$:/language/ThemeTweaks/Metrics/SidebarWidth":{"title":"$:/language/ThemeTweaks/Metrics/SidebarWidth","text":"Sidebar width"},"$:/language/ThemeTweaks/Metrics/SidebarWidth/Hint":{"title":"$:/language/ThemeTweaks/Metrics/SidebarWidth/Hint","text":"the width of the sidebar in fluid-fixed layout"},"$:/language/TiddlerInfo/Advanced/Caption":{"title":"$:/language/TiddlerInfo/Advanced/Caption","text":"Advanced"},"$:/language/TiddlerInfo/Advanced/PluginInfo/Empty/Hint":{"title":"$:/language/TiddlerInfo/Advanced/PluginInfo/Empty/Hint","text":"none"},"$:/language/TiddlerInfo/Advanced/PluginInfo/Heading":{"title":"$:/language/TiddlerInfo/Advanced/PluginInfo/Heading","text":"Plugin Details"},"$:/language/TiddlerInfo/Advanced/PluginInfo/Hint":{"title":"$:/language/TiddlerInfo/Advanced/PluginInfo/Hint","text":"This plugin contains the following shadow tiddlers:"},"$:/language/TiddlerInfo/Advanced/ShadowInfo/Heading":{"title":"$:/language/TiddlerInfo/Advanced/ShadowInfo/Heading","text":"Shadow Status"},"$:/language/TiddlerInfo/Advanced/ShadowInfo/NotShadow/Hint":{"title":"$:/language/TiddlerInfo/Advanced/ShadowInfo/NotShadow/Hint","text":"The tiddler <$link to=<<infoTiddler>>><$text text=<<infoTiddler>>/></$link> is not a shadow tiddler"},"$:/language/TiddlerInfo/Advanced/ShadowInfo/Shadow/Hint":{"title":"$:/language/TiddlerInfo/Advanced/ShadowInfo/Shadow/Hint","text":"The tiddler <$link to=<<infoTiddler>>><$text text=<<infoTiddler>>/></$link> is a shadow tiddler"},"$:/language/TiddlerInfo/Advanced/ShadowInfo/Shadow/Source":{"title":"$:/language/TiddlerInfo/Advanced/ShadowInfo/Shadow/Source","text":"It is defined in the plugin <$link to=<<pluginTiddler>>><$text text=<<pluginTiddler>>/></$link>"},"$:/language/TiddlerInfo/Advanced/ShadowInfo/OverriddenShadow/Hint":{"title":"$:/language/TiddlerInfo/Advanced/ShadowInfo/OverriddenShadow/Hint","text":"It is overridden by an ordinary tiddler"},"$:/language/TiddlerInfo/Fields/Caption":{"title":"$:/language/TiddlerInfo/Fields/Caption","text":"Fields"},"$:/language/TiddlerInfo/List/Caption":{"title":"$:/language/TiddlerInfo/List/Caption","text":"List"},"$:/language/TiddlerInfo/List/Empty":{"title":"$:/language/TiddlerInfo/List/Empty","text":"This tiddler does not have a list"},"$:/language/TiddlerInfo/Listed/Caption":{"title":"$:/language/TiddlerInfo/Listed/Caption","text":"Listed"},"$:/language/TiddlerInfo/Listed/Empty":{"title":"$:/language/TiddlerInfo/Listed/Empty","text":"This tiddler is not listed by any others"},"$:/language/TiddlerInfo/References/Caption":{"title":"$:/language/TiddlerInfo/References/Caption","text":"Backlinks"},"$:/language/TiddlerInfo/References/Empty":{"title":"$:/language/TiddlerInfo/References/Empty","text":"No tiddlers link to this one"},"$:/language/TiddlerInfo/Tagging/Caption":{"title":"$:/language/TiddlerInfo/Tagging/Caption","text":"Tagging"},"$:/language/TiddlerInfo/Tagging/Empty":{"title":"$:/language/TiddlerInfo/Tagging/Empty","text":"No tiddlers are tagged with this one"},"$:/language/TiddlerInfo/Tools/Caption":{"title":"$:/language/TiddlerInfo/Tools/Caption","text":"Tools"},"$:/language/Docs/Types/application/javascript":{"title":"$:/language/Docs/Types/application/javascript","description":"JavaScript code","name":"application/javascript","group":"Developer","group-sort":"2"},"$:/language/Docs/Types/application/json":{"title":"$:/language/Docs/Types/application/json","description":"JSON data","name":"application/json","group":"Developer","group-sort":"2"},"$:/language/Docs/Types/application/x-tiddler-dictionary":{"title":"$:/language/Docs/Types/application/x-tiddler-dictionary","description":"Data dictionary","name":"application/x-tiddler-dictionary","group":"Developer","group-sort":"2"},"$:/language/Docs/Types/image/gif":{"title":"$:/language/Docs/Types/image/gif","description":"GIF image","name":"image/gif","group":"Image","group-sort":"1"},"$:/language/Docs/Types/image/jpeg":{"title":"$:/language/Docs/Types/image/jpeg","description":"JPEG image","name":"image/jpeg","group":"Image","group-sort":"1"},"$:/language/Docs/Types/image/png":{"title":"$:/language/Docs/Types/image/png","description":"PNG image","name":"image/png","group":"Image","group-sort":"1"},"$:/language/Docs/Types/image/svg+xml":{"title":"$:/language/Docs/Types/image/svg+xml","description":"SVG image","name":"image/svg+xml","group":"Image","group-sort":"1"},"$:/language/Docs/Types/text/css":{"title":"$:/language/Docs/Types/text/css","description":"Static stylesheet","name":"text/css","group":"Developer","group-sort":"2"},"$:/language/Docs/Types/text/html":{"title":"$:/language/Docs/Types/text/html","description":"HTML markup","name":"text/html","group":"Text","group-sort":"0"},"$:/language/Docs/Types/text/plain":{"title":"$:/language/Docs/Types/text/plain","description":"Plain text","name":"text/plain","group":"Text","group-sort":"0"},"$:/language/Docs/Types/text/vnd.tiddlywiki":{"title":"$:/language/Docs/Types/text/vnd.tiddlywiki","description":"TiddlyWiki 5","name":"text/vnd.tiddlywiki","group":"Text","group-sort":"0"},"$:/language/Docs/Types/text/vnd.tiddlywiki-multiple":{"title":"$:/language/Docs/Types/text/vnd.tiddlywiki-multiple","description":"Compound tiddler","name":"text/vnd.tiddlywiki-multiple","group":"Developer","group-sort":"2"},"$:/languages/en-GB/icon":{"title":"$:/languages/en-GB/icon","type":"image/svg+xml","text":"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 60 30\" width=\"1200\" height=\"600\">\n<clipPath id=\"t\">\n\t<path d=\"M30,15 h30 v15 z v15 h-30 z h-30 v-15 z v-15 h30 z\"/>\n</clipPath>\n<path d=\"M0,0 v30 h60 v-30 z\" fill=\"#00247d\"/>\n<path d=\"M0,0 L60,30 M60,0 L0,30\" stroke=\"#fff\" stroke-width=\"6\"/>\n<path d=\"M0,0 L60,30 M60,0 L0,30\" clip-path=\"url(#t)\" stroke=\"#cf142b\" stroke-width=\"4\"/>\n<path d=\"M30,0 v30 M0,15 h60\" stroke=\"#fff\" stroke-width=\"10\"/>\n<path d=\"M30,0 v30 M0,15 h60\" stroke=\"#cf142b\" stroke-width=\"6\"/>\n</svg>\n"},"$:/languages/en-GB":{"title":"$:/languages/en-GB","name":"en-GB","description":"English (British)","author":"JeremyRuston","core-version":">=5.0.0\"","text":"Stub pseudo-plugin for the default language"},"$:/core/modules/commander.js":{"title":"$:/core/modules/commander.js","text":"/*\\\ntitle: $:/core/modules/commander.js\ntype: application/javascript\nmodule-type: global\n\nThe $tw.Commander class is a command interpreter\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nParse a sequence of commands\n\tcommandTokens: an array of command string tokens\n\twiki: reference to the wiki store object\n\tstreams: {output:, error:}, each of which has a write(string) method\n\tcallback: a callback invoked as callback(err) where err is null if there was no error\n*/\nvar Commander = function(commandTokens,callback,wiki,streams) {\n\tvar path = require(\"path\");\n\tthis.commandTokens = commandTokens;\n\tthis.nextToken = 0;\n\tthis.callback = callback;\n\tthis.wiki = wiki;\n\tthis.streams = streams;\n\tthis.outputPath = path.resolve($tw.boot.wikiPath,$tw.config.wikiOutputSubDir);\n};\n\n/*\nLog a string if verbose flag is set\n*/\nCommander.prototype.log = function(str) {\n\tif(this.verbose) {\n\t\tthis.streams.output.write(str + \"\\n\");\n\t}\n};\n\n/*\nWrite a string if verbose flag is set\n*/\nCommander.prototype.write = function(str) {\n\tif(this.verbose) {\n\t\tthis.streams.output.write(str);\n\t}\n};\n\n/*\nAdd a string of tokens to the command queue\n*/\nCommander.prototype.addCommandTokens = function(commandTokens) {\n\tvar params = commandTokens.slice(0);\n\tparams.unshift(0);\n\tparams.unshift(this.nextToken);\n\tArray.prototype.splice.apply(this.commandTokens,params);\n};\n\n/*\nExecute the sequence of commands and invoke a callback on completion\n*/\nCommander.prototype.execute = function() {\n\tthis.executeNextCommand();\n};\n\n/*\nExecute the next command in the sequence\n*/\nCommander.prototype.executeNextCommand = function() {\n\tvar self = this;\n\t// Invoke the callback if there are no more commands\n\tif(this.nextToken >= this.commandTokens.length) {\n\t\tthis.callback(null);\n\t} else {\n\t\t// Get and check the command token\n\t\tvar commandName = this.commandTokens[this.nextToken++];\n\t\tif(commandName.substr(0,2) !== \"--\") {\n\t\t\tthis.callback(\"Missing command: \" + commandName);\n\t\t} else {\n\t\t\tcommandName = commandName.substr(2); // Trim off the --\n\t\t\t// Accumulate the parameters to the command\n\t\t\tvar params = [];\n\t\t\twhile(this.nextToken < this.commandTokens.length && \n\t\t\t\tthis.commandTokens[this.nextToken].substr(0,2) !== \"--\") {\n\t\t\t\tparams.push(this.commandTokens[this.nextToken++]);\n\t\t\t}\n\t\t\t// Get the command info\n\t\t\tvar command = $tw.commands[commandName],\n\t\t\t\tc,err;\n\t\t\tif(!command) {\n\t\t\t\tthis.callback(\"Unknown command: \" + commandName);\n\t\t\t} else {\n\t\t\t\tif(this.verbose) {\n\t\t\t\t\tthis.streams.output.write(\"Executing command: \" + commandName + \" \" + params.join(\" \") + \"\\n\");\n\t\t\t\t}\n\t\t\t\t// Parse named parameters if required\n\t\t\t\tif(command.info.namedParameterMode) {\n\t\t\t\t\tparams = this.extractNamedParameters(params,command.info.mandatoryParameters);\n\t\t\t\t\tif(typeof params === \"string\") {\n\t\t\t\t\t\treturn this.callback(params);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(command.info.synchronous) {\n\t\t\t\t\t// Synchronous command\n\t\t\t\t\tc = new command.Command(params,this);\n\t\t\t\t\terr = c.execute();\n\t\t\t\t\tif(err) {\n\t\t\t\t\t\tthis.callback(err);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.executeNextCommand();\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Asynchronous command\n\t\t\t\t\tc = new command.Command(params,this,function(err) {\n\t\t\t\t\t\tif(err) {\n\t\t\t\t\t\t\tself.callback(err);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tself.executeNextCommand();\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\terr = c.execute();\n\t\t\t\t\tif(err) {\n\t\t\t\t\t\tthis.callback(err);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\n/*\nGiven an array of parameter strings `params` in name:value format, and an array of mandatory parameter names in `mandatoryParameters`, returns a hashmap of values or a string if error\n*/\nCommander.prototype.extractNamedParameters = function(params,mandatoryParameters) {\n\tmandatoryParameters = mandatoryParameters || [];\n\tvar errors = [],\n\t\tparamsByName = Object.create(null);\n\t// Extract the parameters\n\t$tw.utils.each(params,function(param) {\n\t\tvar index = param.indexOf(\"=\");\n\t\tif(index < 1) {\n\t\t\terrors.push(\"malformed named parameter: '\" + param + \"'\");\n\t\t}\n\t\tparamsByName[param.slice(0,index)] = $tw.utils.trim(param.slice(index+1));\n\t});\n\t// Check the mandatory parameters are present\n\t$tw.utils.each(mandatoryParameters,function(mandatoryParameter) {\n\t\tif(!$tw.utils.hop(paramsByName,mandatoryParameter)) {\n\t\t\terrors.push(\"missing mandatory parameter: '\" + mandatoryParameter + \"'\");\n\t\t}\n\t});\n\t// Return any errors\n\tif(errors.length > 0) {\n\t\treturn errors.join(\" and\\n\");\n\t} else {\n\t\treturn paramsByName;\n\t}\n};\n\nCommander.initCommands = function(moduleType) {\n\tmoduleType = moduleType || \"command\";\n\t$tw.commands = {};\n\t$tw.modules.forEachModuleOfType(moduleType,function(title,module) {\n\t\tvar c = $tw.commands[module.info.name] = {};\n\t\t// Add the methods defined by the module\n\t\tfor(var f in module) {\n\t\t\tif($tw.utils.hop(module,f)) {\n\t\t\t\tc[f] = module[f];\n\t\t\t}\n\t\t}\n\t});\n};\n\nexports.Commander = Commander;\n\n})();\n","type":"application/javascript","module-type":"global"},"$:/core/modules/commands/build.js":{"title":"$:/core/modules/commands/build.js","text":"/*\\\ntitle: $:/core/modules/commands/build.js\ntype: application/javascript\nmodule-type: command\n\nCommand to build a build target\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"build\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander) {\n\tthis.params = params;\n\tthis.commander = commander;\n};\n\nCommand.prototype.execute = function() {\n\t// Get the build targets defined in the wiki\n\tvar buildTargets = $tw.boot.wikiInfo && $tw.boot.wikiInfo.build;\n\tif(!buildTargets) {\n\t\treturn \"No build targets defined\";\n\t}\n\t// Loop through each of the specified targets\n\tvar targets;\n\tif(this.params.length > 0) {\n\t\ttargets = this.params;\n\t} else {\n\t\ttargets = Object.keys(buildTargets);\n\t}\n\tfor(var targetIndex=0; targetIndex<targets.length; targetIndex++) {\n\t\tvar target = targets[targetIndex],\n\t\t\tcommands = buildTargets[target];\n\t\tif(!commands) {\n\t\t\treturn \"Build target '\" + target + \"' not found\";\n\t\t}\n\t\t// Add the commands to the queue\n\t\tthis.commander.addCommandTokens(commands);\n\t}\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n","type":"application/javascript","module-type":"command"},"$:/core/modules/commands/clearpassword.js":{"title":"$:/core/modules/commands/clearpassword.js","text":"/*\\\ntitle: $:/core/modules/commands/clearpassword.js\ntype: application/javascript\nmodule-type: command\n\nClear password for crypto operations\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"clearpassword\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\t$tw.crypto.setPassword(null);\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n","type":"application/javascript","module-type":"command"},"$:/core/modules/commands/commands.js":{"title":"$:/core/modules/commands/commands.js","text":"/*\\\ntitle: $:/core/modules/commands/commands.js\ntype: application/javascript\nmodule-type: command\n\nRuns the commands returned from a filter\n\n\\*/\n\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"commands\",\n\tsynchronous: true\n};\n\nvar Command = function(params, commander) {\n\tthis.params = params;\n\tthis.commander = commander;\n};\n\nCommand.prototype.execute = function() {\n\t// Parse the filter\n\tvar filter = this.params[0];\n\tif(!filter) {\n\t\treturn \"No filter specified\";\n\t}\n\tvar commands = this.commander.wiki.filterTiddlers(filter)\n\tif(commands.length === 0) {\n\t\treturn \"No tiddlers found for filter '\" + filter + \"'\";\n\t}\n\tthis.commander.addCommandTokens(commands);\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n","type":"application/javascript","module-type":"command"},"$:/core/modules/commands/deletetiddlers.js":{"title":"$:/core/modules/commands/deletetiddlers.js","text":"/*\\\ntitle: $:/core/modules/commands/deletetiddlers.js\ntype: application/javascript\nmodule-type: command\n\nCommand to delete tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"deletetiddlers\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 1) {\n\t\treturn \"Missing filter\";\n\t}\n\tvar self = this,\n\t\twiki = this.commander.wiki,\n\t\tfilter = this.params[0],\n\t\ttiddlers = wiki.filterTiddlers(filter);\n\t$tw.utils.each(tiddlers,function(title) {\n\t\twiki.deleteTiddler(title);\n\t});\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n","type":"application/javascript","module-type":"command"},"$:/core/modules/commands/editions.js":{"title":"$:/core/modules/commands/editions.js","text":"/*\\\ntitle: $:/core/modules/commands/editions.js\ntype: application/javascript\nmodule-type: command\n\nCommand to list the available editions\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"editions\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander) {\n\tthis.params = params;\n\tthis.commander = commander;\n};\n\nCommand.prototype.execute = function() {\n\tvar self = this;\n\t// Output the list\n\tthis.commander.streams.output.write(\"Available editions:\\n\\n\");\n\tvar editionInfo = $tw.utils.getEditionInfo();\n\t$tw.utils.each(editionInfo,function(info,name) {\n\t\tself.commander.streams.output.write(\"    \" + name + \": \" + info.description + \"\\n\");\n\t});\n\tthis.commander.streams.output.write(\"\\n\");\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n","type":"application/javascript","module-type":"command"},"$:/core/modules/commands/fetch.js":{"title":"$:/core/modules/commands/fetch.js","text":"/*\\\ntitle: $:/core/modules/commands/fetch.js\ntype: application/javascript\nmodule-type: command\n\nCommands to fetch external tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"fetch\",\n\tsynchronous: false\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 2) {\n\t\treturn \"Missing subcommand and url\";\n\t}\n\tswitch(this.params[0]) {\n\t\tcase \"raw-file\":\n\t\t\treturn this.fetchFiles({\n\t\t\t\traw: true,\n\t\t\t\turl: this.params[1],\n\t\t\t\ttransformFilter: this.params[2] || \"\",\n\t\t\t\tcallback: this.callback\n\t\t\t});\n\t\t\tbreak;\n\t\tcase \"file\":\n\t\t\treturn this.fetchFiles({\n\t\t\t\turl: this.params[1],\n\t\t\t\timportFilter: this.params[2],\n\t\t\t\ttransformFilter: this.params[3] || \"\",\n\t\t\t\tcallback: this.callback\n\t\t\t});\n\t\t\tbreak;\n\t\tcase \"raw-files\":\n\t\t\treturn this.fetchFiles({\n\t\t\t\traw: true,\n\t\t\t\turlFilter: this.params[1],\n\t\t\t\ttransformFilter: this.params[2] || \"\",\n\t\t\t\tcallback: this.callback\n\t\t\t});\n\t\t\tbreak;\n\t\tcase \"files\":\n\t\t\treturn this.fetchFiles({\n\t\t\t\turlFilter: this.params[1],\n\t\t\t\timportFilter: this.params[2],\n\t\t\t\ttransformFilter: this.params[3] || \"\",\n\t\t\t\tcallback: this.callback\n\t\t\t});\n\t\t\tbreak;\n\t}\n\treturn null;\n};\n\nCommand.prototype.fetchFiles = function(options) {\n\tvar self = this;\n\t// Get the list of URLs\n\tvar urls;\n\tif(options.url) {\n\t\turls = [options.url]\n\t} else if(options.urlFilter) {\n\t\turls = this.commander.wiki.filterTiddlers(options.urlFilter);\n\t} else {\n\t\treturn \"Missing URL\";\n\t}\n\t// Process each URL in turn\n\tvar next = 0;\n\tvar getNextFile = function(err) {\n\t\tif(err) {\n\t\t\treturn options.callback(err);\n\t\t}\n\t\tif(next < urls.length) {\n\t\t\tself.fetchFile(urls[next++],options,getNextFile);\n\t\t} else {\n\t\t\toptions.callback(null);\n\t\t}\n\t};\n\tgetNextFile(null);\n\t// Success\n\treturn null;\n};\n\nCommand.prototype.fetchFile = function(url,options,callback,redirectCount) {\n\tif(redirectCount > 10) {\n\t\treturn callback(\"Error too many redirects retrieving \" + url);\n\t}\n\tvar self = this,\n\t\tlib = url.substr(0,8) === \"https://\" ? require(\"https\") : require(\"http\");\n\tlib.get(url).on(\"response\",function(response) {\n\t    var type = (response.headers[\"content-type\"] || \"\").split(\";\")[0],\n\t    \tdata = [];\n\t    self.commander.write(\"Reading \" + url + \": \");\n\t    response.on(\"data\",function(chunk) {\n\t        data.push(chunk);\n\t        self.commander.write(\".\");\n\t    });\n\t    response.on(\"end\",function() {\n\t        self.commander.write(\"\\n\");\n\t        if(response.statusCode === 200) {\n\t\t        self.processBody(Buffer.concat(data),type,options,url);\n\t\t        callback(null);\n\t        } else {\n\t        \tif(response.statusCode === 302 || response.statusCode === 303 || response.statusCode === 307) {\n\t        \t\treturn self.fetchFile(response.headers.location,options,callback,redirectCount + 1);\n\t        \t} else {\n\t\t        \treturn callback(\"Error \" + response.statusCode + \" retrieving \" + url)\n\t        \t}\n\t        }\n\t   \t});\n\t   \tresponse.on(\"error\",function(e) {\n\t\t\tconsole.log(\"Error on GET request: \" + e);\n\t\t\tcallback(e);\n\t   \t});\n\t});\n\treturn null;\n};\n\nCommand.prototype.processBody = function(body,type,options,url) {\n\tvar self = this;\n\t// Collect the tiddlers in a wiki\n\tvar incomingWiki = new $tw.Wiki();\n\tif(options.raw) {\n\t\tvar typeInfo = type ? $tw.config.contentTypeInfo[type] : null,\n\t\t\tencoding = typeInfo ? typeInfo.encoding : \"utf8\";\n\t\tincomingWiki.addTiddler(new $tw.Tiddler({\n\t\t\ttitle: url,\n\t\t\ttype: type,\n\t\t\ttext: body.toString(encoding)\n\t\t}));\n\t} else {\n\t\t// Deserialise the file to extract the tiddlers\n\t\tvar tiddlers = this.commander.wiki.deserializeTiddlers(type || \"text/html\",body.toString(\"utf8\"),{});\n\t\t$tw.utils.each(tiddlers,function(tiddler) {\n\t\t\tincomingWiki.addTiddler(new $tw.Tiddler(tiddler));\n\t\t});\n\t}\n\t// Filter the tiddlers to select the ones we want\n\tvar filteredTitles = incomingWiki.filterTiddlers(options.importFilter || \"[all[tiddlers]]\");\n\t// Import the selected tiddlers\n\tvar count = 0;\n\tincomingWiki.each(function(tiddler,title) {\n\t\tif(filteredTitles.indexOf(title) !== -1) {\n\t\t\tvar newTiddler;\n\t\t\tif(options.transformFilter) {\n\t\t\t\tvar transformedTitle = (incomingWiki.filterTiddlers(options.transformFilter,null,self.commander.wiki.makeTiddlerIterator([title])) || [\"\"])[0];\n\t\t\t\tif(transformedTitle) {\n\t\t\t\t\tself.commander.log(\"Importing \" + title + \" as \" + transformedTitle)\n\t\t\t\t\tnewTiddler = new $tw.Tiddler(tiddler,{title: transformedTitle});\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tself.commander.log(\"Importing \" + title)\n\t\t\t\tnewTiddler = tiddler;\n\t\t\t}\n\t\t\tself.commander.wiki.importTiddler(newTiddler);\n\t\t\tcount++;\n\t\t}\n\t});\n\tself.commander.log(\"Imported \" + count + \" tiddlers\")\n};\n\nexports.Command = Command;\n\n})();\n","type":"application/javascript","module-type":"command"},"$:/core/modules/commands/help.js":{"title":"$:/core/modules/commands/help.js","text":"/*\\\ntitle: $:/core/modules/commands/help.js\ntype: application/javascript\nmodule-type: command\n\nHelp command\n\n\\*/\n(function(){\n\n/*jshint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"help\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander) {\n\tthis.params = params;\n\tthis.commander = commander;\n};\n\nCommand.prototype.execute = function() {\n\tvar subhelp = this.params[0] || \"default\",\n\t\thelpBase = \"$:/language/Help/\",\n\t\ttext;\n\tif(!this.commander.wiki.getTiddler(helpBase + subhelp)) {\n\t\tsubhelp = \"notfound\";\n\t}\n\t// Wikify the help as formatted text (ie block elements generate newlines)\n\ttext = this.commander.wiki.renderTiddler(\"text/plain-formatted\",helpBase + subhelp);\n\t// Remove any leading linebreaks\n\ttext = text.replace(/^(\\r?\\n)*/g,\"\");\n\tthis.commander.streams.output.write(text);\n};\n\nexports.Command = Command;\n\n})();\n","type":"application/javascript","module-type":"command"},"$:/core/modules/commands/import.js":{"title":"$:/core/modules/commands/import.js","text":"/*\\\ntitle: $:/core/modules/commands/import.js\ntype: application/javascript\nmodule-type: command\n\nCommand to import tiddlers from a file\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"import\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\");\n\tif(this.params.length < 2) {\n\t\treturn \"Missing parameters\";\n\t}\n\tvar filename = self.params[0],\n\t\tdeserializer = self.params[1],\n\t\ttitle = self.params[2] || filename,\n\t\tencoding = self.params[3] || \"utf8\",\n\t\ttext = fs.readFileSync(filename,encoding),\n\t\ttiddlers = this.commander.wiki.deserializeTiddlers(null,text,{title: title},{deserializer: deserializer});\n\t$tw.utils.each(tiddlers,function(tiddler) {\n\t\tself.commander.wiki.importTiddler(new $tw.Tiddler(tiddler));\n\t});\n\tthis.commander.log(tiddlers.length + \" tiddler(s) imported\");\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n","type":"application/javascript","module-type":"command"},"$:/core/modules/commands/init.js":{"title":"$:/core/modules/commands/init.js","text":"/*\\\ntitle: $:/core/modules/commands/init.js\ntype: application/javascript\nmodule-type: command\n\nCommand to initialise an empty wiki folder\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"init\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander) {\n\tthis.params = params;\n\tthis.commander = commander;\n};\n\nCommand.prototype.execute = function() {\n\tvar fs = require(\"fs\"),\n\t\tpath = require(\"path\");\n\t// Check that we don't already have a valid wiki folder\n\tif($tw.boot.wikiTiddlersPath || ($tw.utils.isDirectory($tw.boot.wikiPath) && !$tw.utils.isDirectoryEmpty($tw.boot.wikiPath))) {\n\t\treturn \"Wiki folder is not empty\";\n\t}\n\t// Loop through each of the specified editions\n\tvar editions = this.params.length > 0 ? this.params : [\"empty\"];\n\tfor(var editionIndex=0; editionIndex<editions.length; editionIndex++) {\n\t\tvar editionName = editions[editionIndex];\n\t\t// Check the edition exists\n\t\tvar editionPath = $tw.findLibraryItem(editionName,$tw.getLibraryItemSearchPaths($tw.config.editionsPath,$tw.config.editionsEnvVar));\n\t\tif(!$tw.utils.isDirectory(editionPath)) {\n\t\t\treturn \"Edition '\" + editionName + \"' not found\";\n\t\t}\n\t\t// Copy the edition content\n\t\tvar err = $tw.utils.copyDirectory(editionPath,$tw.boot.wikiPath);\n\t\tif(!err) {\n\t\t\tthis.commander.streams.output.write(\"Copied edition '\" + editionName + \"' to \" + $tw.boot.wikiPath + \"\\n\");\n\t\t} else {\n\t\t\treturn err;\n\t\t}\n\t}\n\t// Tweak the tiddlywiki.info to remove any included wikis\n\tvar packagePath = $tw.boot.wikiPath + \"/tiddlywiki.info\",\n\t\tpackageJson = $tw.utils.parseJSONSafe(fs.readFileSync(packagePath));\n\tdelete packageJson.includeWikis;\n\tfs.writeFileSync(packagePath,JSON.stringify(packageJson,null,$tw.config.preferences.jsonSpaces));\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n","type":"application/javascript","module-type":"command"},"$:/core/modules/commands/listen.js":{"title":"$:/core/modules/commands/listen.js","text":"/*\\\ntitle: $:/core/modules/commands/listen.js\ntype: application/javascript\nmodule-type: command\n\nListen for HTTP requests and serve tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Server = require(\"$:/core/modules/server/server.js\").Server;\n\nexports.info = {\n\tname: \"listen\",\n\tsynchronous: true,\n\tnamedParameterMode: true,\n\tmandatoryParameters: []\n};\n\nvar Command = function(params,commander,callback) {\n\tvar self = this;\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tvar self = this;\n\tif(!$tw.boot.wikiTiddlersPath) {\n\t\t$tw.utils.warning(\"Warning: Wiki folder '\" + $tw.boot.wikiPath + \"' does not exist or is missing a tiddlywiki.info file\");\n\t}\n\t// Set up server\n\tthis.server = new Server({\n\t\twiki: this.commander.wiki,\n\t\tvariables: self.params\n\t});\n\tvar nodeServer = this.server.listen();\n\t$tw.hooks.invokeHook(\"th-server-command-post-start\",this.server,nodeServer,\"tiddlywiki\");\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n","type":"application/javascript","module-type":"command"},"$:/core/modules/commands/load.js":{"title":"$:/core/modules/commands/load.js","text":"/*\\\ntitle: $:/core/modules/commands/load.js\ntype: application/javascript\nmodule-type: command\n\nCommand to load tiddlers from a file or directory\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"load\",\n\tsynchronous: false\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\");\n\tif(this.params.length < 1) {\n\t\treturn \"Missing filename\";\n\t}\n\tvar tiddlers = $tw.loadTiddlersFromPath(self.params[0]),\n\t\tcount = 0;\n\t$tw.utils.each(tiddlers,function(tiddlerInfo) {\n\t\t$tw.utils.each(tiddlerInfo.tiddlers,function(tiddler) {\n\t\t\tself.commander.wiki.importTiddler(new $tw.Tiddler(tiddler));\n\t\t\tcount++;\n\t\t});\n\t});\n\tif(!count && self.params[1] !== \"noerror\") {\n\t\tself.callback(\"No tiddlers found in file \\\"\" + self.params[0] + \"\\\"\");\n\t} else {\n\t\tself.callback(null);\n\t}\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n","type":"application/javascript","module-type":"command"},"$:/core/modules/commands/makelibrary.js":{"title":"$:/core/modules/commands/makelibrary.js","text":"/*\\\ntitle: $:/core/modules/commands/makelibrary.js\ntype: application/javascript\nmodule-type: command\n\nCommand to pack all of the plugins in the library into a plugin tiddler of type \"library\"\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"makelibrary\",\n\tsynchronous: true\n};\n\nvar UPGRADE_LIBRARY_TITLE = \"$:/UpgradeLibrary\";\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tvar wiki = this.commander.wiki,\n\t\tupgradeLibraryTitle = this.params[0] || UPGRADE_LIBRARY_TITLE,\n\t\ttiddlers = $tw.utils.getAllPlugins();\n\t// Save the upgrade library tiddler\n\tvar pluginFields = {\n\t\ttitle: upgradeLibraryTitle,\n\t\ttype: \"application/json\",\n\t\t\"plugin-type\": \"library\",\n\t\t\"text\": JSON.stringify({tiddlers: tiddlers})\n\t};\n\twiki.addTiddler(new $tw.Tiddler(pluginFields));\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n","type":"application/javascript","module-type":"command"},"$:/core/modules/commands/output.js":{"title":"$:/core/modules/commands/output.js","text":"/*\\\ntitle: $:/core/modules/commands/output.js\ntype: application/javascript\nmodule-type: command\n\nCommand to set the default output location (defaults to current working directory)\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"output\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tvar fs = require(\"fs\"),\n\t\tpath = require(\"path\");\n\tif(this.params.length < 1) {\n\t\treturn \"Missing output path\";\n\t}\n\tthis.commander.outputPath = path.resolve(process.cwd(),this.params[0]);\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n","type":"application/javascript","module-type":"command"},"$:/core/modules/commands/password.js":{"title":"$:/core/modules/commands/password.js","text":"/*\\\ntitle: $:/core/modules/commands/password.js\ntype: application/javascript\nmodule-type: command\n\nSave password for crypto operations\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"password\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 1) {\n\t\treturn \"Missing password\";\n\t}\n\t$tw.crypto.setPassword(this.params[0]);\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n","type":"application/javascript","module-type":"command"},"$:/core/modules/commands/render.js":{"title":"$:/core/modules/commands/render.js","text":"/*\\\ntitle: $:/core/modules/commands/render.js\ntype: application/javascript\nmodule-type: command\n\nRender individual tiddlers and save the results to the specified files\n\n\\*/\n(function(){\n\n\t/*jslint node: true, browser: true */\n\t/*global $tw: false */\n\t\"use strict\";\n\t\n\tvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\t\n\texports.info = {\n\t\tname: \"render\",\n\t\tsynchronous: true\n\t};\n\t\n\tvar Command = function(params,commander,callback) {\n\t\tthis.params = params;\n\t\tthis.commander = commander;\n\t\tthis.callback = callback;\n\t};\n\t\n\tCommand.prototype.execute = function() {\n\t\tif(this.params.length < 1) {\n\t\t\treturn \"Missing tiddler filter\";\n\t\t}\n\t\tvar self = this,\n\t\t\tfs = require(\"fs\"),\n\t\t\tpath = require(\"path\"),\n\t\t\twiki = this.commander.wiki,\n\t\t\ttiddlerFilter = this.params[0],\n\t\t\tfilenameFilter = this.params[1] || \"[is[tiddler]addsuffix[.html]]\",\n\t\t\ttype = this.params[2] || \"text/html\",\n\t\t\ttemplate = this.params[3],\n\t\t\tvariableList = this.params.slice(4),\n\t\t\ttiddlers = wiki.filterTiddlers(tiddlerFilter),\n\t\t\tvariables =  Object.create(null);\n\t\t\twhile(variableList.length >= 2) {\n\t\t\t\tvariables[variableList[0]] = variableList[1];\n\t\t\t\tvariableList = variableList.slice(2);\n\t\t\t}\n\t\t$tw.utils.each(tiddlers,function(title) {\n\t\t\tvar filenameResults = wiki.filterTiddlers(filenameFilter,$tw.rootWidget,wiki.makeTiddlerIterator([title]));\n\t\t\tif(filenameResults.length > 0) {\n\t\t\t\tvar filepath = path.resolve(self.commander.outputPath,filenameResults[0]);\n\t\t\t\tif(self.commander.verbose) {\n\t\t\t\t\tconsole.log(\"Rendering \\\"\" + title + \"\\\" to \\\"\" + filepath + \"\\\"\");\n\t\t\t\t}\n\t\t\t\tvar parser = wiki.parseTiddler(template || title),\n\t\t\t\t\twidgetNode = wiki.makeWidget(parser,{variables: $tw.utils.extend({},variables,{currentTiddler: title,storyTiddler: title})}),\n\t\t\t\t\tcontainer = $tw.fakeDocument.createElement(\"div\");\n\t\t\t\twidgetNode.render(container,null);\n\t\t\t\tvar text = type === \"text/html\" ? container.innerHTML : container.textContent;\n\t\t\t\t$tw.utils.createFileDirectories(filepath);\n\t\t\t\tfs.writeFileSync(filepath,text,\"utf8\");\n\t\t\t} else {\n\t\t\t\tconsole.log(\"Not rendering \\\"\" + title + \"\\\" because the filename filter returned an empty result\");\n\t\t\t}\n\t\t});\n\t\treturn null;\n\t};\n\t\n\texports.Command = Command;\n\t\n\t})();\n\t","type":"application/javascript","module-type":"command"},"$:/core/modules/commands/rendertiddler.js":{"title":"$:/core/modules/commands/rendertiddler.js","text":"/*\\\ntitle: $:/core/modules/commands/rendertiddler.js\ntype: application/javascript\nmodule-type: command\n\nCommand to render a tiddler and save it to a file\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"rendertiddler\",\n\tsynchronous: false\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 2) {\n\t\treturn \"Missing filename\";\n\t}\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\"),\n\t\ttitle = this.params[0],\n\t\tfilename = path.resolve(this.commander.outputPath,this.params[1]),\n\t\ttype = this.params[2] || \"text/html\",\n\t\ttemplate = this.params[3],\n\t\tname = this.params[4],\n\t\tvalue = this.params[5],\n\t\tvariables = {};\n\t$tw.utils.createFileDirectories(filename);\n\tif(template) {\n\t\tvariables.currentTiddler = title;\n\t\tvariables.storyTiddler = title;\n\t\ttitle = template;\n\t}\n\tif(name && value) {\n\t\tvariables[name] = value;\n\t}\n\tfs.writeFile(filename,this.commander.wiki.renderTiddler(type,title,{variables: variables}),\"utf8\",function(err) {\n\t\tself.callback(err);\n\t});\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n","type":"application/javascript","module-type":"command"},"$:/core/modules/commands/rendertiddlers.js":{"title":"$:/core/modules/commands/rendertiddlers.js","text":"/*\\\ntitle: $:/core/modules/commands/rendertiddlers.js\ntype: application/javascript\nmodule-type: command\n\nCommand to render several tiddlers to a folder of files\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nexports.info = {\n\tname: \"rendertiddlers\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 2) {\n\t\treturn \"Missing filename\";\n\t}\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\"),\n\t\twiki = this.commander.wiki,\n\t\tfilter = this.params[0],\n\t\ttemplate = this.params[1],\n\t\toutputPath = this.commander.outputPath,\n\t\tpathname = path.resolve(outputPath,this.params[2]),\n\t\ttype = this.params[3] || \"text/html\",\n\t\textension = this.params[4] || \".html\",\n\t\tdeleteDirectory = (this.params[5] || \"\").toLowerCase() !== \"noclean\",\n\t\ttiddlers = wiki.filterTiddlers(filter);\n\tif(deleteDirectory) {\n\t\t$tw.utils.deleteDirectory(pathname);\n\t}\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tvar parser = wiki.parseTiddler(template),\n\t\t\twidgetNode = wiki.makeWidget(parser,{variables: {currentTiddler: title, storyTiddler: title}}),\n\t\t\tcontainer = $tw.fakeDocument.createElement(\"div\");\n\t\twidgetNode.render(container,null);\n\t\tvar text = type === \"text/html\" ? container.innerHTML : container.textContent,\n\t\t\texportPath = null;\n\t\tif($tw.utils.hop($tw.macros,\"tv-get-export-path\")) {\n\t\t\tvar macroPath = $tw.macros[\"tv-get-export-path\"].run.apply(self,[title]);\n\t\t\tif(macroPath) {\n\t\t\t\texportPath = path.resolve(outputPath,macroPath + extension);\n\t\t\t}\n\t\t}\n\t\tvar finalPath = exportPath || path.resolve(pathname,$tw.utils.encodeURIComponentExtended(title) + extension);\n\t\t$tw.utils.createFileDirectories(finalPath);\n\t\tfs.writeFileSync(finalPath,text,\"utf8\");\n\t});\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n","type":"application/javascript","module-type":"command"},"$:/core/modules/commands/save.js":{"title":"$:/core/modules/commands/save.js","text":"/*\\\ntitle: $:/core/modules/commands/save.js\ntype: application/javascript\nmodule-type: command\n\nSaves individual tiddlers in their raw text or binary format to the specified files\n\n\\*/\n(function(){\n\n\t/*jslint node: true, browser: true */\n\t/*global $tw: false */\n\t\"use strict\";\n\t\n\texports.info = {\n\t\tname: \"save\",\n\t\tsynchronous: true\n\t};\n\t\n\tvar Command = function(params,commander,callback) {\n\t\tthis.params = params;\n\t\tthis.commander = commander;\n\t\tthis.callback = callback;\n\t};\n\t\n\tCommand.prototype.execute = function() {\n\t\tif(this.params.length < 1) {\n\t\t\treturn \"Missing filename filter\";\n\t\t}\n\t\tvar self = this,\n\t\t\tfs = require(\"fs\"),\n\t\t\tpath = require(\"path\"),\n\t\t\tresult = null,\n\t\t\twiki = this.commander.wiki,\n\t\t\ttiddlerFilter = this.params[0],\n\t\t\tfilenameFilter = this.params[1] || \"[is[tiddler]]\",\n\t\t\ttiddlers = wiki.filterTiddlers(tiddlerFilter);\n\t\t$tw.utils.each(tiddlers,function(title) {\n\t\t\tif(!result) {\n\t\t\t\tvar tiddler = self.commander.wiki.getTiddler(title);\n\t\t\t\tif(tiddler) {\n\t\t\t\t\tvar fileInfo = $tw.utils.generateTiddlerFileInfo(tiddler,{\n\t\t\t\t\t\tdirectory: path.resolve(self.commander.outputPath),\n\t\t\t\t\t\tpathFilters: [filenameFilter],\n\t\t\t\t\t\twiki: wiki,\n\t\t\t\t\t\tfileInfo: {\n\t\t\t\t\t\t\toverwrite: true\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tif(self.commander.verbose) {\n\t\t\t\t\t\tconsole.log(\"Saving \\\"\" + title + \"\\\" to \\\"\" + fileInfo.filepath + \"\\\"\");\n\t\t\t\t\t}\n\t\t\t\t\ttry {\n\t\t\t\t\t\t$tw.utils.saveTiddlerToFileSync(tiddler,fileInfo);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tresult = \"Error saving tiddler \\\"\" + title + \"\\\", to file: \\\"\" + fileInfo.filepath + \"\\\"\";\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tresult = \"Tiddler '\" + title + \"' not found\";\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\treturn result;\n\t};\n\t\n\texports.Command = Command;\n\t\n\t})();\n\t","type":"application/javascript","module-type":"command"},"$:/core/modules/commands/savelibrarytiddlers.js":{"title":"$:/core/modules/commands/savelibrarytiddlers.js","text":"/*\\\ntitle: $:/core/modules/commands/savelibrarytiddlers.js\ntype: application/javascript\nmodule-type: command\n\nCommand to save the subtiddlers of a bundle tiddler as a series of JSON files\n\n--savelibrarytiddlers <tiddler> <tiddler-filter> <pathname> <skinnylisting>\n\nThe tiddler identifies the bundle tiddler that contains the subtiddlers.\n\nThe tiddler filter specifies the plugins to be included.\n\nThe pathname specifies the pathname to the folder in which the JSON files should be saved. The filename is the URL encoded title of the subtiddler.\n\nThe skinnylisting specifies the title of the tiddler to which a JSON catalogue of the subtiddlers will be saved. The JSON file contains the same data as the bundle tiddler but with the `text` field removed.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"savelibrarytiddlers\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 2) {\n\t\treturn \"Missing filename\";\n\t}\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\"),\n\t\tcontainerTitle = this.params[0],\n\t\tfilter = this.params[1],\n\t\tbasepath = this.params[2],\n\t\tskinnyListTitle = this.params[3];\n\t// Get the container tiddler as data\n\tvar containerData = self.commander.wiki.getTiddlerDataCached(containerTitle,undefined);\n\tif(!containerData) {\n\t\treturn \"'\" + containerTitle + \"' is not a tiddler bundle\";\n\t}\n\t// Filter the list of plugins\n\tvar pluginList = [];\n\t$tw.utils.each(containerData.tiddlers,function(tiddler,title) {\n\t\tpluginList.push(title);\n\t});\n\tvar filteredPluginList;\n\tif(filter) {\n\t\tfilteredPluginList = self.commander.wiki.filterTiddlers(filter,null,self.commander.wiki.makeTiddlerIterator(pluginList));\n\t} else {\n\t\tfilteredPluginList = pluginList;\n\t}\n\t// Iterate through the plugins\n\tvar skinnyList = [];\n\t$tw.utils.each(filteredPluginList,function(title) {\n\t\tvar tiddler = containerData.tiddlers[title];\n\t\t// Save each JSON file and collect the skinny data\n\t\tvar pathname = path.resolve(self.commander.outputPath,basepath + $tw.utils.encodeURIComponentExtended(title) + \".json\");\n\t\t$tw.utils.createFileDirectories(pathname);\n\t\tfs.writeFileSync(pathname,JSON.stringify(tiddler),\"utf8\");\n\t\t// Collect the skinny list data\n\t\tvar pluginTiddlers = $tw.utils.parseJSONSafe(tiddler.text),\n\t\t\treadmeContent = (pluginTiddlers.tiddlers[title + \"/readme\"] || {}).text,\n\t\t\tdoesRequireReload = !!self.commander.wiki.doesPluginInfoRequireReload(pluginTiddlers),\n\t\t\ticonTiddler = pluginTiddlers.tiddlers[title + \"/icon\"] || {},\n\t\t\ticonType = iconTiddler.type,\n\t\t\ticonText = iconTiddler.text,\n\t\t\ticonContent;\n\t\tif(iconType && iconText) {\n\t\t\ticonContent = $tw.utils.makeDataUri(iconText,iconType);\n\t\t}\n\t\tskinnyList.push($tw.utils.extend({},tiddler,{\n\t\t\ttext: undefined,\n\t\t\treadme: readmeContent,\n\t\t\t\"requires-reload\": doesRequireReload ? \"yes\" : \"no\",\n\t\t\ticon: iconContent\n\t\t}));\n\t});\n\t// Save the catalogue tiddler\n\tif(skinnyListTitle) {\n\t\tself.commander.wiki.setTiddlerData(skinnyListTitle,skinnyList);\n\t}\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n","type":"application/javascript","module-type":"command"},"$:/core/modules/commands/savetiddler.js":{"title":"$:/core/modules/commands/savetiddler.js","text":"/*\\\ntitle: $:/core/modules/commands/savetiddler.js\ntype: application/javascript\nmodule-type: command\n\nCommand to save the content of a tiddler to a file\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"savetiddler\",\n\tsynchronous: false\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 2) {\n\t\treturn \"Missing filename\";\n\t}\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\"),\n\t\ttitle = this.params[0],\n\t\tfilename = path.resolve(this.commander.outputPath,this.params[1]),\n\t\ttiddler = this.commander.wiki.getTiddler(title);\n\tif(tiddler) {\n\t\tvar type = tiddler.fields.type || \"text/vnd.tiddlywiki\",\n\t\t\tcontentTypeInfo = $tw.config.contentTypeInfo[type] || {encoding: \"utf8\"};\n\t\t$tw.utils.createFileDirectories(filename);\n\t\tfs.writeFile(filename,tiddler.fields.text,contentTypeInfo.encoding,function(err) {\n\t\t\tself.callback(err);\n\t\t});\n\t} else {\n\t\treturn \"Missing tiddler: \" + title;\n\t}\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n","type":"application/javascript","module-type":"command"},"$:/core/modules/commands/savetiddlers.js":{"title":"$:/core/modules/commands/savetiddlers.js","text":"/*\\\ntitle: $:/core/modules/commands/savetiddlers.js\ntype: application/javascript\nmodule-type: command\n\nCommand to save several tiddlers to a folder of files\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nexports.info = {\n\tname: \"savetiddlers\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 1) {\n\t\treturn \"Missing filename\";\n\t}\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\"),\n\t\twiki = this.commander.wiki,\n\t\tfilter = this.params[0],\n\t\tpathname = path.resolve(this.commander.outputPath,this.params[1]),\n\t\tdeleteDirectory = (this.params[2] || \"\").toLowerCase() !== \"noclean\",\n\t\ttiddlers = wiki.filterTiddlers(filter);\n\tif(deleteDirectory) {\n\t\t$tw.utils.deleteDirectory(pathname);\n\t}\n\t$tw.utils.createDirectory(pathname);\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tvar tiddler = self.commander.wiki.getTiddler(title),\n\t\t\ttype = tiddler.fields.type || \"text/vnd.tiddlywiki\",\n\t\t\tcontentTypeInfo = $tw.config.contentTypeInfo[type] || {encoding: \"utf8\"},\n\t\t\tfilename = path.resolve(pathname,$tw.utils.encodeURIComponentExtended(title));\n\t\tfs.writeFileSync(filename,tiddler.fields.text || \"\",contentTypeInfo.encoding);\n\t});\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n","type":"application/javascript","module-type":"command"},"$:/core/modules/commands/savewikifolder.js":{"title":"$:/core/modules/commands/savewikifolder.js","text":"/*\\\ntitle: $:/core/modules/commands/savewikifolder.js\ntype: application/javascript\nmodule-type: command\n\nCommand to save the current wiki as a wiki folder\n\n--savewikifolder <wikifolderpath> [ [<name>=<value>] ]*\n\nThe following options are supported:\n\n* ''filter'': a filter expression defining the tiddlers to be included in the output\n* ''explodePlugins'': set to \"no\" to suppress exploding plugins into their constituent shadow tiddlers (defaults to \"yes\")\n\nSupports backward compatibility with --savewikifolder <wikifolderpath> [<filter>] [ [<name>=<value>] ]*\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"savewikifolder\",\n\tsynchronous: true\n};\n\nvar fs,path;\nif($tw.node) {\n\tfs = require(\"fs\");\n\tpath = require(\"path\");\n}\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 1) {\n\t\treturn \"Missing wiki folder path\";\n\t}\n\tvar regFilter = /^[a-zA-Z0-9\\.\\-_]+=/g,  // dynamic parameters\n\t\tnamedParames,\n\t\ttiddlerFilter,\n\t\toptions = {};\n\tif (regFilter.test(this.params[1])) {  \n\t\tnamedParames = this.commander.extractNamedParameters(this.params.slice(1));\n\t\ttiddlerFilter = namedParames.filter || \"[all[tiddlers]]\";\n\t} else {\n\t\tnamedParames = this.commander.extractNamedParameters(this.params.slice(2));\n\t\ttiddlerFilter = this.params[1];\n\t}\n\ttiddlerFilter = tiddlerFilter || \"[all[tiddlers]]\";\n\toptions.explodePlugins = namedParames.explodePlugins || \"yes\";\n\tvar wikifoldermaker = new WikiFolderMaker(this.params[0],tiddlerFilter,this.commander,options);\n\treturn wikifoldermaker.save();\n};\n\nfunction WikiFolderMaker(wikiFolderPath,wikiFilter,commander,options) {\n\tthis.wikiFolderPath = wikiFolderPath;\n\tthis.wikiFilter = wikiFilter;\n\tthis.commander = commander;\n\tthis.explodePlugins = options.explodePlugins;\n\tthis.wiki = commander.wiki;\n\tthis.savedPaths = []; // So that we can detect filename clashes\n}\n\nWikiFolderMaker.prototype.log = function(str) {\n\tif(this.commander.verbose) {\n\t\tconsole.log(str);\n\t}\n};\n\nWikiFolderMaker.prototype.tiddlersToIgnore = [\n\t\"$:/boot/boot.css\",\n\t\"$:/boot/boot.js\",\n\t\"$:/boot/bootprefix.js\",\n\t\"$:/core\",\n\t\"$:/library/sjcl.js\",\n\t\"$:/temp/info-plugin\"\n];\n\n/*\nReturns null if successful, or an error string if there was an error\n*/\nWikiFolderMaker.prototype.save = function() {\n\tvar self = this;\n\t// Check that the output directory doesn't exist\n\tif(fs.existsSync(this.wikiFolderPath) && !$tw.utils.isDirectoryEmpty(this.wikiFolderPath)) {\n\t\treturn \"The unpackwiki command requires that the output wiki folder be empty\";\n\t}\n\t// Get the tiddlers from the source wiki\n\tvar tiddlerTitles = this.wiki.filterTiddlers(this.wikiFilter);\n\t// Initialise a new tiddlwiki.info file\n\tvar newWikiInfo = {};\n\t// Process each incoming tiddler in turn\n\t$tw.utils.each(tiddlerTitles,function(title) {\n\t\tvar tiddler = self.wiki.getTiddler(title);\n\t\tif(tiddler) {\n\t\t\tif(self.tiddlersToIgnore.indexOf(title) !== -1) {\n\t\t\t\t// Ignore the core plugin and the ephemeral info plugin\n\t\t\t\tself.log(\"Ignoring tiddler: \" + title);\n\t\t\t} else {\n\t\t\t\tvar type = tiddler.fields.type,\n\t\t\t\t\tpluginType = tiddler.fields[\"plugin-type\"];\n\t\t\t\tif(type === \"application/json\" && pluginType) {\n\t\t\t\t\t// Plugin tiddler\n\t\t\t\t\tvar libraryDetails = self.findPluginInLibrary(title);\n\t\t\t\t\tif(libraryDetails) {\n\t\t\t\t\t\t// A plugin from the core library\n\t\t\t\t\t\tself.log(\"Adding built-in plugin: \" + libraryDetails.name);\n\t\t\t\t\t\tnewWikiInfo[libraryDetails.type] = newWikiInfo[libraryDetails.type]  || [];\n\t\t\t\t\t\t$tw.utils.pushTop(newWikiInfo[libraryDetails.type],libraryDetails.name);\n\t\t\t\t\t} else if(self.explodePlugins !== \"no\") {\n\t\t\t\t\t\t// A custom plugin\n\t\t\t\t\t\tself.log(\"Processing custom plugin: \" + title);\n\t\t\t\t\t\tself.saveCustomPlugin(tiddler);\n\t\t\t\t\t} else if(self.explodePlugins === \"no\") {\n\t\t\t\t\t\tself.log(\"Processing custom plugin to tiddlders folder: \" + title);\n\t\t\t\t\t\tself.saveTiddler(\"tiddlers\", tiddler);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Ordinary tiddler\n\t\t\t\t\tself.saveTiddler(\"tiddlers\",tiddler);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\t// Save the tiddlywiki.info file\n\tthis.saveJSONFile(\"tiddlywiki.info\",newWikiInfo);\n\tself.log(\"Writing tiddlywiki.info: \" + JSON.stringify(newWikiInfo,null,$tw.config.preferences.jsonSpaces));\n\treturn null;\n};\n\n/*\nTest whether the specified tiddler is a plugin in the plugin library\n*/\nWikiFolderMaker.prototype.findPluginInLibrary = function(title) {\n\tvar parts = title.split(\"/\"),\n\t\tpluginPath, type, name;\n\tif(parts[0] === \"$:\") {\n\t\tif(parts[1] === \"languages\" && parts.length === 3) {\n\t\t\tpluginPath = \"languages\" + path.sep + parts[2];\n\t\t\ttype = parts[1];\n\t\t\tname = parts[2];\n\t\t} else if(parts[1] === \"plugins\" || parts[1] === \"themes\" && parts.length === 4) {\n\t\t\tpluginPath = parts[1] + path.sep + parts[2] + path.sep + parts[3];\n\t\t\ttype = parts[1];\n\t\t\tname = parts[2] + \"/\" + parts[3];\n\t\t}\n\t}\n\tif(pluginPath && type && name) {\n\t\tpluginPath = path.resolve($tw.boot.bootPath,\"..\",pluginPath);\n\t\tif(fs.existsSync(pluginPath)) {\n\t\t\treturn {\n\t\t\t\tpluginPath: pluginPath,\n\t\t\t\ttype: type,\n\t\t\t\tname: name\n\t\t\t};\n\t\t}\n\t}\n\treturn false;\n};\n\nWikiFolderMaker.prototype.saveCustomPlugin = function(pluginTiddler) {\n\tvar self = this,\n\t\tpluginTitle = pluginTiddler.fields.title,\n\t\ttitleParts = pluginTitle.split(\"/\"),\n\t\tdirectory = $tw.utils.generateTiddlerFilepath(titleParts[titleParts.length - 1],{\n\t\t\tdirectory: path.resolve(this.wikiFolderPath,pluginTiddler.fields[\"plugin-type\"] + \"s\")\n\t\t}),\n\t\tpluginInfo = pluginTiddler.getFieldStrings({exclude: [\"text\",\"type\"]});\n\tthis.saveJSONFile(directory + path.sep + \"plugin.info\",pluginInfo);\n\tself.log(\"Writing \" + directory + path.sep + \"plugin.info: \" + JSON.stringify(pluginInfo,null,$tw.config.preferences.jsonSpaces));\n\tvar pluginTiddlers = $tw.utils.parseJSONSafe(pluginTiddler.fields.text).tiddlers; // A hashmap of tiddlers in the plugin\n\t$tw.utils.each(pluginTiddlers,function(tiddler,title) {\n\t\tif(!tiddler.title) {\n\t\t\ttiddler.title = title;\n\t\t }\n\t\tself.saveTiddler(directory,new $tw.Tiddler(tiddler));\n\t});\n};\n\nWikiFolderMaker.prototype.saveTiddler = function(directory,tiddler) {\n\tvar title = tiddler.fields.title, fileInfo, pathFilters, extFilters;\n\tif(this.wiki.tiddlerExists(\"$:/config/FileSystemPaths\")) {\n\t\tpathFilters = this.wiki.getTiddlerText(\"$:/config/FileSystemPaths\",\"\").split(\"\\n\");\n\t}\n\tif(this.wiki.tiddlerExists(\"$:/config/FileSystemExtensions\")) {\n\t\textFilters = this.wiki.getTiddlerText(\"$:/config/FileSystemExtensions\",\"\").split(\"\\n\");\n\t}\n\tvar fileInfo = $tw.utils.generateTiddlerFileInfo(tiddler,{\n\t\tdirectory: path.resolve(this.wikiFolderPath,directory),\n\t\tpathFilters: pathFilters,\n\t\textFilters: extFilters,\n\t\twiki: this.wiki,\n\t\tfileInfo: {}\n\t});\n\ttry {\n\t\t$tw.utils.saveTiddlerToFileSync(tiddler,fileInfo);\n\t} catch (err) {\n\t\tconsole.log(\"SaveWikiFolder: Error saving file '\" + fileInfo.filepath + \"', tiddler: '\" + tiddler.fields.title);\n\t}\n};\n\nWikiFolderMaker.prototype.saveJSONFile = function(filename,json) {\n\tthis.saveTextFile(filename,JSON.stringify(json,null,$tw.config.preferences.jsonSpaces));\n};\n\nWikiFolderMaker.prototype.saveTextFile = function(filename,data) {\n\tthis.saveFile(filename,\"utf8\",data);\n};\n\nWikiFolderMaker.prototype.saveFile = function(filename,encoding,data) {\n\tvar filepath = path.resolve(this.wikiFolderPath,filename);\n\t$tw.utils.createFileDirectories(filepath);\n\tfs.writeFileSync(filepath,data,encoding);\n};\n\nexports.Command = Command;\n\n})();\n","type":"application/javascript","module-type":"command"},"$:/core/modules/commands/server.js":{"title":"$:/core/modules/commands/server.js","text":"/*\\\ntitle: $:/core/modules/commands/server.js\ntype: application/javascript\nmodule-type: command\n\nDeprecated legacy command for serving tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Server = require(\"$:/core/modules/server/server.js\").Server;\n\nexports.info = {\n\tname: \"server\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tvar self = this;\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(!$tw.boot.wikiTiddlersPath) {\n\t\t$tw.utils.warning(\"Warning: Wiki folder '\" + $tw.boot.wikiPath + \"' does not exist or is missing a tiddlywiki.info file\");\n\t}\n\t// Set up server\n\tthis.server = new Server({\n\t\twiki: this.commander.wiki,\n\t\tvariables: {\n\t\t\tport: this.params[0],\n\t\t\thost: this.params[6],\n\t\t\t\"root-tiddler\": this.params[1],\n\t\t\t\"root-render-type\": this.params[2],\n\t\t\t\"root-serve-type\": this.params[3],\n\t\t\tusername: this.params[4],\n\t\t\tpassword: this.params[5],\n\t\t\t\"path-prefix\": this.params[7],\n\t\t\t\"debug-level\": this.params[8]\n\t\t}\n\t});\n\tvar nodeServer = this.server.listen();\n\t$tw.hooks.invokeHook(\"th-server-command-post-start\",this.server,nodeServer,\"tiddlywiki\");\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n","type":"application/javascript","module-type":"command"},"$:/core/modules/commands/setfield.js":{"title":"$:/core/modules/commands/setfield.js","text":"/*\\\ntitle: $:/core/modules/commands/setfield.js\ntype: application/javascript\nmodule-type: command\n\nCommand to modify selected tiddlers to set a field to the text of a template tiddler that has been wikified with the selected tiddler as the current tiddler.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nexports.info = {\n\tname: \"setfield\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 4) {\n\t\treturn \"Missing parameters\";\n\t}\n\tvar self = this,\n\t\twiki = this.commander.wiki,\n\t\tfilter = this.params[0],\n\t\tfieldname = this.params[1] || \"text\",\n\t\ttemplatetitle = this.params[2],\n\t\trendertype = this.params[3] || \"text/plain\",\n\t\ttiddlers = wiki.filterTiddlers(filter);\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tvar parser = wiki.parseTiddler(templatetitle),\n\t\t\tnewFields = {},\n\t\t\ttiddler = wiki.getTiddler(title);\n\t\tif(parser) {\n\t\t\tvar widgetNode = wiki.makeWidget(parser,{variables: {currentTiddler: title}});\n\t\t\tvar container = $tw.fakeDocument.createElement(\"div\");\n\t\t\twidgetNode.render(container,null);\n\t\t\tnewFields[fieldname] = rendertype === \"text/html\" ? container.innerHTML : container.textContent;\n\t\t} else {\n\t\t\tnewFields[fieldname] = undefined;\n\t\t}\n\t\twiki.addTiddler(new $tw.Tiddler(tiddler,newFields));\n\t});\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n","type":"application/javascript","module-type":"command"},"$:/core/modules/commands/unpackplugin.js":{"title":"$:/core/modules/commands/unpackplugin.js","text":"/*\\\ntitle: $:/core/modules/commands/unpackplugin.js\ntype: application/javascript\nmodule-type: command\n\nCommand to extract the shadow tiddlers from within a plugin\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"unpackplugin\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 1) {\n\t\treturn \"Missing plugin name\";\n\t}\n\tvar self = this,\n\t\ttitle = this.params[0],\n\t\tpluginData = this.commander.wiki.getTiddlerDataCached(title);\n\tif(!pluginData) {\n\t\treturn \"Plugin '\" + title + \"' not found\";\n\t}\n\t$tw.utils.each(pluginData.tiddlers,function(tiddler) {\n\t\tself.commander.wiki.addTiddler(new $tw.Tiddler(tiddler));\n\t});\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n","type":"application/javascript","module-type":"command"},"$:/core/modules/commands/verbose.js":{"title":"$:/core/modules/commands/verbose.js","text":"/*\\\ntitle: $:/core/modules/commands/verbose.js\ntype: application/javascript\nmodule-type: command\n\nVerbose command\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"verbose\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander) {\n\tthis.params = params;\n\tthis.commander = commander;\n};\n\nCommand.prototype.execute = function() {\n\tthis.commander.verbose = true;\n\t// Output the boot message log\n\tthis.commander.streams.output.write(\"Boot log:\\n  \" + $tw.boot.logMessages.join(\"\\n  \") + \"\\n\");\n\treturn null; // No error\n};\n\nexports.Command = Command;\n\n})();\n","type":"application/javascript","module-type":"command"},"$:/core/modules/commands/version.js":{"title":"$:/core/modules/commands/version.js","text":"/*\\\ntitle: $:/core/modules/commands/version.js\ntype: application/javascript\nmodule-type: command\n\nVersion command\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"version\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander) {\n\tthis.params = params;\n\tthis.commander = commander;\n};\n\nCommand.prototype.execute = function() {\n\tthis.commander.streams.output.write($tw.version + \"\\n\");\n\treturn null; // No error\n};\n\nexports.Command = Command;\n\n})();\n","type":"application/javascript","module-type":"command"},"$:/core/modules/config.js":{"title":"$:/core/modules/config.js","text":"/*\\\ntitle: $:/core/modules/config.js\ntype: application/javascript\nmodule-type: config\n\nCore configuration constants\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.preferences = {};\n\nexports.preferences.notificationDuration = 3 * 1000;\nexports.preferences.jsonSpaces = 4;\n\nexports.textPrimitives = {\n\tupperLetter: \"[A-Z\\u00c0-\\u00d6\\u00d8-\\u00de\\u0150\\u0170]\",\n\tlowerLetter: \"[a-z\\u00df-\\u00f6\\u00f8-\\u00ff\\u0151\\u0171]\",\n\tanyLetter:   \"[A-Za-z0-9\\u00c0-\\u00d6\\u00d8-\\u00de\\u00df-\\u00f6\\u00f8-\\u00ff\\u0150\\u0170\\u0151\\u0171]\",\n\tblockPrefixLetters:\t\"[A-Za-z0-9-_\\u00c0-\\u00d6\\u00d8-\\u00de\\u00df-\\u00f6\\u00f8-\\u00ff\\u0150\\u0170\\u0151\\u0171]\"\n};\n\nexports.textPrimitives.unWikiLink = \"~\";\nexports.textPrimitives.wikiLink = exports.textPrimitives.upperLetter + \"+\" +\n\texports.textPrimitives.lowerLetter + \"+\" +\n\texports.textPrimitives.upperLetter +\n\texports.textPrimitives.anyLetter + \"*\";\n\nexports.htmlEntities = {quot:34, dollar:36, amp:38, apos:39, lt:60, gt:62, nbsp:160, iexcl:161, cent:162, pound:163, curren:164, yen:165, brvbar:166, sect:167, uml:168, copy:169, ordf:170, laquo:171, not:172, shy:173, reg:174, macr:175, deg:176, plusmn:177, sup2:178, sup3:179, acute:180, micro:181, para:182, middot:183, cedil:184, sup1:185, ordm:186, raquo:187, frac14:188, frac12:189, frac34:190, iquest:191, Agrave:192, Aacute:193, Acirc:194, Atilde:195, Auml:196, Aring:197, AElig:198, Ccedil:199, Egrave:200, Eacute:201, Ecirc:202, Euml:203, Igrave:204, Iacute:205, Icirc:206, Iuml:207, ETH:208, Ntilde:209, Ograve:210, Oacute:211, Ocirc:212, Otilde:213, Ouml:214, times:215, Oslash:216, Ugrave:217, Uacute:218, Ucirc:219, Uuml:220, Yacute:221, THORN:222, szlig:223, agrave:224, aacute:225, acirc:226, atilde:227, auml:228, aring:229, aelig:230, ccedil:231, egrave:232, eacute:233, ecirc:234, euml:235, igrave:236, iacute:237, icirc:238, iuml:239, eth:240, ntilde:241, ograve:242, oacute:243, ocirc:244, otilde:245, ouml:246, divide:247, oslash:248, ugrave:249, uacute:250, ucirc:251, uuml:252, yacute:253, thorn:254, yuml:255, OElig:338, oelig:339, Scaron:352, scaron:353, Yuml:376, fnof:402, circ:710, tilde:732, Alpha:913, Beta:914, Gamma:915, Delta:916, Epsilon:917, Zeta:918, Eta:919, Theta:920, Iota:921, Kappa:922, Lambda:923, Mu:924, Nu:925, Xi:926, Omicron:927, Pi:928, Rho:929, Sigma:931, Tau:932, Upsilon:933, Phi:934, Chi:935, Psi:936, Omega:937, alpha:945, beta:946, gamma:947, delta:948, epsilon:949, zeta:950, eta:951, theta:952, iota:953, kappa:954, lambda:955, mu:956, nu:957, xi:958, omicron:959, pi:960, rho:961, sigmaf:962, sigma:963, tau:964, upsilon:965, phi:966, chi:967, psi:968, omega:969, thetasym:977, upsih:978, piv:982, ensp:8194, emsp:8195, thinsp:8201, zwnj:8204, zwj:8205, lrm:8206, rlm:8207, ndash:8211, mdash:8212, lsquo:8216, rsquo:8217, sbquo:8218, ldquo:8220, rdquo:8221, bdquo:8222, dagger:8224, Dagger:8225, bull:8226, hellip:8230, permil:8240, prime:8242, Prime:8243, lsaquo:8249, rsaquo:8250, oline:8254, frasl:8260, nobreak:8288, NoBreak:8288, euro:8364, image:8465, weierp:8472, real:8476, trade:8482, alefsym:8501, larr:8592, uarr:8593, rarr:8594, darr:8595, harr:8596, crarr:8629, lArr:8656, uArr:8657, rArr:8658, dArr:8659, hArr:8660, forall:8704, part:8706, exist:8707, empty:8709, nabla:8711, isin:8712, notin:8713, ni:8715, prod:8719, sum:8721, minus:8722, lowast:8727, radic:8730, prop:8733, infin:8734, ang:8736, and:8743, or:8744, cap:8745, cup:8746, int:8747, there4:8756, sim:8764, cong:8773, asymp:8776, ne:8800, equiv:8801, le:8804, ge:8805, sub:8834, sup:8835, nsub:8836, sube:8838, supe:8839, oplus:8853, otimes:8855, perp:8869, sdot:8901, lceil:8968, rceil:8969, lfloor:8970, rfloor:8971, lang:9001, rang:9002, loz:9674, spades:9824, clubs:9827, hearts:9829, diams:9830 };\n\nexports.htmlVoidElements = \"area,base,br,col,command,embed,hr,img,input,keygen,link,meta,param,source,track,wbr\".split(\",\");\n\nexports.htmlBlockElements = \"address,article,aside,audio,blockquote,canvas,dd,details,div,dl,dt,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,hr,li,nav,ol,p,pre,section,summary,table,tfoot,ul,video\".split(\",\");\n\nexports.htmlUnsafeElements = \"script\".split(\",\");\n\n})();\n","type":"application/javascript","module-type":"config"},"$:/core/modules/deserializers.js":{"title":"$:/core/modules/deserializers.js","text":"/*\\\ntitle: $:/core/modules/deserializers.js\ntype: application/javascript\nmodule-type: tiddlerdeserializer\n\nFunctions to deserialise tiddlers from a block of text\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"application/x-tiddler-html-div\"] = function(text,fields) {\n\treturn [deserializeTiddlerDiv(text,fields)];\n};\n\nexports[\"application/json\"] = function(text,fields) {\n\tvar results = [],\n\t\tincoming = $tw.utils.parseJSONSafe(text,function(err) {\n\t\t\treturn [{\n\t\t\t\ttitle: \"JSON error: \" + err,\n\t\t\t\ttext: \"\"\n\t\t\t}];\n\t\t});\n\tif(!$tw.utils.isArray(incoming)) {\n\t\tincoming = [incoming];\n\t}\n\tfor(var t=0; t<incoming.length; t++) {\n\t\tvar incomingFields = incoming[t],\n\t\t\tfields = {};\n\t\tfor(var f in incomingFields) {\n\t\t\tif(typeof incomingFields[f] === \"string\") {\n\t\t\t\tfields[f] = incomingFields[f];\n\t\t\t}\n\t\t}\n\t\tresults.push(fields);\n\t}\n\treturn results;\n};\n\n/*\nParse an HTML file into tiddlers. There are three possibilities:\n# A TiddlyWiki classic HTML file containing `text/x-tiddlywiki` tiddlers\n# A TiddlyWiki5 HTML file containing `text/vnd.tiddlywiki` tiddlers\n# An ordinary HTML file\n*/\nexports[\"text/html\"] = function(text,fields) {\n\tvar results = [];\n\t// Check if we've got an old-style store area\n\tvar storeAreaMarkerRegExp = /<div id=[\"']?storeArea['\"]?( style=[\"']?display:none;[\"']?)?>/gi,\n\t\tstoreAreaMatch = storeAreaMarkerRegExp.exec(text);\n\tif(storeAreaMatch) {\n\t\t// If so, we've got tiddlers in classic TiddlyWiki format or unencrypted old-style TW5 format\n\t\tresults.push.apply(results,deserializeStoreArea(text,storeAreaMarkerRegExp.lastIndex,!!storeAreaMatch[1],fields));\n\t}\n\t// Check for new-style store areas\n\tvar newStoreAreaMarkerRegExp = /<script class=\"tiddlywiki-tiddler-store\" type=\"([^\"]*)\">/gi,\n\t\tnewStoreAreaMatch = newStoreAreaMarkerRegExp.exec(text),\n\t\thaveHadNewStoreArea = !!newStoreAreaMatch;\n\twhile(newStoreAreaMatch) {\n\t\tresults.push.apply(results,deserializeNewStoreArea(text,newStoreAreaMarkerRegExp.lastIndex,newStoreAreaMatch[1],fields));\n\t\tnewStoreAreaMatch = newStoreAreaMarkerRegExp.exec(text);\n\t}\n\t// Return if we had either an old-style or a new-style store area\n\tif(storeAreaMatch || haveHadNewStoreArea) {\n\t\treturn results;\n\t}\n\t// Otherwise, check whether we've got an encrypted file\n\tvar encryptedStoreArea = $tw.utils.extractEncryptedStoreArea(text);\n\tif(encryptedStoreArea) {\n\t\t// If so, attempt to decrypt it using the current password\n\t\treturn $tw.utils.decryptStoreArea(encryptedStoreArea);\n\t} else {\n\t\t// It's not a TiddlyWiki so we'll return the entire HTML file as a tiddler\n\t\treturn deserializeHtmlFile(text,fields);\n\t}\n};\n\nfunction deserializeHtmlFile(text,fields) {\n\tvar result = {};\n\t$tw.utils.each(fields,function(value,name) {\n\t\tresult[name] = value;\n\t});\n\tresult.text = text;\n\tresult.type = \"text/html\";\n\treturn [result];\n}\n\nfunction deserializeNewStoreArea(text,storeAreaEnd,type,fields) {\n\tvar endOfScriptRegExp = /<\\/script>/gi;\n\tendOfScriptRegExp.lastIndex = storeAreaEnd;\n\tvar match = endOfScriptRegExp.exec(text);\n\tif(match) {\n\t\tvar scriptContent = text.substring(storeAreaEnd,match.index);\n\t\treturn $tw.wiki.deserializeTiddlers(type,scriptContent);\n\t} else {\n\t\treturn [];\n\t}\n}\n\nfunction deserializeStoreArea(text,storeAreaEnd,isTiddlyWiki5,fields) {\n\tvar results = [],\n\t\tendOfDivRegExp = /(<\\/div>\\s*)/gi,\n\t\tstartPos = storeAreaEnd,\n\t\tdefaultType = isTiddlyWiki5 ? undefined : \"text/x-tiddlywiki\";\n\tendOfDivRegExp.lastIndex = startPos;\n\tvar match = endOfDivRegExp.exec(text);\n\twhile(match) {\n\t\tvar endPos = endOfDivRegExp.lastIndex,\n\t\t\ttiddlerFields = deserializeTiddlerDiv(text.substring(startPos,endPos),fields,{type: defaultType});\n\t\tif(!tiddlerFields) {\n\t\t\tbreak;\n\t\t}\n\t\t$tw.utils.each(tiddlerFields,function(value,name) {\n\t\t\tif(typeof value === \"string\") {\n\t\t\t\ttiddlerFields[name] = $tw.utils.htmlDecode(value);\n\t\t\t}\n\t\t});\n\t\tif(tiddlerFields.text !== null) {\n\t\t\tresults.push(tiddlerFields);\n\t\t}\n\t\tstartPos = endPos;\n\t\tmatch = endOfDivRegExp.exec(text);\n\t}\n\treturn results;\n}\n\n/*\nUtility function to parse an old-style tiddler DIV in a *.tid file. It looks like this:\n\n<div title=\"Title\" creator=\"JoeBloggs\" modifier=\"JoeBloggs\" created=\"201102111106\" modified=\"201102111310\" tags=\"myTag [[my long tag]]\">\n<pre>The text of the tiddler (without the expected HTML encoding).\n</pre>\n</div>\n\nNote that the field attributes are HTML encoded, but that the body of the <PRE> tag is not encoded.\n\nWhen these tiddler DIVs are encountered within a TiddlyWiki HTML file then the body is encoded in the usual way.\n*/\nvar deserializeTiddlerDiv = function(text /* [,fields] */) {\n\t// Slot together the default results\n\tvar result = {};\n\tif(arguments.length > 1) {\n\t\tfor(var f=1; f<arguments.length; f++) {\n\t\t\tvar fields = arguments[f];\n\t\t\tfor(var t in fields) {\n\t\t\t\tresult[t] = fields[t];\t\t\n\t\t\t}\n\t\t}\n\t}\n\t// Parse the DIV body\n\tvar startRegExp = /^\\s*<div\\s+([^>]*)>(\\s*<pre>)?/gi,\n\t\tendRegExp,\n\t\tmatch = startRegExp.exec(text);\n\tif(match) {\n\t\t// Old-style DIVs don't have the <pre> tag\n\t\tif(match[2]) {\n\t\t\tendRegExp = /<\\/pre>\\s*<\\/div>\\s*$/gi;\n\t\t} else {\n\t\t\tendRegExp = /<\\/div>\\s*$/gi;\n\t\t}\n\t\tvar endMatch = endRegExp.exec(text);\n\t\tif(endMatch) {\n\t\t\t// Extract the text\n\t\t\tresult.text = text.substring(match.index + match[0].length,endMatch.index);\n\t\t\t// Process the attributes\n\t\t\tvar attrRegExp = /\\s*([^=\\s]+)\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)')/gi,\n\t\t\t\tattrMatch;\n\t\t\tdo {\n\t\t\t\tattrMatch = attrRegExp.exec(match[1]);\n\t\t\t\tif(attrMatch) {\n\t\t\t\t\tvar name = attrMatch[1];\n\t\t\t\t\tvar value = attrMatch[2] !== undefined ? attrMatch[2] : attrMatch[3];\n\t\t\t\t\tresult[name] = value;\n\t\t\t\t}\n\t\t\t} while(attrMatch);\n\t\t\treturn result;\n\t\t}\n\t}\n\treturn undefined;\n};\n\n})();\n","type":"application/javascript","module-type":"tiddlerdeserializer"},"$:/core/modules/editor/engines/framed.js":{"title":"$:/core/modules/editor/engines/framed.js","text":"/*\\\ntitle: $:/core/modules/editor/engines/framed.js\ntype: application/javascript\nmodule-type: library\n\nText editor engine based on a simple input or textarea within an iframe. This is done so that the selection is preserved even when clicking away from the textarea\n\n\\*/\n(function(){\n\n/*jslint node: true,browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar HEIGHT_VALUE_TITLE = \"$:/config/TextEditor/EditorHeight/Height\";\n\nfunction FramedEngine(options) {\n\t// Save our options\n\toptions = options || {};\n\tthis.widget = options.widget;\n\tthis.value = options.value;\n\tthis.parentNode = options.parentNode;\n\tthis.nextSibling = options.nextSibling;\n\t// Create our hidden dummy text area for reading styles\n\tthis.dummyTextArea = this.widget.document.createElement(\"textarea\");\n\tif(this.widget.editClass) {\n\t\tthis.dummyTextArea.className = this.widget.editClass;\n\t}\n\tthis.dummyTextArea.setAttribute(\"hidden\",\"true\");\n\tthis.parentNode.insertBefore(this.dummyTextArea,this.nextSibling);\n\tthis.widget.domNodes.push(this.dummyTextArea);\n\t// Create the iframe\n\tthis.iframeNode = this.widget.document.createElement(\"iframe\");\n\tthis.parentNode.insertBefore(this.iframeNode,this.nextSibling);\n\tthis.iframeDoc = this.iframeNode.contentWindow.document;\n\t// (Firefox requires us to put some empty content in the iframe)\n\tvar paletteTitle = this.widget.wiki.getTiddlerText(\"$:/palette\");\n\tvar colorScheme = (this.widget.wiki.getTiddler(paletteTitle) || {fields: {}}).fields[\"color-scheme\"] || \"light\";\n\tthis.iframeDoc.open();\n\tthis.iframeDoc.write(\"<meta name='color-scheme' content='\" + colorScheme + \"'>\");\n\tthis.iframeDoc.close();\n\t// Style the iframe\n\tthis.iframeNode.className = this.dummyTextArea.className;\n\tthis.iframeNode.style.border = \"none\";\n\tthis.iframeNode.style.padding = \"0\";\n\tthis.iframeNode.style.resize = \"none\";\n\tthis.iframeDoc.body.style.margin = \"0\";\n\tthis.iframeDoc.body.style.padding = \"0\";\n\tthis.widget.domNodes.push(this.iframeNode);\n\t// Construct the textarea or input node\n\tvar tag = this.widget.editTag;\n\tif($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {\n\t\ttag = \"input\";\n\t}\n\tthis.domNode = this.iframeDoc.createElement(tag);\n\t// Set the text\n\tif(this.widget.editTag === \"textarea\") {\n\t\tthis.domNode.appendChild(this.iframeDoc.createTextNode(this.value));\n\t} else {\n\t\tthis.domNode.value = this.value;\n\t}\n\t// Set the attributes\n\tif(this.widget.editType && this.widget.editTag !== \"textarea\") {\n\t\tthis.domNode.setAttribute(\"type\",this.widget.editType);\n\t}\n\tif(this.widget.editPlaceholder) {\n\t\tthis.domNode.setAttribute(\"placeholder\",this.widget.editPlaceholder);\n\t}\n\tif(this.widget.editSize) {\n\t\tthis.domNode.setAttribute(\"size\",this.widget.editSize);\n\t}\n\tif(this.widget.editRows) {\n\t\tthis.domNode.setAttribute(\"rows\",this.widget.editRows);\n\t}\n\tif(this.widget.editTabIndex) {\n\t\tthis.iframeNode.setAttribute(\"tabindex\",this.widget.editTabIndex);\n\t}\n\tif(this.widget.editAutoComplete) {\n\t\tthis.domNode.setAttribute(\"autocomplete\",this.widget.editAutoComplete);\n\t}\n\tif(this.widget.isDisabled === \"yes\") {\n\t\tthis.domNode.setAttribute(\"disabled\",true);\n\t}\n\t// Copy the styles from the dummy textarea\n\tthis.copyStyles();\n\t// Add event listeners\n\t$tw.utils.addEventListeners(this.domNode,[\n\t\t{name: \"click\",handlerObject: this,handlerMethod: \"handleClickEvent\"},\n\t\t{name: \"input\",handlerObject: this,handlerMethod: \"handleInputEvent\"},\n\t\t{name: \"keydown\",handlerObject: this,handlerMethod: \"handleKeydownEvent\"},\n\t\t{name: \"focus\",handlerObject: this,handlerMethod: \"handleFocusEvent\"}\n\t]);\n\t// Add drag and drop event listeners if fileDrop is enabled\n\tif(this.widget.isFileDropEnabled) {\n\t\t$tw.utils.addEventListeners(this.domNode,[\n\t\t\t{name: \"dragenter\",handlerObject: this.widget,handlerMethod: \"handleDragEnterEvent\"},\n\t\t\t{name: \"dragover\",handlerObject: this.widget,handlerMethod: \"handleDragOverEvent\"},\n\t\t\t{name: \"dragleave\",handlerObject: this.widget,handlerMethod: \"handleDragLeaveEvent\"},\n\t\t\t{name: \"dragend\",handlerObject: this.widget,handlerMethod: \"handleDragEndEvent\"},\n\t\t\t{name: \"drop\", handlerObject: this.widget,handlerMethod: \"handleDropEvent\"},\n\t\t\t{name: \"paste\", handlerObject: this.widget,handlerMethod: \"handlePasteEvent\"},\n\t\t\t{name: \"click\",handlerObject: this.widget,handlerMethod: \"handleClickEvent\"}\n\t\t]);\n\t}\n\t// Insert the element into the DOM\n\tthis.iframeDoc.body.appendChild(this.domNode);\n}\n\n/*\nCopy styles from the dummy text area to the textarea in the iframe\n*/\nFramedEngine.prototype.copyStyles = function() {\n\t// Copy all styles\n\t$tw.utils.copyStyles(this.dummyTextArea,this.domNode);\n\t// Override the ones that should not be set the same as the dummy textarea\n\tthis.domNode.style.display = \"block\";\n\tthis.domNode.style.width = \"100%\";\n\tthis.domNode.style.margin = \"0\";\n\t// In Chrome setting -webkit-text-fill-color overrides the placeholder text colour\n\tthis.domNode.style[\"-webkit-text-fill-color\"] = \"currentcolor\";\n\t// Ensure we don't force text direction to LTR\n\tthis.domNode.style.removeProperty(\"direction\");\n};\n\n/*\nSet the text of the engine if it doesn't currently have focus\n*/\nFramedEngine.prototype.setText = function(text,type) {\n\tif(!this.domNode.isTiddlyWikiFakeDom) {\n\t\tif(this.domNode.ownerDocument.activeElement !== this.domNode) {\n\t\t\tthis.updateDomNodeText(text);\n\t\t}\n\t\t// Fix the height if needed\n\t\tthis.fixHeight();\n\t}\n};\n\n/*\nUpdate the DomNode with the new text\n*/\nFramedEngine.prototype.updateDomNodeText = function(text) {\n\ttry {\n\t\tthis.domNode.value = text;\n\t} catch(e) {\n\t\t// Ignore\n\t}\n};\n\n/*\nGet the text of the engine\n*/\nFramedEngine.prototype.getText = function() {\n\treturn this.domNode.value;\n};\n\n/*\nFix the height of textarea to fit content\n*/\nFramedEngine.prototype.fixHeight = function() {\n\t// Make sure styles are updated\n\tthis.copyStyles();\n\t// Adjust height\n\tif(this.widget.editTag === \"textarea\") {\n\t\tif(this.widget.editAutoHeight) {\n\t\t\tif(this.domNode && !this.domNode.isTiddlyWikiFakeDom) {\n\t\t\t\tvar newHeight = $tw.utils.resizeTextAreaToFit(this.domNode,this.widget.editMinHeight);\n\t\t\t\tthis.iframeNode.style.height = newHeight + \"px\";\n\t\t\t}\n\t\t} else {\n\t\t\tvar fixedHeight = parseInt(this.widget.wiki.getTiddlerText(HEIGHT_VALUE_TITLE,\"400px\"),10);\n\t\t\tfixedHeight = Math.max(fixedHeight,20);\n\t\t\tthis.domNode.style.height = fixedHeight + \"px\";\n\t\t\tthis.iframeNode.style.height = fixedHeight + \"px\";\n\t\t}\n\t}\n};\n\n/*\nFocus the engine node\n*/\nFramedEngine.prototype.focus  = function() {\n\tif(this.domNode.focus) {\n\t\tthis.domNode.focus();\n\t}\n\tif(this.domNode.select) {\n\t\t$tw.utils.setSelectionByPosition(this.domNode,this.widget.editFocusSelectFromStart,this.widget.editFocusSelectFromEnd);\n\t}\n};\n\n/*\nHandle a focus event\n*/\nFramedEngine.prototype.handleFocusEvent = function(event) {\n\tif(this.widget.editCancelPopups) {\n\t\t$tw.popup.cancel(0);\n\t}\n};\n\n/*\nHandle a keydown event\n */\nFramedEngine.prototype.handleKeydownEvent = function(event) {\n\tif ($tw.keyboardManager.handleKeydownEvent(event, {onlyPriority: true})) {\n\t\treturn true;\n\t}\n\n\treturn this.widget.handleKeydownEvent(event);\n};\n\n/*\nHandle a click\n*/\nFramedEngine.prototype.handleClickEvent = function(event) {\n\tthis.fixHeight();\n\treturn true;\n};\n\n/*\nHandle a dom \"input\" event which occurs when the text has changed\n*/\nFramedEngine.prototype.handleInputEvent = function(event) {\n\tthis.widget.saveChanges(this.getText());\n\tthis.fixHeight();\n\tif(this.widget.editInputActions) {\n\t\tthis.widget.invokeActionString(this.widget.editInputActions,this,event,{actionValue: this.getText()});\n\t}\n\treturn true;\n};\n\n/*\nCreate a blank structure representing a text operation\n*/\nFramedEngine.prototype.createTextOperation = function() {\n\tvar operation = {\n\t\ttext: this.domNode.value,\n\t\tselStart: this.domNode.selectionStart,\n\t\tselEnd: this.domNode.selectionEnd,\n\t\tcutStart: null,\n\t\tcutEnd: null,\n\t\treplacement: null,\n\t\tnewSelStart: null,\n\t\tnewSelEnd: null\n\t};\n\toperation.selection = operation.text.substring(operation.selStart,operation.selEnd);\n\treturn operation;\n};\n\n/*\nExecute a text operation\n*/\nFramedEngine.prototype.executeTextOperation = function(operation) {\n\t// Perform the required changes to the text area and the underlying tiddler\n\tvar newText = operation.text;\n\tif(operation.replacement !== null) {\n\t\tnewText = operation.text.substring(0,operation.cutStart) + operation.replacement + operation.text.substring(operation.cutEnd);\n\t\t// Attempt to use a execCommand to modify the value of the control\n\t\tif(this.iframeDoc.queryCommandSupported(\"insertText\") && this.iframeDoc.queryCommandSupported(\"delete\") && !$tw.browser.isFirefox) {\n\t\t\tthis.domNode.focus();\n\t\t\tthis.domNode.setSelectionRange(operation.cutStart,operation.cutEnd);\n\t\t\tif(operation.replacement === \"\") {\n\t\t\t\tthis.iframeDoc.execCommand(\"delete\",false,\"\");\n\t\t\t} else {\n\t\t\t\tthis.iframeDoc.execCommand(\"insertText\",false,operation.replacement);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.domNode.value = newText;\n\t\t}\n\t\tthis.domNode.focus();\n\t\tthis.domNode.setSelectionRange(operation.newSelStart,operation.newSelEnd);\n\t}\n\tthis.domNode.focus();\n\treturn newText;\n};\n\nexports.FramedEngine = FramedEngine;\n\n})();\n","type":"application/javascript","module-type":"library"},"$:/core/modules/editor/engines/simple.js":{"title":"$:/core/modules/editor/engines/simple.js","text":"/*\\\ntitle: $:/core/modules/editor/engines/simple.js\ntype: application/javascript\nmodule-type: library\n\nText editor engine based on a simple input or textarea tag\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar HEIGHT_VALUE_TITLE = \"$:/config/TextEditor/EditorHeight/Height\";\n\nfunction SimpleEngine(options) {\n\t// Save our options\n\toptions = options || {};\n\tthis.widget = options.widget;\n\tthis.value = options.value;\n\tthis.parentNode = options.parentNode;\n\tthis.nextSibling = options.nextSibling;\n\t// Construct the textarea or input node\n\tvar tag = this.widget.editTag;\n\tif($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {\n\t\ttag = \"input\";\n\t}\n\tthis.domNode = this.widget.document.createElement(tag);\n\t// Set the text\n\tif(this.widget.editTag === \"textarea\") {\n\t\tthis.domNode.appendChild(this.widget.document.createTextNode(this.value));\n\t} else {\n\t\tthis.domNode.value = this.value;\n\t}\n\t// Set the attributes\n\tif(this.widget.editType && this.widget.editTag !== \"textarea\") {\n\t\tthis.domNode.setAttribute(\"type\",this.widget.editType);\n\t}\n\tif(this.widget.editPlaceholder) {\n\t\tthis.domNode.setAttribute(\"placeholder\",this.widget.editPlaceholder);\n\t}\n\tif(this.widget.editSize) {\n\t\tthis.domNode.setAttribute(\"size\",this.widget.editSize);\n\t}\n\tif(this.widget.editRows) {\n\t\tthis.domNode.setAttribute(\"rows\",this.widget.editRows);\n\t}\n\tif(this.widget.editClass) {\n\t\tthis.domNode.className = this.widget.editClass;\n\t}\n\tif(this.widget.editTabIndex) {\n\t\tthis.domNode.setAttribute(\"tabindex\",this.widget.editTabIndex);\n\t}\n\tif(this.widget.editAutoComplete) {\n\t\tthis.domNode.setAttribute(\"autocomplete\",this.widget.editAutoComplete);\n\t}\n\tif(this.widget.isDisabled === \"yes\") {\n\t\tthis.domNode.setAttribute(\"disabled\",true);\n\t}\n\t// Add an input event handler\n\t$tw.utils.addEventListeners(this.domNode,[\n\t\t{name: \"focus\", handlerObject: this, handlerMethod: \"handleFocusEvent\"},\n\t\t{name: \"input\", handlerObject: this, handlerMethod: \"handleInputEvent\"}\n\t]);\n\t// Insert the element into the DOM\n\tthis.parentNode.insertBefore(this.domNode,this.nextSibling);\n\tthis.widget.domNodes.push(this.domNode);\n}\n\n/*\nSet the text of the engine if it doesn't currently have focus\n*/\nSimpleEngine.prototype.setText = function(text,type) {\n\tif(!this.domNode.isTiddlyWikiFakeDom) {\n\t\tif(this.domNode.ownerDocument.activeElement !== this.domNode || text === \"\") {\n\t\t\tthis.updateDomNodeText(text);\n\t\t}\n\t\t// Fix the height if needed\n\t\tthis.fixHeight();\n\t}\n};\n\n/*\nUpdate the DomNode with the new text\n*/\nSimpleEngine.prototype.updateDomNodeText = function(text) {\n\ttry {\n\t\tthis.domNode.value = text;\n\t} catch(e) {\n\t\t// Ignore\n\t}\n};\n\n/*\nGet the text of the engine\n*/\nSimpleEngine.prototype.getText = function() {\n\treturn this.domNode.value;\n};\n\n/*\nFix the height of textarea to fit content\n*/\nSimpleEngine.prototype.fixHeight = function() {\n\tif(this.widget.editTag === \"textarea\") {\n\t\tif(this.widget.editAutoHeight) {\n\t\t\tif(this.domNode && !this.domNode.isTiddlyWikiFakeDom) {\n\t\t\t\t$tw.utils.resizeTextAreaToFit(this.domNode,this.widget.editMinHeight);\n\t\t\t}\n\t\t} else {\n\t\t\tvar fixedHeight = parseInt(this.widget.wiki.getTiddlerText(HEIGHT_VALUE_TITLE,\"400px\"),10);\n\t\t\tfixedHeight = Math.max(fixedHeight,20);\n\t\t\tthis.domNode.style.height = fixedHeight + \"px\";\n\t\t}\n\t}\n};\n\n/*\nFocus the engine node\n*/\nSimpleEngine.prototype.focus = function() {\n\tif(this.domNode.focus) {\n\t\tthis.domNode.focus();\n\t}\n\tif(this.domNode.select) {\n\t\t$tw.utils.setSelectionByPosition(this.domNode,this.widget.editFocusSelectFromStart,this.widget.editFocusSelectFromEnd);\n\t}\n};\n\n/*\nHandle a dom \"input\" event which occurs when the text has changed\n*/\nSimpleEngine.prototype.handleInputEvent = function(event) {\n\tthis.widget.saveChanges(this.getText());\n\tthis.fixHeight();\n\tif(this.widget.editInputActions) {\n\t\tthis.widget.invokeActionString(this.widget.editInputActions,this,event,{actionValue: this.getText()});\n\t}\n\treturn true;\n};\n\n/*\nHandle a dom \"focus\" event\n*/\nSimpleEngine.prototype.handleFocusEvent = function(event) {\n\tif(this.widget.editCancelPopups) {\n\t\t$tw.popup.cancel(0);\n\t}\n\tif(this.widget.editFocusPopup) {\n\t\t$tw.popup.triggerPopup({\n\t\t\tdomNode: this.domNode,\n\t\t\ttitle: this.widget.editFocusPopup,\n\t\t\twiki: this.widget.wiki,\n\t\t\tforce: true\n\t\t});\n\t}\n\treturn true;\n};\n\n/*\nCreate a blank structure representing a text operation\n*/\nSimpleEngine.prototype.createTextOperation = function() {\n\treturn null;\n};\n\n/*\nExecute a text operation\n*/\nSimpleEngine.prototype.executeTextOperation = function(operation) {\n};\n\nexports.SimpleEngine = SimpleEngine;\n\n})();\n","type":"application/javascript","module-type":"library"},"$:/core/modules/editor/factory.js":{"title":"$:/core/modules/editor/factory.js","text":"/*\\\ntitle: $:/core/modules/editor/factory.js\ntype: application/javascript\nmodule-type: library\n\nFactory for constructing text editor widgets with specified engines for the toolbar and non-toolbar cases\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar DEFAULT_MIN_TEXT_AREA_HEIGHT = \"100px\"; // Minimum height of textareas in pixels\n\n// Configuration tiddlers\nvar HEIGHT_MODE_TITLE = \"$:/config/TextEditor/EditorHeight/Mode\";\nvar ENABLE_TOOLBAR_TITLE = \"$:/config/TextEditor/EnableToolbar\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nfunction editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {\n\n\tvar EditTextWidget = function(parseTreeNode,options) {\n\t\t// Initialise the editor operations if they've not been done already\n\t\tif(!this.editorOperations) {\n\t\t\tEditTextWidget.prototype.editorOperations = {};\n\t\t\t$tw.modules.applyMethods(\"texteditoroperation\",this.editorOperations);\n\t\t}\n\t\tthis.initialise(parseTreeNode,options);\n\t};\n\n\t/*\n\tInherit from the base widget class\n\t*/\n\tEditTextWidget.prototype = new Widget();\n\n\t/*\n\tRender this widget into the DOM\n\t*/\n\tEditTextWidget.prototype.render = function(parent,nextSibling) {\n\t\t// Save the parent dom node\n\t\tthis.parentDomNode = parent;\n\t\t// Compute our attributes\n\t\tthis.computeAttributes();\n\t\t// Execute our logic\n\t\tthis.execute();\n\t\t// Create the wrapper for the toolbar and render its content\n\t\tif(this.editShowToolbar) {\n\t\t\tthis.toolbarNode = this.document.createElement(\"div\");\n\t\t\tthis.toolbarNode.className = \"tc-editor-toolbar\";\n\t\t\tparent.insertBefore(this.toolbarNode,nextSibling);\n\t\t\tthis.renderChildren(this.toolbarNode,null);\n\t\t\tthis.domNodes.push(this.toolbarNode);\n\t\t}\n\t\t// Create our element\n\t\tvar editInfo = this.getEditInfo(),\n\t\t\tEngine = this.editShowToolbar ? toolbarEngine : nonToolbarEngine;\n\t\tthis.engine = new Engine({\n\t\t\t\twidget: this,\n\t\t\t\tvalue: editInfo.value,\n\t\t\t\ttype: editInfo.type,\n\t\t\t\tparentNode: parent,\n\t\t\t\tnextSibling: nextSibling\n\t\t\t});\n\t\t// Call the postRender hook\n\t\tif(this.postRender) {\n\t\t\tthis.postRender();\n\t\t}\n\t\t// Fix height\n\t\tthis.engine.fixHeight();\n\t\t// Focus if required\n\t\tif(this.editFocus === \"true\" || this.editFocus === \"yes\") {\n\t\t\tthis.engine.focus();\n\t\t}\n\t\t// Add widget message listeners\n\t\tthis.addEventListeners([\n\t\t\t{type: \"tm-edit-text-operation\", handler: \"handleEditTextOperationMessage\"}\n\t\t]);\n\t};\n\n\t/*\n\tGet the tiddler being edited and current value\n\t*/\n\tEditTextWidget.prototype.getEditInfo = function() {\n\t\t// Get the edit value\n\t\tvar self = this,\n\t\t\tvalue,\n\t\t\ttype = \"text/plain\",\n\t\t\tupdate;\n\t\tif(this.editIndex) {\n\t\t\tvalue = this.wiki.extractTiddlerDataItem(this.editTitle,this.editIndex,this.editDefault);\n\t\t\tupdate = function(value) {\n\t\t\t\tvar data = self.wiki.getTiddlerData(self.editTitle,{});\n\t\t\t\tif(data[self.editIndex] !== value) {\n\t\t\t\t\tdata[self.editIndex] = value;\n\t\t\t\t\tself.wiki.setTiddlerData(self.editTitle,data);\n\t\t\t\t}\n\t\t\t};\n\t\t} else {\n\t\t\t// Get the current tiddler and the field name\n\t\t\tvar tiddler = this.wiki.getTiddler(this.editTitle);\n\t\t\tif(tiddler) {\n\t\t\t\t// If we've got a tiddler, the value to display is the field string value\n\t\t\t\tif(tiddler.hasField(this.editField)) {\n\t\t\t\t\tvalue = tiddler.getFieldString(this.editField);\n\t\t\t\t} else {\n\t\t\t\t\tvalue = this.editDefault || \"\";\n\t\t\t\t}\n\t\t\t\tif(this.editField === \"text\") {\n\t\t\t\t\ttype = tiddler.fields.type || \"text/vnd.tiddlywiki\";\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Otherwise, we need to construct a default value for the editor\n\t\t\t\tswitch(this.editField) {\n\t\t\t\t\tcase \"text\":\n\t\t\t\t\t\tvalue = \"\";\n\t\t\t\t\t\ttype = \"text/vnd.tiddlywiki\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"title\":\n\t\t\t\t\t\tvalue = this.editTitle;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tvalue = \"\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif(this.editDefault !== undefined) {\n\t\t\t\t\tvalue = this.editDefault;\n\t\t\t\t}\n\t\t\t}\n\t\t\tupdate = function(value) {\n\t\t\t\tvar tiddler = self.wiki.getTiddler(self.editTitle),\n\t\t\t\t\tupdateFields = {\n\t\t\t\t\t\ttitle: self.editTitle\n\t\t\t\t\t};\n\t\t\t\tupdateFields[self.editField] = value;\n\t\t\t\tself.wiki.addTiddler(new $tw.Tiddler(self.wiki.getCreationFields(),tiddler,updateFields,self.wiki.getModificationFields()));\n\t\t\t};\n\t\t}\n\t\tif(this.editType) {\n\t\t\ttype = this.editType;\n\t\t}\n\t\treturn {value: value || \"\", type: type, update: update};\n\t};\n\n\t/*\n\tHandle an edit text operation message from the toolbar\n\t*/\n\tEditTextWidget.prototype.handleEditTextOperationMessage = function(event) {\n\t\t// Prepare information about the operation\n\t\tvar operation = this.engine.createTextOperation();\n\t\t// Invoke the handler for the selected operation\n\t\tvar handler = this.editorOperations[event.param];\n\t\tif(handler) {\n\t\t\thandler.call(this,event,operation);\n\t\t}\n\t\t// Execute the operation via the engine\n\t\tvar newText = this.engine.executeTextOperation(operation);\n\t\t// Fix the tiddler height and save changes\n\t\tthis.engine.fixHeight();\n\t\tthis.saveChanges(newText);\n\t};\n\n\t/*\n\tCompute the internal state of the widget\n\t*/\n\tEditTextWidget.prototype.execute = function() {\n\t\t// Get our parameters\n\t\tthis.editTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\t\tthis.editField = this.getAttribute(\"field\",\"text\");\n\t\tthis.editIndex = this.getAttribute(\"index\");\n\t\tthis.editDefault = this.getAttribute(\"default\");\n\t\tthis.editClass = this.getAttribute(\"class\");\n\t\tthis.editPlaceholder = this.getAttribute(\"placeholder\");\n\t\tthis.editSize = this.getAttribute(\"size\");\n\t\tthis.editRows = this.getAttribute(\"rows\");\n\t\tthis.editAutoHeight = this.wiki.getTiddlerText(HEIGHT_MODE_TITLE,\"auto\");\n\t\tthis.editAutoHeight = this.getAttribute(\"autoHeight\",this.editAutoHeight === \"auto\" ? \"yes\" : \"no\") === \"yes\";\n\t\tthis.editMinHeight = this.getAttribute(\"minHeight\",DEFAULT_MIN_TEXT_AREA_HEIGHT);\n\t\tthis.editFocusPopup = this.getAttribute(\"focusPopup\");\n\t\tthis.editFocus = this.getAttribute(\"focus\");\n\t\tthis.editFocusSelectFromStart = $tw.utils.parseNumber(this.getAttribute(\"focusSelectFromStart\",\"0\"));\n\t\tthis.editFocusSelectFromEnd = $tw.utils.parseNumber(this.getAttribute(\"focusSelectFromEnd\",\"0\"));\n\t\tthis.editTabIndex = this.getAttribute(\"tabindex\");\n\t\tthis.editCancelPopups = this.getAttribute(\"cancelPopups\",\"\") === \"yes\";\n\t\tthis.editInputActions = this.getAttribute(\"inputActions\");\n\t\tthis.editRefreshTitle = this.getAttribute(\"refreshTitle\");\n\t\tthis.editAutoComplete = this.getAttribute(\"autocomplete\");\n\t\tthis.isDisabled = this.getAttribute(\"disabled\",\"no\");\n\t\tthis.isFileDropEnabled = this.getAttribute(\"fileDrop\",\"no\") === \"yes\";\n\t\t// Get the default editor element tag and type\n\t\tvar tag,type;\n\t\tif(this.editField === \"text\") {\n\t\t\ttag = \"textarea\";\n\t\t} else {\n\t\t\ttag = \"input\";\n\t\t\tvar fieldModule = $tw.Tiddler.fieldModules[this.editField];\n\t\t\tif(fieldModule && fieldModule.editTag) {\n\t\t\t\ttag = fieldModule.editTag;\n\t\t\t}\n\t\t\tif(fieldModule && fieldModule.editType) {\n\t\t\t\ttype = fieldModule.editType;\n\t\t\t}\n\t\t\ttype = type || \"text\";\n\t\t}\n\t\t// Get the rest of our parameters\n\t\tthis.editTag = this.getAttribute(\"tag\",tag) || \"input\";\n\t\tthis.editType = this.getAttribute(\"type\",type);\n\t\t// Make the child widgets\n\t\tthis.makeChildWidgets();\n\t\t// Determine whether to show the toolbar\n\t\tthis.editShowToolbar = this.wiki.getTiddlerText(ENABLE_TOOLBAR_TITLE,\"yes\");\n\t\tthis.editShowToolbar = (this.editShowToolbar === \"yes\") && !!(this.children && this.children.length > 0) && (!this.document.isTiddlyWikiFakeDom);\n\t};\n\n\t/*\n\tSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n\t*/\n\tEditTextWidget.prototype.refresh = function(changedTiddlers) {\n\t\tvar changedAttributes = this.computeAttributes();\n\t\t// Completely rerender if any of our attributes have changed\n\t\tif(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes[\"default\"] || changedAttributes[\"class\"] || changedAttributes.placeholder || changedAttributes.size || changedAttributes.autoHeight || changedAttributes.minHeight || changedAttributes.focusPopup ||  changedAttributes.rows || changedAttributes.tabindex || changedAttributes.cancelPopups || changedAttributes.inputActions || changedAttributes.refreshTitle || changedAttributes.autocomplete || changedTiddlers[HEIGHT_MODE_TITLE] || changedTiddlers[ENABLE_TOOLBAR_TITLE] || changedTiddlers[\"$:/palette\"] || changedAttributes.disabled || changedAttributes.fileDrop) {\n\t\t\tthis.refreshSelf();\n\t\t\treturn true;\n\t\t} else if (changedTiddlers[this.editRefreshTitle]) {\n\t\t\tthis.engine.updateDomNodeText(this.getEditInfo().value);\n\t\t} else if(changedTiddlers[this.editTitle]) {\n\t\t\tvar editInfo = this.getEditInfo();\n\t\t\tthis.updateEditor(editInfo.value,editInfo.type);\n\t\t}\n\t\tthis.engine.fixHeight();\n\t\tif(this.editShowToolbar) {\n\t\t\treturn this.refreshChildren(changedTiddlers);\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t};\n\n\t/*\n\tUpdate the editor with new text. This method is separate from updateEditorDomNode()\n\tso that subclasses can override updateEditor() and still use updateEditorDomNode()\n\t*/\n\tEditTextWidget.prototype.updateEditor = function(text,type) {\n\t\tthis.updateEditorDomNode(text,type);\n\t};\n\n\t/*\n\tUpdate the editor dom node with new text\n\t*/\n\tEditTextWidget.prototype.updateEditorDomNode = function(text,type) {\n\t\tthis.engine.setText(text,type);\n\t};\n\n\t/*\n\tSave changes back to the tiddler store\n\t*/\n\tEditTextWidget.prototype.saveChanges = function(text) {\n\t\tvar editInfo = this.getEditInfo();\n\t\tif(text !== editInfo.value) {\n\t\t\teditInfo.update(text);\n\t\t}\n\t};\n\n\t/*\n\tHandle a dom \"keydown\" event, which we'll bubble up to our container for the keyboard widgets benefit\n\t*/\n\tEditTextWidget.prototype.handleKeydownEvent = function(event) {\n\t\t// Check for a keyboard shortcut\n\t\tif(this.toolbarNode) {\n\t\t\tvar shortcutElements = this.toolbarNode.querySelectorAll(\"[data-tw-keyboard-shortcut]\");\n\t\t\tfor(var index=0; index<shortcutElements.length; index++) {\n\t\t\t\tvar el = shortcutElements[index],\n\t\t\t\t\tshortcutData = el.getAttribute(\"data-tw-keyboard-shortcut\"),\n\t\t\t\t\tkeyInfoArray = $tw.keyboardManager.parseKeyDescriptors(shortcutData,{\n\t\t\t\t\t\twiki: this.wiki\n\t\t\t\t\t});\n\t\t\t\tif($tw.keyboardManager.checkKeyDescriptors(event,keyInfoArray)) {\n\t\t\t\t\tvar clickEvent = this.document.createEvent(\"Events\");\n\t\t\t\t    clickEvent.initEvent(\"click\",true,false);\n\t\t\t\t    el.dispatchEvent(clickEvent);\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Propogate the event to the container\n\t\tif(this.propogateKeydownEvent(event)) {\n\t\t\t// Ignore the keydown if it was already handled\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\t\treturn true;\n\t\t}\n\t\t// Otherwise, process the keydown normally\n\t\treturn false;\n\t};\n\n\t/*\n\tPropogate keydown events to our container for the keyboard widgets benefit\n\t*/\n\tEditTextWidget.prototype.propogateKeydownEvent = function(event) {\n\t\tvar newEvent = this.cloneEvent(event,[\"keyCode\",\"code\",\"which\",\"key\",\"metaKey\",\"ctrlKey\",\"altKey\",\"shiftKey\"]);\n\t\treturn !this.parentDomNode.dispatchEvent(newEvent);\n\t};\n\n\tEditTextWidget.prototype.cloneEvent = function(event,propertiesToCopy) {\n\t\tvar propertiesToCopy = propertiesToCopy || [],\n\t\t\tnewEvent = this.document.createEventObject ? this.document.createEventObject() : this.document.createEvent(\"Events\");\n\t\tif(newEvent.initEvent) {\n\t\t\tnewEvent.initEvent(event.type, true, true);\n\t\t}\n\t\t$tw.utils.each(propertiesToCopy,function(prop){\n\t\t\tnewEvent[prop] = event[prop];\n\t\t});\n\t\treturn newEvent;\n\t};\n\n\tEditTextWidget.prototype.dispatchDOMEvent = function(newEvent) {\n\t\tvar dispatchNode = this.engine.iframeNode || this.engine.parentNode;\n\t\treturn dispatchNode.dispatchEvent(newEvent);\n\t};\n\n\t/*\n\tPropogate drag and drop events with File data to our container for the dropzone widgets benefit.\n\tIf there are no Files, let the browser handle it.\n\t*/\n\tEditTextWidget.prototype.handleDropEvent = function(event) {\n\t\tif($tw.utils.dragEventContainsFiles(event)) {\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\t\tthis.dispatchDOMEvent(this.cloneEvent(event,[\"dataTransfer\"]));\n\t\t} \n\t};\n\n\tEditTextWidget.prototype.handlePasteEvent = function(event) {\n\t\tif(event.clipboardData && event.clipboardData.files && event.clipboardData.files.length) {\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\t\tthis.dispatchDOMEvent(this.cloneEvent(event,[\"clipboardData\"]));\n\t\t}\n\t};\n\n\tEditTextWidget.prototype.handleDragEnterEvent = function(event) {\n\t\tif($tw.utils.dragEventContainsFiles(event)) {\n\t\t\t// Ignore excessive events fired by FF when entering and leaving text nodes in a text area.\n\t\t\tif( event.relatedTarget && (event.relatedTarget.nodeType === 3 || event.target === event.relatedTarget)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tevent.preventDefault();\n\t\t\treturn this.dispatchDOMEvent(this.cloneEvent(event,[\"dataTransfer\"]));\n\t\t}\n\t\treturn true;\n\t};\n\n\tEditTextWidget.prototype.handleDragOverEvent = function(event) {\n\t\tif($tw.utils.dragEventContainsFiles(event)) {\n\t\t\t// Call preventDefault() in browsers that default to not allowing drop events on textarea\n\t\t\tif($tw.browser.isFirefox || $tw.browser.isIE) {\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\t\t\tevent.dataTransfer.dropEffect = \"copy\";\n\t\t\treturn this.dispatchDOMEvent(this.cloneEvent(event,[\"dataTransfer\"]));\n\t\t}\n\t\treturn true;\n\t};\n\n\tEditTextWidget.prototype.handleDragLeaveEvent = function(event) {\n\t\t// Ignore excessive events fired by FF when entering and leaving text nodes in a text area.\n\t\tif(event.relatedTarget && ((event.relatedTarget.nodeType === 3) || (event.target === event.relatedTarget))) {\n\t\t\treturn true;\n\t\t}\n\t\tevent.preventDefault();\n\t\tthis.dispatchDOMEvent(this.cloneEvent(event,[\"dataTransfer\"]));\n\t};\n\n\tEditTextWidget.prototype.handleDragEndEvent = function(event) {\n\t\tthis.dispatchDOMEvent(this.cloneEvent(event));\n\t};\n\n\tEditTextWidget.prototype.handleClickEvent = function(event) {\n\t\treturn !this.dispatchDOMEvent(this.cloneEvent(event));\n\t};\n\n\treturn EditTextWidget;\n}\n\nexports.editTextWidgetFactory = editTextWidgetFactory;\n\n})();\n","type":"application/javascript","module-type":"library"},"$:/core/modules/editor/operations/bitmap/clear.js":{"title":"$:/core/modules/editor/operations/bitmap/clear.js","text":"/*\\\ntitle: $:/core/modules/editor/operations/bitmap/clear.js\ntype: application/javascript\nmodule-type: bitmapeditoroperation\n\nBitmap editor operation to clear the image\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"clear\"] = function(event) {\n\tvar ctx = this.canvasDomNode.getContext(\"2d\");\n\tctx.globalAlpha = 1;\n\tctx.fillStyle = event.paramObject.colour || \"white\";\n\tctx.fillRect(0,0,this.canvasDomNode.width,this.canvasDomNode.height);\n\t// Save changes\n\tthis.strokeEnd();\n};\n\n})();\n","type":"application/javascript","module-type":"bitmapeditoroperation"},"$:/core/modules/editor/operations/bitmap/resize.js":{"title":"$:/core/modules/editor/operations/bitmap/resize.js","text":"/*\\\ntitle: $:/core/modules/editor/operations/bitmap/resize.js\ntype: application/javascript\nmodule-type: bitmapeditoroperation\n\nBitmap editor operation to resize the image\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"resize\"] = function(event) {\n\t// Get the new width\n\tvar newWidth = parseInt(event.paramObject.width || this.canvasDomNode.width,10),\n\t\tnewHeight = parseInt(event.paramObject.height || this.canvasDomNode.height,10);\n\t// Update if necessary\n\tif(newWidth > 0 && newHeight > 0 && !(newWidth === this.currCanvas.width && newHeight === this.currCanvas.height)) {\n\t\tthis.changeCanvasSize(newWidth,newHeight);\n\t}\n\t// Update the input controls\n\tthis.refreshToolbar();\n\t// Save the image into the tiddler\n\tthis.saveChanges();\n};\n\n})();\n","type":"application/javascript","module-type":"bitmapeditoroperation"},"$:/core/modules/editor/operations/bitmap/rotate-left.js":{"title":"$:/core/modules/editor/operations/bitmap/rotate-left.js","text":"/*\\\ntitle: $:/core/modules/editor/operations/bitmap/rotate-left.js\ntype: application/javascript\nmodule-type: bitmapeditoroperation\n\nBitmap editor operation to rotate the image left by 90 degrees\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"rotate-left\"] = function(event) {\n\t// Rotate the canvas left by 90 degrees\n\tthis.rotateCanvasLeft();\n\t// Update the input controls\n\tthis.refreshToolbar();\n\t// Save the image into the tiddler\n\tthis.saveChanges();\n};\n\n})();\n","type":"application/javascript","module-type":"bitmapeditoroperation"},"$:/core/modules/editor/operations/text/excise.js":{"title":"$:/core/modules/editor/operations/text/excise.js","text":"/*\\\ntitle: $:/core/modules/editor/operations/text/excise.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to excise the selection to a new tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nfunction isMarkdown(mediaType) {\n\treturn mediaType === 'text/markdown' || mediaType === 'text/x-markdown';\n}\n\nexports[\"excise\"] = function(event,operation) {\n\tvar editTiddler = this.wiki.getTiddler(this.editTitle),\n\t\teditTiddlerTitle = this.editTitle,\n\t\twikiLinks = !isMarkdown(editTiddler.fields.type),\n\t\texcisionBaseTitle = $tw.language.getString(\"Buttons/Excise/DefaultTitle\");\n\tif(editTiddler && editTiddler.fields[\"draft.of\"]) {\n\t\teditTiddlerTitle = editTiddler.fields[\"draft.of\"];\n\t}\n\tvar excisionTitle = event.paramObject.title || this.wiki.generateNewTitle(excisionBaseTitle);\n\tthis.wiki.addTiddler(new $tw.Tiddler(\n\t\tthis.wiki.getCreationFields(),\n\t\tthis.wiki.getModificationFields(),\n\t\t{\n\t\t\ttitle: excisionTitle,\n\t\t\ttext: operation.selection,\n\t\t\ttags: event.paramObject.tagnew === \"yes\" ?  [editTiddlerTitle] : [],\n\t\t\ttype: editTiddler.fields.type\n\t\t}\n\t));\n\toperation.replacement = excisionTitle;\n\tswitch(event.paramObject.type || \"transclude\") {\n\t\tcase \"transclude\":\n\t\t\toperation.replacement = \"{{\" + operation.replacement+ \"}}\";\n\t\t\tbreak;\n\t\tcase \"link\":\n\t\t\toperation.replacement = wikiLinks ? \"[[\" + operation.replacement+ \"]]\"\n\t\t\t\t: (\"[\" + operation.replacement + \"](<#\" + operation.replacement + \">)\");\n\t\t\tbreak;\n\t\tcase \"macro\":\n\t\t\toperation.replacement = \"<<\" + (event.paramObject.macro || \"translink\") + \" \\\"\\\"\\\"\" + operation.replacement + \"\\\"\\\"\\\">>\";\n\t\t\tbreak;\n\t}\n\toperation.cutStart = operation.selStart;\n\toperation.cutEnd = operation.selEnd;\n\toperation.newSelStart = operation.selStart;\n\toperation.newSelEnd = operation.selStart + operation.replacement.length;\n};\n\n})();\n","type":"application/javascript","module-type":"texteditoroperation"},"$:/core/modules/editor/operations/text/focus-editor.js":{"title":"$:/core/modules/editor/operations/text/focus-editor.js","text":"/*\\\ntitle: $:/core/modules/editor/operations/text/focus-editor.js\ntype: application/javascript\nmodule-type: texteditoroperation\nSimply focus the Text editor\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"focus-editor\"] = function(event,operation) {\n\toperation = null;\n};\n\n})();","type":"application/javascript","module-type":"texteditoroperation"},"$:/core/modules/editor/operations/text/insert-text.js":{"title":"$:/core/modules/editor/operations/text/insert-text.js","text":"/*\\\ntitle: $:/core/modules/editor/operations/text/insert-text.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation insert text at the caret position. If there is a selection it is replaced.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"insert-text\"] = function(event,operation) {\n\toperation.replacement = event.paramObject.text;\n\toperation.cutStart = operation.selStart;\n\toperation.cutEnd = operation.selEnd;\n\toperation.newSelStart = operation.selStart + operation.replacement.length;\n\toperation.newSelEnd = operation.newSelStart;\n};\n\n})();\n","type":"application/javascript","module-type":"texteditoroperation"},"$:/core/modules/editor/operations/text/make-link.js":{"title":"$:/core/modules/editor/operations/text/make-link.js","text":"/*\\\ntitle: $:/core/modules/editor/operations/text/make-link.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to make a link\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"make-link\"] = function(event,operation) {\n\tif(operation.selection) {\n\t\toperation.replacement = \"[[\" + operation.selection + \"|\" + event.paramObject.text + \"]]\";\n\t\toperation.cutStart = operation.selStart;\n\t\toperation.cutEnd = operation.selEnd;\n\t} else {\n\t\toperation.replacement = \"[[\" + event.paramObject.text + \"]]\";\n\t\toperation.cutStart = operation.selStart;\n\t\toperation.cutEnd = operation.selEnd;\n\t}\n\toperation.newSelStart = operation.selStart + operation.replacement.length;\n\toperation.newSelEnd = operation.newSelStart;\n};\n\n})();\n","type":"application/javascript","module-type":"texteditoroperation"},"$:/core/modules/editor/operations/text/prefix-lines.js":{"title":"$:/core/modules/editor/operations/text/prefix-lines.js","text":"/*\\\ntitle: $:/core/modules/editor/operations/text/prefix-lines.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to add a prefix to the selected lines\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"prefix-lines\"] = function(event,operation) {\n\tvar targetCount = parseInt(event.paramObject.count + \"\",10);\n\t// Cut just past the preceding line break, or the start of the text\n\toperation.cutStart = $tw.utils.findPrecedingLineBreak(operation.text,operation.selStart);\n\t// Cut to just past the following line break, or to the end of the text\n\toperation.cutEnd = $tw.utils.findFollowingLineBreak(operation.text,operation.selEnd);\n\t// Compose the required prefix\n\tvar prefix = $tw.utils.repeat(event.paramObject.character,targetCount);\n\t// Process each line\n\tvar lines = operation.text.substring(operation.cutStart,operation.cutEnd).split(/\\r?\\n/mg);\n\t$tw.utils.each(lines,function(line,index) {\n\t\t// Remove and count any existing prefix characters\n\t\tvar count = 0;\n\t\twhile($tw.utils.startsWith(line,event.paramObject.character)) {\n\t\t\tline = line.substring(event.paramObject.character.length);\n\t\t\tcount++;\n\t\t}\n\t\t// Remove any whitespace\n\t\twhile(line.charAt(0) === \" \") {\n\t\t\tline = line.substring(1);\n\t\t}\n\t\t// We're done if we removed the exact required prefix, otherwise add it\n\t\tif(count !== targetCount) {\n\t\t\t// Apply the prefix\n\t\t\tline =  prefix + \" \" + line;\n\t\t}\n\t\t// Save the modified line\n\t\tlines[index] = line;\n\t});\n\t// Stitch the replacement text together and set the selection\n\toperation.replacement = lines.join(\"\\n\");\n\tif(lines.length === 1) {\n\t\toperation.newSelStart = operation.cutStart + operation.replacement.length;\n\t\toperation.newSelEnd = operation.newSelStart;\n\t} else {\n\t\toperation.newSelStart = operation.cutStart;\n\t\toperation.newSelEnd = operation.newSelStart + operation.replacement.length;\n\t}\n};\n\n})();\n","type":"application/javascript","module-type":"texteditoroperation"},"$:/core/modules/editor/operations/text/replace-all.js":{"title":"$:/core/modules/editor/operations/text/replace-all.js","text":"/*\\\ntitle: $:/core/modules/editor/operations/text/replace-all.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to replace the entire text\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"replace-all\"] = function(event,operation) {\n\toperation.cutStart = 0;\n\toperation.cutEnd = operation.text.length;\n\toperation.replacement = event.paramObject.text;\n\toperation.newSelStart = 0;\n\toperation.newSelEnd = operation.replacement.length;\n};\n\n})();\n","type":"application/javascript","module-type":"texteditoroperation"},"$:/core/modules/editor/operations/text/replace-selection.js":{"title":"$:/core/modules/editor/operations/text/replace-selection.js","text":"/*\\\ntitle: $:/core/modules/editor/operations/text/replace-selection.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to replace the selection\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"replace-selection\"] = function(event,operation) {\n\toperation.replacement = event.paramObject.text;\n\toperation.cutStart = operation.selStart;\n\toperation.cutEnd = operation.selEnd;\n\toperation.newSelStart = operation.selStart;\n\toperation.newSelEnd = operation.selStart + operation.replacement.length;\n};\n\n})();\n","type":"application/javascript","module-type":"texteditoroperation"},"$:/core/modules/editor/operations/text/save-selection.js":{"title":"$:/core/modules/editor/operations/text/save-selection.js","text":"/*\\\ntitle: $:/core/modules/editor/operations/text/save-selection.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to save the current selection in a specified tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"save-selection\"] = function(event,operation) {\n\tvar tiddler = event.paramObject.tiddler,\n\t\tfield = event.paramObject.field || \"text\";\n\tif(tiddler && field) {\n\t\tthis.wiki.setText(tiddler,field,null,operation.text.substring(operation.selStart,operation.selEnd));\n\t}\n};\n\n})();\n","type":"application/javascript","module-type":"texteditoroperation"},"$:/core/modules/editor/operations/text/wrap-lines.js":{"title":"$:/core/modules/editor/operations/text/wrap-lines.js","text":"/*\\\ntitle: $:/core/modules/editor/operations/text/wrap-lines.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to wrap the selected lines with a prefix and suffix\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"wrap-lines\"] = function(event,operation) {\n\tvar prefix = event.paramObject.prefix || \"\",\n\t\tsuffix = event.paramObject.suffix || \"\";\n\tif($tw.utils.endsWith(operation.text.substring(0,operation.selStart), prefix + \"\\n\") &&\n\t\t\t$tw.utils.startsWith(operation.text.substring(operation.selEnd), \"\\n\" + suffix)) {\n\t\t// Selected text is already surrounded by prefix and suffix: Remove them\n\t\t// Cut selected text plus prefix and suffix\n\t\toperation.cutStart = operation.selStart - (prefix.length + 1);\n\t\toperation.cutEnd = operation.selEnd + suffix.length + 1;\n\t\t// Also cut the following newline (if there is any)\n\t\tif (operation.text[operation.cutEnd] === \"\\n\") {\n\t\t\toperation.cutEnd++;\n\t\t}\n\t\t// Replace with selection\n\t\toperation.replacement = operation.text.substring(operation.selStart,operation.selEnd);\n\t\t// Select text that was in between prefix and suffix\n\t\toperation.newSelStart = operation.cutStart;\n\t\toperation.newSelEnd = operation.selEnd - (prefix.length + 1);\n\t} else {\n\t\t// Cut just past the preceding line break, or the start of the text\n\t\toperation.cutStart = $tw.utils.findPrecedingLineBreak(operation.text,operation.selStart);\n\t\t// Cut to just past the following line break, or to the end of the text\n\t\toperation.cutEnd = $tw.utils.findFollowingLineBreak(operation.text,operation.selEnd);\n\t\t// Add the prefix and suffix\n\t\toperation.replacement = prefix + \"\\n\" +\n\t\t\t\t\toperation.text.substring(operation.cutStart,operation.cutEnd) + \"\\n\" +\n\t\t\t\t\tsuffix + \"\\n\";\n\t\toperation.newSelStart = operation.cutStart + prefix.length + 1;\n\t\toperation.newSelEnd = operation.newSelStart + (operation.cutEnd - operation.cutStart);\n\t}\n};\n\n})();\n","type":"application/javascript","module-type":"texteditoroperation"},"$:/core/modules/editor/operations/text/wrap-selection.js":{"title":"$:/core/modules/editor/operations/text/wrap-selection.js","text":"/*\\\ntitle: $:/core/modules/editor/operations/text/wrap-selection.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to wrap the selection with the specified prefix and suffix\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"wrap-selection\"] = function(event,operation) {\n\tvar o = operation,\n\t\tprefix = event.paramObject.prefix,\n\t\tsuffix = event.paramObject.suffix,\n\t\ttrimSelection = event.paramObject.trimSelection || \"no\",\n\t\tselLength = o.selEnd - o.selStart;\n\n\t// This function detects, if trailing spaces are part of the selection __and__ if the user wants to handle them\n\t// Returns \"yes\", \"start\", \"end\", \"no\" (default)\n\t//\tyes .. there are trailing spaces at both ends\n\t//\tstart .. there are trailing spaces at the start\n\t//\tend .. there are trailing spaces at the end\n\t//\tno .. no trailing spaces are taken into account\n\tvar trailingSpaceAt = function(sel) {\n\t\tvar _start,\n\t\t\t_end,\n\t\t\tresult;\n\t\t// trimSelection is a user parameter, which this evaluations takes into account\n\t\tswitch(trimSelection) {\n\t\t\tcase \"end\":\n\t\t\t\tresult = (sel.trimEnd().length !== selLength) ? \"end\" : \"no\";\n\t\t\t\tbreak;\n\t\t\tcase \"yes\":\n\t\t\t\t_start = sel.trimStart().length !== selLength;\n\t\t\t\t_end = sel.trimEnd().length !== selLength;\n\t\t\t\tresult = (_start && _end) ? \"yes\" : (_start) ? \"start\" : (_end) ? \"end\" : \"no\";\n\t\t\t\tbreak;\n\t\t\tcase \"start\":\n\t\t\t\tresult = (sel.trimStart().length !== selLength) ? \"start\" : \"no\";\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tresult = \"no\";\n\t\t\t\tbreak;\n\t\t}\n\t\treturn result;\n\t}\n\n\tfunction togglePrefixSuffix() {\n\t\tif(o.text.substring(o.selStart - prefix.length, o.selStart + suffix.length) === prefix + suffix) {\n\t\t\t// Remove the prefix and suffix\n\t\t\to.cutStart = o.selStart - prefix.length;\n\t\t\to.cutEnd = o.selEnd + suffix.length;\n\t\t\to.replacement = \"\";\n\t\t\to.newSelStart = o.cutStart;\n\t\t\to.newSelEnd = o.newSelStart;\n\t\t} else {\n\t\t\t// Wrap the cursor instead\n\t\t\to.cutStart = o.selStart;\n\t\t\to.cutEnd = o.selEnd;\n\t\t\to.replacement = prefix + suffix;\n\t\t\to.newSelStart = o.selStart + prefix.length;\n\t\t\to.newSelEnd = o.newSelStart;\n\t\t}\n\t}\n\n\t// options: lenPrefix, lenSuffix\n\tfunction removePrefixSuffix(options) {\n\t\toptions = options || {};\n\t\tvar _lenPrefix = options.lenPrefix || 0;\n\t\tvar _lenSuffix = options.lenSuffix || 0;\n\n\t\to.cutStart = o.selStart - _lenPrefix;\n\t\to.cutEnd = o.selEnd + _lenSuffix;\n\t\to.replacement = (_lenPrefix || _lenSuffix) ? o.selection : o.selection.substring(prefix.length, o.selection.length - suffix.length);\n\t\to.newSelStart = o.cutStart;\n\t\to.newSelEnd = o.cutStart + o.replacement.length;\n\t}\n\n\tfunction addPrefixSuffix() {\n\t\t// remove trailing space if requested\n\t\tswitch(trailingSpaceAt(o.selection)) {\n\t\t\tcase \"no\":\n\t\t\t\t// has no trailing spaces\n\t\t\t\to.cutStart = o.selStart;\n\t\t\t\to.cutEnd = o.selEnd;\n\t\t\t\to.replacement = prefix + o.selection + suffix;\n\t\t\t\to.newSelStart = o.selStart;\n\t\t\t\to.newSelEnd = o.selStart + o.replacement.length;\n\t\t\t\tbreak;\n\t\t\tcase \"yes\":\n\t\t\t\t// handle both ends\n\t\t\t\to.cutStart = o.selEnd - (o.selection.trimStart().length);\n\t\t\t\to.cutEnd = o.selection.trimEnd().length + o.selStart;\n\t\t\t\to.replacement = prefix + o.selection.trim() + suffix;\n\t\t\t\to.newSelStart = o.cutStart;\n\t\t\t\to.newSelEnd = o.cutStart + o.replacement.length;\n\t\t\t\tbreak;\n\t\t\tcase \"start\":\n\t\t\t\t// handle leading\n\t\t\t\to.cutStart = o.selEnd - (o.selection.trimStart().length);\n\t\t\t\to.cutEnd = o.selEnd;\n\t\t\t\to.replacement = prefix + o.selection.trimStart() + suffix;\n\t\t\t\to.newSelStart = o.cutStart;\n\t\t\t\to.newSelEnd = o.cutStart + o.replacement.length;\n\t\t\t\tbreak;\n\t\t\tcase \"end\":\n\t\t\t\t// handle trailing\n\t\t\t\to.cutStart = o.selStart;\n\t\t\t\to.cutEnd = o.selection.trimEnd().length + o.selStart;\n\t\t\t\to.replacement = prefix + o.selection.trimEnd() + suffix;\n\t\t\t\to.newSelStart = o.selStart;\n\t\t\t\to.newSelEnd = o.selStart + o.replacement.length;\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tif(o.selStart === o.selEnd) {\n\t\t// No selection; Create prefix and suffix. Set cursor in between them: \"\"|\"\"\n\t\ttogglePrefixSuffix();\n\t} else if(o.text.substring(o.selStart, o.selStart + prefix.length) === prefix &&\n\t\t\t\to.text.substring(o.selEnd - suffix.length,o.selEnd) === suffix) {\n\t\t// Prefix and suffix are already present, so remove them\n\t\tremovePrefixSuffix();\n\t} else if(o.text.substring(o.selStart - prefix.length, o.selStart) === prefix &&\n\t\t\t\to.text.substring(o.selEnd, o.selEnd + suffix.length) === suffix) {\n\t\t// Prefix and suffix are present BUT not selected -> remove them\n\t\tremovePrefixSuffix({\"lenPrefix\": prefix.length, \"lenSuffix\": suffix.length});\n\t} else {\n\t\t// Add the prefix and suffix\n\t\taddPrefixSuffix();\n\t}\n};\n\n})();\n","type":"application/javascript","module-type":"texteditoroperation"},"$:/core/modules/filterrunprefixes/all.js":{"title":"$:/core/modules/filterrunprefixes/all.js","text":"/*\\\ntitle: $:/core/modules/filterrunprefixes/all.js\ntype: application/javascript\nmodule-type: filterrunprefix\n\nUnion of sets without de-duplication.\nEquivalent to = filter run prefix.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter prefix function\n*/\nexports.all = function(operationSubFunction) {\n\treturn function(results,source,widget) {\n\t\tresults.push.apply(results, operationSubFunction(source,widget));\n\t};\n};\n\n})();\n","type":"application/javascript","module-type":"filterrunprefix"},"$:/core/modules/filterrunprefixes/and.js":{"title":"$:/core/modules/filterrunprefixes/and.js","text":"/*\\\ntitle: $:/core/modules/filterrunprefixes/and.js\ntype: application/javascript\nmodule-type: filterrunprefix\n\nIntersection of sets.\nEquivalent to + filter run prefix.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter prefix function\n*/\nexports.and = function(operationSubFunction,options) {\n\treturn function(results,source,widget) {\n\t\t// This replaces all the elements of the array, but keeps the actual array so that references to it are preserved\n\t\tsource = options.wiki.makeTiddlerIterator(results.toArray());\n\t\tresults.clear();\n\t\tresults.pushTop(operationSubFunction(source,widget));\n\t};\n};\n\n})();\n","type":"application/javascript","module-type":"filterrunprefix"},"$:/core/modules/filterrunprefixes/cascade.js":{"title":"$:/core/modules/filterrunprefixes/cascade.js","text":"/*\\\ntitle: $:/core/modules/filterrunprefixes/cascade.js\ntype: application/javascript\nmodule-type: filterrunprefix\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter prefix function\n*/\nexports.cascade = function(operationSubFunction,options) {\n\treturn function(results,source,widget) {\n\t\tif(results.length !== 0) {\n\t\t\tvar filterList = operationSubFunction(source,widget),\n\t\t\t\tfilterFnList = [];\n\t\t\tvar inputResults = results.toArray();\n\t\t\tresults.clear();\n\t\t\t$tw.utils.each(inputResults,function(title) {\n\t\t\t\tvar result = \"\"; // If no filter matches, we return an empty string\n\t\t\t\t$tw.utils.each(filterList,function(filter,index) {\n\t\t\t\t\tif(!filterFnList[index]) {\n\t\t\t\t\t\tfilterFnList[index] = options.wiki.compileFilter(filter);\n\t\t\t\t\t}\n\t\t\t\t\tvar output = filterFnList[index](options.wiki.makeTiddlerIterator([title]),widget.makeFakeWidgetWithVariables({\n\t\t\t\t\t\t\"currentTiddler\": \"\" + title,\n\t\t\t\t\t\t\"..currentTiddler\": widget.getVariable(\"currentTiddler\",\"\")\n\t\t\t\t\t}));\n\t\t\t\t\tif(output.length !== 0) {\n\t\t\t\t\t\tresult = output[0];\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tresults.push(result);\n\t\t\t});\n\t\t}\n\t}\n};\n\n})();","type":"application/javascript","module-type":"filterrunprefix"},"$:/core/modules/filterrunprefixes/else.js":{"title":"$:/core/modules/filterrunprefixes/else.js","text":"/*\\\ntitle: $:/core/modules/filterrunprefixes/else.js\ntype: application/javascript\nmodule-type: filterrunprefix\n\nEquivalent to ~ filter run prefix.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter prefix function\n*/\nexports.else = function(operationSubFunction) {\n\treturn function(results,source,widget) {\n\t\tif(results.length === 0) {\n\t\t\t// Main result so far is empty\n\t\t\tresults.pushTop(operationSubFunction(source,widget));\n\t\t}\n\t};\n};\n\n})();\n","type":"application/javascript","module-type":"filterrunprefix"},"$:/core/modules/filterrunprefixes/except.js":{"title":"$:/core/modules/filterrunprefixes/except.js","text":"/*\\\ntitle: $:/core/modules/filterrunprefixes/except.js\ntype: application/javascript\nmodule-type: filterrunprefix\n\nDifference of sets.\nEquivalent to - filter run prefix.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter prefix function\n*/\nexports.except = function(operationSubFunction) {\n\treturn function(results,source,widget) {\n\t\tresults.remove(operationSubFunction(source,widget));\n\t};\n};\n\n})();\n","type":"application/javascript","module-type":"filterrunprefix"},"$:/core/modules/filterrunprefixes/filter.js":{"title":"$:/core/modules/filterrunprefixes/filter.js","text":"/*\\\ntitle: $:/core/modules/filterrunprefixes/filter.js\ntype: application/javascript\nmodule-type: filterrunprefix\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.filter = function(operationSubFunction,options) {\n\treturn function(results,source,widget) {\n\t\tif(results.length > 0) {\n\t\t\tvar resultsToRemove = [],\n\t\t\t\tindex = 0;\n\t\t\tresults.each(function(title) {\n\t\t\t\tvar filtered = operationSubFunction(options.wiki.makeTiddlerIterator([title]),widget.makeFakeWidgetWithVariables({\n\t\t\t\t\t\"currentTiddler\": \"\" + title,\n\t\t\t\t\t\"..currentTiddler\": widget.getVariable(\"currentTiddler\",\"\"),\n\t\t\t\t\t\"index\": \"\" + index,\n\t\t\t\t\t\"revIndex\": \"\" +  (results.length - 1 - index),\n\t\t\t\t\t\"length\": \"\" + results.length\n\t\t\t\t}));\n\t\t\t\tif(filtered.length === 0) {\n\t\t\t\t\tresultsToRemove.push(title);\n\t\t\t\t}\n\t\t\t\t++index;\n\t\t\t});\n\t\t\tresults.remove(resultsToRemove);\n\t\t}\n\t}\n};\n\n})();\n","type":"application/javascript","module-type":"filterrunprefix"},"$:/core/modules/filterrunprefixes/intersection.js":{"title":"$:/core/modules/filterrunprefixes/intersection.js","text":"/*\\\ntitle: $:/core/modules/filterrunprefixes/intersection.js\ntype: application/javascript\nmodule-type: filterrunprefix\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter prefix function\n*/\nexports.intersection = function(operationSubFunction) {\n\treturn function(results,source,widget) {\n\t\tif(results.length !== 0) {\n\t\t\tvar secondRunResults = operationSubFunction(source,widget);\n\t\t\tvar firstRunResults = results.toArray();\n\t\t\tresults.clear();\n\t\t\t$tw.utils.each(firstRunResults,function(title) {\n\t\t\t\tif(secondRunResults.indexOf(title) !== -1) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t};\n};\n\n})();\n","type":"application/javascript","module-type":"filterrunprefix"},"$:/core/modules/filterrunprefixes/map.js":{"title":"$:/core/modules/filterrunprefixes/map.js","text":"/*\\\ntitle: $:/core/modules/filterrunprefixes/map.js\ntype: application/javascript\nmodule-type: filterrunprefix\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter prefix function\n*/\nexports.map = function(operationSubFunction,options) {\n\treturn function(results,source,widget) {\n\t\tif(results.length > 0) {\n\t\t\tvar inputTitles = results.toArray(),\n\t\t\t\tindex = 0,\n\t\t\t\tsuffixes = options.suffixes,\n\t\t\t\tflatten = (suffixes[0] && suffixes[0][0] === \"flat\") ? true : false;\n\t\t\tresults.clear();\n\t\t\t$tw.utils.each(inputTitles,function(title) {\n\t\t\t\tvar filtered = operationSubFunction(options.wiki.makeTiddlerIterator([title]),widget.makeFakeWidgetWithVariables({\n\t\t\t\t\t\"currentTiddler\": \"\" + title,\n\t\t\t\t\t\"..currentTiddler\": widget.getVariable(\"currentTiddler\",\"\"),\n\t\t\t\t\t\"index\": \"\" + index,\n\t\t\t\t\t\"revIndex\": \"\" +  (inputTitles.length - 1 - index),\n\t\t\t\t\t\"length\": \"\" + inputTitles.length\n\t\t\t\t}));\n\t\t\t\tif(filtered.length && flatten) {\n\t\t\t\t\t$tw.utils.each(filtered,function(value) {\n\t\t\t\t\t\tresults.push(value);\n\t\t\t\t\t})\n\t\t\t\t} else {\n\t\t\t\t\tresults.push(filtered[0]||\"\");\n\t\t\t\t}\n\t\t\t\t++index;\n\t\t\t});\n\t\t}\n\t}\n};\n\n})();","type":"application/javascript","module-type":"filterrunprefix"},"$:/core/modules/filterrunprefixes/or.js":{"title":"$:/core/modules/filterrunprefixes/or.js","text":"/*\\\ntitle: $:/core/modules/filterrunprefixes/or.js\ntype: application/javascript\nmodule-type: filterrunprefix\n\nEquivalent to a filter run with no prefix.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter prefix function\n*/\nexports.or = function(operationSubFunction) {\n\treturn function(results,source,widget) {\n\t\tresults.pushTop(operationSubFunction(source,widget));\n\t};\n};\n\n})();\n","type":"application/javascript","module-type":"filterrunprefix"},"$:/core/modules/filterrunprefixes/reduce.js":{"title":"$:/core/modules/filterrunprefixes/reduce.js","text":"/*\\\ntitle: $:/core/modules/filterrunprefixes/reduce.js\ntype: application/javascript\nmodule-type: filterrunprefix\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter prefix function\n*/\nexports.reduce = function(operationSubFunction,options) {\n\treturn function(results,source,widget) {\n\t\tif(results.length > 0) {\n\t\t\tvar accumulator = \"\",\n\t\t\t\tindex = 0;\n\t\t\tresults.each(function(title) {\n\t\t\t\tvar list = operationSubFunction(options.wiki.makeTiddlerIterator([title]),widget.makeFakeWidgetWithVariables({\n\t\t\t\t\t\"currentTiddler\": \"\" + title,\n\t\t\t\t\t\"..currentTiddler\": widget.getVariable(\"currentTiddler\"),\n\t\t\t\t\t\"index\": \"\" + index,\n\t\t\t\t\t\"revIndex\": \"\" +  (results.length - 1 - index),\n\t\t\t\t\t\"length\": \"\" + results.length,\n\t\t\t\t\t\"accumulator\": \"\" + accumulator\n\t\t\t\t}));\n\t\t\t\tif(list.length > 0) {\n\t\t\t\t\taccumulator = \"\" + list[0];\n\t\t\t\t}\n\t\t\t\t++index;\n\t\t\t});\n\t\t\tresults.clear();\n\t\t\tresults.push(accumulator);\n\t\t}\n\t}\n};\n\n})();\n","type":"application/javascript","module-type":"filterrunprefix"},"$:/core/modules/filterrunprefixes/sort.js":{"title":"$:/core/modules/filterrunprefixes/sort.js","text":"/*\\\ntitle: $:/core/modules/filterrunprefixes/sort.js\ntype: application/javascript\nmodule-type: filterrunprefix\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter prefix function\n*/\nexports.sort = function(operationSubFunction,options) {\n\treturn function(results,source,widget) {\n\t\tif(results.length > 0) {\n\t\t\tvar suffixes = options.suffixes,\n\t\t\t\tsortType = (suffixes[0] && suffixes[0][0]) ? suffixes[0][0] : \"string\",\n\t\t\t\tinvert = suffixes[1] ? (suffixes[1].indexOf(\"reverse\") !== -1) : false,\n\t\t\t\tisCaseSensitive = suffixes[1] ? (suffixes[1].indexOf(\"casesensitive\") !== -1) : false,\n\t\t\t\tinputTitles = results.toArray(),\n\t\t\t\tsortKeys = [],\n\t\t\t\tindexes = new Array(inputTitles.length),\n\t\t\t\tcompareFn;\n\t\t\tresults.each(function(title) {\n\t\t\t\tvar key = operationSubFunction(options.wiki.makeTiddlerIterator([title]),widget.makeFakeWidgetWithVariables({\n\t\t\t\t\t\"currentTiddler\": \"\" + title,\n\t\t\t\t\t\"..currentTiddler\": widget.getVariable(\"currentTiddler\")\n\t\t\t\t}));\n\t\t\t\tsortKeys.push(key[0] || \"\");\n\t\t\t});\n\t\t\tresults.clear();\n\t\t\t// Prepare an array of indexes to sort\n\t\t\tfor(var t=0; t<inputTitles.length; t++) {\n\t\t\t\tindexes[t] = t;\n\t\t\t}\n\t\t\t// Sort the indexes\n\t\t\tcompareFn = $tw.utils.makeCompareFunction(sortType,{defaultType: \"string\", invert:invert, isCaseSensitive:isCaseSensitive});\n\t\t\tindexes = indexes.sort(function(a,b) {\n\t\t\t\t\treturn compareFn(sortKeys[a],sortKeys[b]);\n\t\t\t});\n\t\t\t// Add to results in correct order\n\t\t\t$tw.utils.each(indexes,function(index) {\n\t\t\t\tresults.push(inputTitles[index]);\n\t\t\t});\n\t\t}\n\t}\n};\n\n})();","type":"application/javascript","module-type":"filterrunprefix"},"$:/core/modules/filterrunprefixes/then.js":{"title":"$:/core/modules/filterrunprefixes/then.js","text":"/*\\\ntitle: $:/core/modules/filterrunprefixes/then.js\ntype: application/javascript\nmodule-type: filterrunprefix\n\nReplace results of previous runs unless empty\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter prefix function\n*/\nexports.then = function(operationSubFunction) {\n\treturn function(results,source,widget) {\n\t\tif(results.length !== 0) {\n\t\t\t// Only run if previous run(s) produced results\n\t\t\tvar thisRunResult = operationSubFunction(source,widget);\n\t\t\tif(thisRunResult.length !== 0) {\n\t\t\t\t// Replace results only if this run actually produces a result\n\t\t\t\tresults.clear();\n\t\t\t\tresults.pushTop(thisRunResult);\n\t\t\t}\n\t\t}\n\t};\n};\n\n})();\n","type":"application/javascript","module-type":"filterrunprefix"},"$:/core/modules/filters/addprefix.js":{"title":"$:/core/modules/filters/addprefix.js","text":"/*\\\ntitle: $:/core/modules/filters/addprefix.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for adding a prefix to each title in the list. This is\nespecially useful in contexts where only a filter expression is allowed\nand macro substitution isn't available.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.addprefix = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(operator.operand + title);\n\t});\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/addsuffix.js":{"title":"$:/core/modules/filters/addsuffix.js","text":"/*\\\ntitle: $:/core/modules/filters/addsuffix.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for adding a suffix to each title in the list. This is\nespecially useful in contexts where only a filter expression is allowed\nand macro substitution isn't available.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.addsuffix = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title + operator.operand);\n\t});\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/after.js":{"title":"$:/core/modules/filters/after.js","text":"/*\\\ntitle: $:/core/modules/filters/after.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning the tiddler from the current list that is after the tiddler named in the operand.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.after = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\tvar index = results.indexOf(operator.operand);\n\tif(index === -1 || index > (results.length - 2)) {\n\t\treturn [];\n\t} else {\n\t\treturn [results[index + 1]];\n\t}\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/all/current.js":{"title":"$:/core/modules/filters/all/current.js","text":"/*\\\ntitle: $:/core/modules/filters/all/current.js\ntype: application/javascript\nmodule-type: allfilteroperator\n\nFilter function for [all[current]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.current = function(source,prefix,options) {\n\tvar currTiddlerTitle = options.widget && options.widget.getVariable(\"currentTiddler\");\n\tif(currTiddlerTitle) {\n\t\treturn [currTiddlerTitle];\n\t} else {\n\t\treturn [];\n\t}\n};\n\n})();\n","type":"application/javascript","module-type":"allfilteroperator"},"$:/core/modules/filters/all/missing.js":{"title":"$:/core/modules/filters/all/missing.js","text":"/*\\\ntitle: $:/core/modules/filters/all/missing.js\ntype: application/javascript\nmodule-type: allfilteroperator\n\nFilter function for [all[missing]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.missing = function(source,prefix,options) {\n\treturn options.wiki.getMissingTitles();\n};\n\n})();\n","type":"application/javascript","module-type":"allfilteroperator"},"$:/core/modules/filters/all/orphans.js":{"title":"$:/core/modules/filters/all/orphans.js","text":"/*\\\ntitle: $:/core/modules/filters/all/orphans.js\ntype: application/javascript\nmodule-type: allfilteroperator\n\nFilter function for [all[orphans]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.orphans = function(source,prefix,options) {\n\treturn options.wiki.getOrphanTitles();\n};\n\n})();\n","type":"application/javascript","module-type":"allfilteroperator"},"$:/core/modules/filters/all/shadows.js":{"title":"$:/core/modules/filters/all/shadows.js","text":"/*\\\ntitle: $:/core/modules/filters/all/shadows.js\ntype: application/javascript\nmodule-type: allfilteroperator\n\nFilter function for [all[shadows]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.shadows = function(source,prefix,options) {\n\treturn options.wiki.allShadowTitles();\n};\n\n})();\n","type":"application/javascript","module-type":"allfilteroperator"},"$:/core/modules/filters/all/tags.js":{"title":"$:/core/modules/filters/all/tags.js","text":"/*\\\ntitle: $:/core/modules/filters/all/tags.js\ntype: application/javascript\nmodule-type: allfilteroperator\n\nFilter function for [all[tags]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.tags = function(source,prefix,options) {\n\treturn Object.keys(options.wiki.getTagMap());\n};\n\n})();\n","type":"application/javascript","module-type":"allfilteroperator"},"$:/core/modules/filters/all/tiddlers.js":{"title":"$:/core/modules/filters/all/tiddlers.js","text":"/*\\\ntitle: $:/core/modules/filters/all/tiddlers.js\ntype: application/javascript\nmodule-type: allfilteroperator\n\nFilter function for [all[tiddlers]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.tiddlers = function(source,prefix,options) {\n\treturn options.wiki.allTitles();\n};\n\n})();\n","type":"application/javascript","module-type":"allfilteroperator"},"$:/core/modules/filters/all.js":{"title":"$:/core/modules/filters/all.js","text":"/*\\\ntitle: $:/core/modules/filters/all.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for selecting tiddlers\n\n[all[shadows+tiddlers]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar allFilterOperators;\n\nfunction getAllFilterOperators() {\n\tif(!allFilterOperators) {\n\t\tallFilterOperators = {};\n\t\t$tw.modules.applyMethods(\"allfilteroperator\",allFilterOperators);\n\t}\n\treturn allFilterOperators;\n}\n\n/*\nExport our filter function\n*/\nexports.all = function(source,operator,options) {\n\t// Check for common optimisations\n\tvar subops = operator.operand.split(\"+\");\n\tif(subops.length === 1 && subops[0] === \"\") {\n\t\treturn source;\n\t} else if(subops.length === 1 && subops[0] === \"tiddlers\") {\n\t\treturn options.wiki.each;\n\t} else if(subops.length === 1 && subops[0] === \"shadows\") {\n\t\treturn options.wiki.eachShadow;\n\t} else if(subops.length === 2 && subops[0] === \"tiddlers\" && subops[1] === \"shadows\") {\n\t\treturn options.wiki.eachTiddlerPlusShadows;\n\t} else if(subops.length === 2 && subops[0] === \"shadows\" && subops[1] === \"tiddlers\") {\n\t\treturn options.wiki.eachShadowPlusTiddlers;\n\t}\n\t// Do it the hard way\n\t// Get our suboperators\n\tvar allFilterOperators = getAllFilterOperators();\n\t// Cycle through the suboperators accumulating their results\n\tvar results = new $tw.utils.LinkedList();\n\tfor(var t=0; t<subops.length; t++) {\n\t\tvar subop = allFilterOperators[subops[t]];\n\t\tif(subop) {\n\t\t\tresults.pushTop(subop(source,operator.prefix,options));\n\t\t}\n\t}\n\treturn results.makeTiddlerIterator(options.wiki);\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/backlinks.js":{"title":"$:/core/modules/filters/backlinks.js","text":"/*\\\ntitle: $:/core/modules/filters/backlinks.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning all the backlinks from a tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.backlinks = function(source,operator,options) {\n\tvar results = new $tw.utils.LinkedList();\n\tsource(function(tiddler,title) {\n\t\tresults.pushTop(options.wiki.getTiddlerBacklinks(title));\n\t});\n\treturn results.makeTiddlerIterator(options.wiki);\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/backtranscludes.js":{"title":"$:/core/modules/filters/backtranscludes.js","text":"/*\\\ntitle: $:/core/modules/filters/backtranscludes.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning all the backtranscludes from a tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.backtranscludes = function(source,operator,options) {\n\tvar results = new $tw.utils.LinkedList();\n\tsource(function(tiddler,title) {\n\t\tresults.pushTop(options.wiki.getTiddlerBacktranscludes(title));\n\t});\n\treturn results.makeTiddlerIterator(options.wiki);\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/before.js":{"title":"$:/core/modules/filters/before.js","text":"/*\\\ntitle: $:/core/modules/filters/before.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning the tiddler from the current list that is before the tiddler named in the operand.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.before = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\tvar index = results.indexOf(operator.operand);\n\tif(index <= 0) {\n\t\treturn [];\n\t} else {\n\t\treturn [results[index - 1]];\n\t}\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/commands.js":{"title":"$:/core/modules/filters/commands.js","text":"/*\\\ntitle: $:/core/modules/filters/commands.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the names of the commands available in this wiki\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.commands = function(source,operator,options) {\n\tvar results = [];\n\t$tw.utils.each($tw.commands,function(commandInfo,name) {\n\t\tresults.push(name);\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/compare.js":{"title":"$:/core/modules/filters/compare.js","text":"/*\\\ntitle: $:/core/modules/filters/compare.js\ntype: application/javascript\nmodule-type: filteroperator\n\nGeneral purpose comparison operator\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.compare = function(source,operator,options) {\n\tvar suffixes = operator.suffixes || [],\n\t\ttype = (suffixes[0] || [])[0],\n\t\tmode = (suffixes[1] || [])[0],\n\t\ttypeFn = $tw.utils.makeCompareFunction(type,{defaultType: \"number\"}),\n\t\tmodeFn = modes[mode] || modes.eq,\n\t\tinvert = operator.prefix === \"!\",\n\t\tresults = [];\n\tsource(function(tiddler,title) {\n\t\tif(modeFn(typeFn(title,operator.operand)) !== invert) {\n\t\t\tresults.push(title);\n\t\t}\n\t});\n\treturn results;\n};\n\nvar modes = {\n\t\"eq\": function(value) {return value === 0;},\n\t\"ne\": function(value) {return value !== 0;},\n\t\"gteq\": function(value) {return value >= 0;},\n\t\"gt\": function(value) {return value > 0;},\n\t\"lteq\": function(value) {return value <= 0;},\n\t\"lt\": function(value) {return value < 0;}\n}\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/contains.js":{"title":"$:/core/modules/filters/contains.js","text":"/*\\\ntitle: $:/core/modules/filters/contains.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for finding values in array fields\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.contains = function(source,operator,options) {\n\tvar results = [],\n\t\tfieldname = operator.suffix || \"list\";\n\tif(operator.prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(tiddler) {\n\t\t\t\tvar list = tiddler.getFieldList(fieldname);\n\t\t\t\tif(list.indexOf(operator.operand) === -1) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(tiddler) {\n\t\t\t\tvar list = tiddler.getFieldList(fieldname);\n\t\t\t\tif(list.indexOf(operator.operand) !== -1) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/count.js":{"title":"$:/core/modules/filters/count.js","text":"/*\\\ntitle: $:/core/modules/filters/count.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning the number of entries in the current list.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.count = function(source,operator,options) {\n\tvar count = 0;\n\tsource(function(tiddler,title) {\n\t\tcount++;\n\t});\n\treturn [count + \"\"];\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/crypto.js":{"title":"$:/core/modules/filters/crypto.js","text":"/*\\\ntitle: $:/core/modules/filters/crypto.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operators for cryptography, using the Stanford JavaScript library\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.sha256 = function(source,operator,options) {\n\tvar results = [],\n\t\tlength = parseInt(operator.operand,10) || 20;\n\tsource(function(tiddler,title) {\n\t\tresults.push($tw.utils.sha256(title,{length: length}));\n\t});\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/days.js":{"title":"$:/core/modules/filters/days.js","text":"/*\\\ntitle: $:/core/modules/filters/days.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator that selects tiddlers with a specified date field within a specified date interval.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.days = function(source,operator,options) {\n\tvar results = [],\n\t\tfieldName = operator.suffix || \"modified\",\n\t\tdayInterval = (parseInt(operator.operand,10)||0),\n\t\tdayIntervalSign = $tw.utils.sign(dayInterval),\n\t\ttargetTimeStamp = (new Date()).setHours(0,0,0,0) + 1000*60*60*24*dayInterval,\n\t\tisWithinDays = function(dateField) {\n\t\t\tvar sign = $tw.utils.sign(targetTimeStamp - (new Date(dateField)).setHours(0,0,0,0));\n\t\t\treturn sign === 0 || sign === dayIntervalSign;\n\t\t};\n\n\tif(operator.prefix === \"!\") {\n\t\ttargetTimeStamp = targetTimeStamp - 1000*60*60*24*dayIntervalSign;\n\t\tsource(function(tiddler,title) {\n\t\t\tif(tiddler && tiddler.fields[fieldName]) {\n\t\t\t\tif(!isWithinDays($tw.utils.parseDate(tiddler.fields[fieldName]))) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(tiddler && tiddler.fields[fieldName]) {\n\t\t\t\tif(isWithinDays($tw.utils.parseDate(tiddler.fields[fieldName]))) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/deserialize.js":{"title":"$:/core/modules/filters/deserialize.js","text":"/*\\\ntitle: $:/core/modules/filters/deserialize.js\ntype: application/javascript\nmodule-type: filteroperator\nFilter operator for deserializing string data into JSON representing tiddlers\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"deserialize\"] = function(source,operator,options) {\n\tvar results = [],\n\t\tdeserializer;\n\tif(operator.operand) {\n\t\t// Get the deserializer identified by the operand\n\t\tdeserializer = $tw.Wiki.tiddlerDeserializerModules[operator.operand];\n\t\tif(deserializer) {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tvar tiddlers;\n\t\t\t\ttry {\n\t\t\t\t\ttiddlers = deserializer(title);\n\t\t\t\t} catch(e) {\n\t\t\t\t\t// Return an empty array if we could not extract any tiddlers\n\t\t\t\t\ttiddlers = [];\n\t\t\t\t}\n\t\t\t\tresults.push(JSON.stringify(tiddlers));\n\t\t\t});\n\t\t} else {\n\t\t\treturn [$tw.language.getString(\"Error/DeserializeOperator/UnknownDeserializer\")];\n\t\t}\n\t} else {\n\t\treturn [$tw.language.getString(\"Error/DeserializeOperator/MissingOperand\")];\n\t}\n\treturn results;\n}\n\n})();","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/deserializers.js":{"title":"$:/core/modules/filters/deserializers.js","text":"/*\\\ntitle: $:/core/modules/filters/deserializers.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the names of the deserializers in this wiki\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.deserializers = function(source,operator,options) {\n\tvar results = [];\n\t$tw.utils.each($tw.Wiki.tiddlerDeserializerModules,function(deserializer,type) {\n\t\tresults.push(type);\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/duplicateslugs.js":{"title":"$:/core/modules/filters/duplicateslugs.js","text":"/*\\\ntitle: $:/core/modules/filters/duplicateslugs.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter function for [duplicateslugs[]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.duplicateslugs = function(source,operator,options) {\n\tvar slugs = Object.create(null), // Hashmap by slug of title, replaced with \"true\" if the duplicate title has already been output\n\t\tresults = [];\n\tsource(function(tiddler,title) {\n\t\tvar slug = options.wiki.slugify(title);\n\t\tif(slug in slugs) {\n\t\t\tif(slugs[slug] !== true) {\n\t\t\t\tresults.push(slugs[slug]);\n\t\t\t\tslugs[slug] = true;\n\t\t\t}\n\t\t\tresults.push(title);\n\t\t} else {\n\t\t\tslugs[slug] = title;\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/each.js":{"title":"$:/core/modules/filters/each.js","text":"/*\\\ntitle: $:/core/modules/filters/each.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator that selects one tiddler for each unique value of the specified field.\nWith suffix \"list\", selects all tiddlers that are values in a specified list field.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.each = function(source,operator,options) {\n\tvar results =[] ,\n\tvalue,values = {},\n\tfield = operator.operand || \"title\";\n\tif(operator.suffix === \"value\" && field === \"title\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!$tw.utils.hop(values,title)) {\n\t\t\t\tvalues[title] = true;\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else if(operator.suffix !== \"list-item\") {\n\t\tif(field === \"title\") {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler && !$tw.utils.hop(values,title)) {\n\t\t\t\t\tvalues[title] = true;\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler) {\n\t\t\t\t\tvalue = tiddler.getFieldString(field);\n\t\t\t\t\tif(!$tw.utils.hop(values,value)) {\n\t\t\t\t\t\tvalues[value] = true;\n\t\t\t\t\t\tresults.push(title);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(tiddler) {\n\t\t\t\t$tw.utils.each(\n\t\t\t\t\toptions.wiki.getTiddlerList(title,field),\n\t\t\t\t\tfunction(value) {\n\t\t\t\t\t\tif(!$tw.utils.hop(values,value)) {\n\t\t\t\t\t\t\tvalues[value] = true;\n\t\t\t\t\t\t\tresults.push(value);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/eachday.js":{"title":"$:/core/modules/filters/eachday.js","text":"/*\\\ntitle: $:/core/modules/filters/eachday.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator that selects one tiddler for each unique day covered by the specified date field\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.eachday = function(source,operator,options) {\n\tvar results = [],\n\t\tvalues = [],\n\t\tfieldName = operator.operand || \"modified\";\n\t// Function to convert a date/time to a date integer\n\tvar toDate = function(value) {\n\t\tvalue = (new Date(value)).setHours(0,0,0,0);\n\t\treturn value+0;\n\t};\n\tsource(function(tiddler,title) {\n\t\tif(tiddler && tiddler.fields[fieldName]) {\n\t\t\tvar value = toDate($tw.utils.parseDate(tiddler.fields[fieldName]));\n\t\t\tif(values.indexOf(value) === -1) {\n\t\t\t\tvalues.push(value);\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/editiondescription.js":{"title":"$:/core/modules/filters/editiondescription.js","text":"/*\\\ntitle: $:/core/modules/filters/editiondescription.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the descriptions of the specified edition names\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.editiondescription = function(source,operator,options) {\n\tvar results = [];\n\tif($tw.node) {\n\t\tvar editionInfo = $tw.utils.getEditionInfo();\n\t\tif(editionInfo) {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif($tw.utils.hop(editionInfo,title)) {\n\t\t\t\t\tresults.push(editionInfo[title].description || \"\");\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/editions.js":{"title":"$:/core/modules/filters/editions.js","text":"/*\\\ntitle: $:/core/modules/filters/editions.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the names of the available editions in this wiki\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.editions = function(source,operator,options) {\n\tvar results = [];\n\tif($tw.node) {\n\t\tvar editionInfo = $tw.utils.getEditionInfo();\n\t\tif(editionInfo) {\n\t\t\t$tw.utils.each(editionInfo,function(info,name) {\n\t\t\t\tresults.push(name);\n\t\t\t});\n\t\t}\n\t\tresults.sort();\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/else.js":{"title":"$:/core/modules/filters/else.js","text":"/*\\\ntitle: $:/core/modules/filters/else.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for replacing an empty input list with a constant, passing a non-empty input list straight through\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.else = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\tif(results.length === 0) {\n\t\treturn [operator.operand];\n\t} else {\n\t\treturn results;\n\t}\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/decodeuricomponent.js":{"title":"$:/core/modules/filters/decodeuricomponent.js","text":"/*\\\ntitle: $:/core/modules/filters/decodeuricomponent.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for applying decodeURIComponent() to each item.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter functions\n*/\n\nexports.decodebase64 = function(source,operator,options) {\n\tvar results = [];\n\tvar binary = operator.suffixes && operator.suffixes[0].indexOf(\"binary\") !== -1;\n\tvar urlsafe = operator.suffixes && operator.suffixes[0].indexOf(\"urlsafe\") !== -1;\n\tsource(function(tiddler,title) {\n\t\tresults.push($tw.utils.base64Decode(title,binary,urlsafe));\n\t});\n\treturn results;\n};\n\nexports.encodebase64 = function(source,operator,options) {\n\tvar results = [];\n\tvar binary = operator.suffixes && operator.suffixes[0].indexOf(\"binary\") !== -1;\n\tvar urlsafe = operator.suffixes && operator.suffixes[0].indexOf(\"urlsafe\") !== -1;\n\tsource(function(tiddler,title) {\n\t\tresults.push($tw.utils.base64Encode(title,binary,urlsafe));\n\t});\n\treturn results;\n};\n\nexports.decodeuricomponent = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push($tw.utils.decodeURIComponentSafe(title));\n\t});\n\treturn results;\n};\n\nexports.encodeuricomponent = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push($tw.utils.encodeURIComponentExtended(title));\n\t});\n\treturn results;\n};\n\nexports.decodeuri = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push($tw.utils.decodeURISafe(title));\n\t});\n\treturn results;\n};\n\nexports.encodeuri = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(encodeURI(title));\n\t});\n\treturn results;\n};\n\nexports.decodehtml = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push($tw.utils.htmlDecode(title));\n\t});\n\treturn results;\n};\n\nexports.encodehtml = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push($tw.utils.htmlEncode(title));\n\t});\n\treturn results;\n};\n\nexports.stringify = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push($tw.utils.stringify(title,(operator.suffix === \"rawunicode\")));\n\t});\n\treturn results;\n};\n\nexports.jsonstringify = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push($tw.utils.jsonStringify(title,(operator.suffix === \"rawunicode\")));\n\t});\n\treturn results;\n};\n\nexports.escaperegexp = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push($tw.utils.escapeRegExp(title));\n\t});\n\treturn results;\n};\n\nexports.escapecss = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\t// escape any character with a special meaning in CSS using CSS.escape()\n\t\tresults.push($tw.utils.escapeCSS(title));\n\t});\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/enlist.js":{"title":"$:/core/modules/filters/enlist.js","text":"/*\\\ntitle: $:/core/modules/filters/enlist.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning its operand parsed as a list\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.enlist = function(source,operator,options) {\n\tvar allowDuplicates = false;\n\tswitch(operator.suffix) {\n\t\tcase \"raw\":\n\t\t\tallowDuplicates = true;\n\t\t\tbreak;\n\t\tcase \"dedupe\":\n\t\t\tallowDuplicates = false;\n\t\t\tbreak;\n\t}\n\tvar list = $tw.utils.parseStringArray(operator.operand,allowDuplicates);\n\tif(operator.prefix === \"!\") {\n\t\tvar results = [];\n\t\tsource(function(tiddler,title) {\n\t\t\tif(list.indexOf(title) === -1) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t\treturn results;\n\t} else {\n\t\treturn list;\n\t}\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/field.js":{"title":"$:/core/modules/filters/field.js","text":"/*\\\ntitle: $:/core/modules/filters/field.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for comparing fields for equality\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.field = function(source,operator,options) {\n\tvar results = [],indexedResults,\n\t\tfieldname = operator.suffix || operator.operator || \"title\";\n\tif(operator.prefix === \"!\") {\n\t\tif(operator.regexp) {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler) {\n\t\t\t\t\tvar text = tiddler.getFieldString(fieldname);\n\t\t\t\t\tif(text !== null && !operator.regexp.exec(text)) {\n\t\t\t\t\t\tresults.push(title);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler) {\n\t\t\t\t\tvar text = tiddler.getFieldString(fieldname);\n\t\t\t\t\tif(text !== null && text !== operator.operand) {\n\t\t\t\t\t\tresults.push(title);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t} else {\n\t\tif(operator.regexp) {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler) {\n\t\t\t\t\tvar text = tiddler.getFieldString(fieldname);\n\t\t\t\t\tif(text !== null && !!operator.regexp.exec(text)) {\n\t\t\t\t\t\tresults.push(title);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tif(source.byField && operator.operand) {\n\t\t\t\tindexedResults = source.byField(fieldname,operator.operand);\n\t\t\t\tif(indexedResults) {\n\t\t\t\t\treturn indexedResults\n\t\t\t\t}\n\t\t\t}\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler) {\n\t\t\t\t\tvar text = tiddler.getFieldString(fieldname);\n\t\t\t\t\tif(text !== null && text === operator.operand) {\n\t\t\t\t\t\tresults.push(title);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/fields.js":{"title":"$:/core/modules/filters/fields.js","text":"/*\\\ntitle: $:/core/modules/filters/fields.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the names of the fields on the selected tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.fields = function(source,operator,options) {\n\tvar results = [],\n\t\tfieldName,\n\t\tsuffixes = (operator.suffixes || [])[0] || [],\n\t\toperand = $tw.utils.parseStringArray(operator.operand);\n\n\tsource(function(tiddler,title) {\n\t\tif(tiddler) {\n\t\t\tif(suffixes.indexOf(\"include\") !== -1) {\n\t\t\t\tfor(fieldName in tiddler.fields) {\n\t\t\t\t\t(operand.indexOf(fieldName) !== -1) ? $tw.utils.pushTop(results,fieldName) : \"\";\n\t\t\t\t}\n\t\t\t} else if (suffixes.indexOf(\"exclude\") !== -1) {\n\t\t\t\tfor(fieldName in tiddler.fields) {\n\t\t\t\t\t(operand.indexOf(fieldName) !== -1) ? \"\" : $tw.utils.pushTop(results,fieldName);\n\t\t\t\t}\n\t\t\t} // else if\n\t\t\telse {\n\t\t\t\tfor(fieldName in tiddler.fields) {\n\t\t\t\t\t$tw.utils.pushTop(results,fieldName);\n\t\t\t\t}\n\t\t\t} // else\n\t\t} // if (tiddler)\n\t});\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/filter.js":{"title":"$:/core/modules/filters/filter.js","text":"/*\\\ntitle: $:/core/modules/filters/filter.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning those input titles that pass a subfilter\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.filter = function(source,operator,options) {\n\tvar filterFn = options.wiki.compileFilter(operator.operand),\n\t\tresults = [],\n\t\ttarget = operator.prefix !== \"!\";\n\tsource(function(tiddler,title) {\n\t\tvar list = filterFn.call(options.wiki,options.wiki.makeTiddlerIterator([title]),options.widget.makeFakeWidgetWithVariables({\n\t\t\t\"currentTiddler\": \"\" + title,\n\t\t\t\"..currentTiddler\": options.widget.getVariable(\"currentTiddler\",\"\")\n\t\t}));\n\t\tif((list.length > 0) === target) {\n\t\t\tresults.push(title);\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/format/date.js":{"title":"$:/core/modules/filters/format/date.js","text":"/*\\\ntitle: $:/core/modules/filters/format/date.js\ntype: application/javascript\nmodule-type: formatfilteroperator\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.date = function(source,operand,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar value = $tw.utils.parseDate(title);\n\t\tif(value && $tw.utils.isDate(value) && value.toString() !== \"Invalid Date\") {\n\t\t\tresults.push($tw.utils.formatDateString(value,operand || \"YYYY MM DD 0hh:0mm\"));\n\t\t}\n\t});\n\treturn results;\n};\n\n})();","type":"application/javascript","module-type":"formatfilteroperator"},"$:/core/modules/filters/format/json.js":{"title":"$:/core/modules/filters/format/json.js","text":"/*\\\ntitle: $:/core/modules/filters/format/json.js\ntype: application/javascript\nmodule-type: formatfilteroperator\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.json = function(source,operand,options) {\n\tvar results = [],\n\t\tspaces = null;\n\tif(operand) {\n\t\tspaces = /^\\d+$/.test(operand) ? parseInt(operand,10) : operand;\n\t}\n\tsource(function(tiddler,title) {\n\t\tvar data = $tw.utils.parseJSONSafe(title);\n\t\ttry {\n\t\t\tdata = JSON.parse(title);\n\t\t} catch(e) {\n\t\t\tdata = undefined;\n\t\t}\n\t\tif(data !== undefined) {\n\t\t\tresults.push(JSON.stringify(data,null,spaces));\n\t\t}\n\t});\n\treturn results;\n};\n\n})();","type":"application/javascript","module-type":"formatfilteroperator"},"$:/core/modules/filters/format/relativedate.js":{"title":"$:/core/modules/filters/format/relativedate.js","text":"/*\\\ntitle: $:/core/modules/filters/format/relativedate.js\ntype: application/javascript\nmodule-type: formatfilteroperator\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.relativedate = function(source,operand,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar value = $tw.utils.parseDate(title);\n\t\tif(value && $tw.utils.isDate(value) && value.toString() !== \"Invalid Date\") {\n\t\t\tresults.push($tw.utils.getRelativeDate((new Date()) - (new Date(value))).description);\n\t\t}\n\t});\n\treturn results;\n};\n\n})();","type":"application/javascript","module-type":"formatfilteroperator"},"$:/core/modules/filters/format/timestamp.js":{"title":"$:/core/modules/filters/format/timestamp.js","text":"/*\\\ntitle: $:/core/modules/filters/format/timestamp.js\ntype: application/javascript\nmodule-type: formatfilteroperator\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.timestamp = function(source,operand,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tif (title.match(/^-?\\d+$/)) {\n\t\t\tvar value = new Date(Number(title));\n\t\t\tresults.push($tw.utils.formatDateString(value,operand || \"[UTC]YYYY0MM0DD0hh0mm0ss0XXX\"));\n\t\t}\n\t});\n\treturn results;\n};\n})();","type":"application/javascript","module-type":"formatfilteroperator"},"$:/core/modules/filters/format/titlelist.js":{"title":"$:/core/modules/filters/format/titlelist.js","text":"/*\\\ntitle: $:/core/modules/filters/format/titlelist.js\ntype: application/javascript\nmodule-type: formatfilteroperator\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.titlelist = function(source,operand,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tif(title && title.length) {\n\t\t\tresults.push($tw.utils.stringifyList([title]));\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"formatfilteroperator"},"$:/core/modules/filters/format.js":{"title":"$:/core/modules/filters/format.js","text":"/*\\\ntitle: $:/core/modules/filters/format.js\ntype: application/javascript\nmodule-type: filteroperator\nFilter operator for formatting strings\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar formatFilterOperators;\n\nfunction getFormatFilterOperators() {\n\tif(!formatFilterOperators) {\n\t\tformatFilterOperators = {};\n\t\t$tw.modules.applyMethods(\"formatfilteroperator\",formatFilterOperators);\n\t}\n\treturn formatFilterOperators;\n}\n\n/*\nExport our filter function\n*/\nexports.format = function(source,operator,options) {\n\t// Dispatch to the correct formatfilteroperator\n\tvar formatFilterOperators = getFormatFilterOperators();\n\tif(operator.suffix) {\n\t\tvar formatFilterOperator = formatFilterOperators[operator.suffix];\n\t\tif(formatFilterOperator) {\n\t\t\treturn formatFilterOperator(source,operator.operand,options);\n\t\t} else {\n\t\t\treturn [$tw.language.getString(\"Error/FormatFilterOperator\")];\n\t\t}\n\t} else {\n\t\t// Return all unchanged if the suffix is missing\n\t\tvar results = [];\n\t\tsource(function(tiddler,title) {\n\t\t\tresults.push(title);\n\t\t});\n\t\treturn results;\n\t}\n};\n\n})();","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/function.js":{"title":"$:/core/modules/filters/function.js","text":"/*\\\ntitle: $:/core/modules/filters/function.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning those input titles that are returned from a function\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.function = function(source,operator,options) {\n\tvar functionName = operator.operands[0],\n\t\tparams = [];\n\t$tw.utils.each(operator.operands.slice(1),function(param) {\n\t\tparams.push({value: param});\n\t});\n\tvar variableInfo = options.widget && options.widget.getVariableInfo && options.widget.getVariableInfo(functionName,{params: params, source: source});\n\tif(variableInfo && variableInfo.srcVariable && variableInfo.srcVariable.isFunctionDefinition) {\n\t\treturn variableInfo.resultList ? variableInfo.resultList : [variableInfo.text];\n\t}\n\t// Return the input list if the function wasn't found\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/get.js":{"title":"$:/core/modules/filters/get.js","text":"/*\\\ntitle: $:/core/modules/filters/get.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for replacing tiddler titles by the value of the field specified in the operand.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.get = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tif(tiddler) {\n\t\t\tvar value = tiddler.getFieldString(operator.operand);\n\t\t\tif(value) {\n\t\t\t\tresults.push(value);\n\t\t\t}\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/getindex.js":{"title":"$:/core/modules/filters/getindex.js","text":"/*\\\ntitle: $:/core/modules/filters/getindex.js\ntype: application/javascript\nmodule-type: filteroperator\n\nreturns the value at a given index of datatiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.getindex = function(source,operator,options) {\n\tvar data,title,results = [];\n\tif(operator.operand){\n\t\tsource(function(tiddler,title) {\n\t\t\ttitle = tiddler ? tiddler.fields.title : title;\n\t\t\tdata = options.wiki.extractTiddlerDataItem(tiddler,operator.operand);\n\t\t\tif(data) {\n\t\t\t\tresults.push(data);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/getvariable.js":{"title":"$:/core/modules/filters/getvariable.js","text":"/*\\\ntitle: $:/core/modules/filters/getvariable.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for replacing input values by the value of the variable with the same name, or blank if the variable is missing\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.getvariable = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(options.widget.getVariable(title) || \"\");\n\t});\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/has.js":{"title":"$:/core/modules/filters/has.js","text":"/*\\\ntitle: $:/core/modules/filters/has.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for checking if a tiddler has the specified field or index\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.has = function(source,operator,options) {\n\tvar results = [],\n\t\tinvert = operator.prefix === \"!\";\n\n\tif(operator.suffix === \"field\") {\n\t\tif(invert) {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(!tiddler || (tiddler && (!$tw.utils.hop(tiddler.fields,operator.operand)))) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler && $tw.utils.hop(tiddler.fields,operator.operand)) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\telse if(operator.suffix === \"index\") {\n\t\tif(invert) {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(!tiddler || (tiddler && (!$tw.utils.hop(options.wiki.getTiddlerDataCached(tiddler,Object.create(null)),operator.operand)))) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler && $tw.utils.hop(options.wiki.getTiddlerDataCached(tiddler,Object.create(null)),operator.operand)) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\telse {\n\t\tif(invert) {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(!tiddler || !$tw.utils.hop(tiddler.fields,operator.operand) || (tiddler.fields[operator.operand].length === 0)) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler && $tw.utils.hop(tiddler.fields,operator.operand) && (tiddler.fields[operator.operand].length !== 0)) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/haschanged.js":{"title":"$:/core/modules/filters/haschanged.js","text":"/*\\\ntitle: $:/core/modules/filters/haschanged.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returns tiddlers from the list that have a non-zero changecount.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.haschanged = function(source,operator,options) {\n\tvar results = [];\n\tif(operator.prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.wiki.getChangeCount(title) === 0) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.wiki.getChangeCount(title) > 0) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/indexes.js":{"title":"$:/core/modules/filters/indexes.js","text":"/*\\\ntitle: $:/core/modules/filters/indexes.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the indexes of a data tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.indexes = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar data = options.wiki.getTiddlerDataCached(title);\n\t\tif(data) {\n\t\t\t$tw.utils.pushTop(results,Object.keys(data));\n\t\t}\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/insertafter.js":{"title":"$:/core/modules/filters/insertafter.js","text":"/*\\\ntitle: $:/core/modules/filters/insertafter.js\ntype: application/javascript\nmodule-type: filteroperator\n\nInsert an item after another item in a list\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nOrder a list\n*/\nexports.insertafter = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\tvar target = operator.operands[1] || (options.widget && options.widget.getVariable(operator.suffix || \"currentTiddler\"));\n\tif(target !== operator.operand) {\n\t\t// Remove the entry from the list if it is present\n\t\tvar pos = results.indexOf(operator.operand);\n\t\tif(pos !== -1) {\n\t\t\tresults.splice(pos,1);\n\t\t}\n\t\t// Insert the entry after the target marker\n\t\tpos = results.indexOf(target);\n\t\tif(pos !== -1) {\n\t\t\tresults.splice(pos+1,0,operator.operand);\n\t\t} else {\n\t\t\tvar suffix = operator.operands.length > 1 ? operator.suffix : \"\";\n\t\t\tif(suffix === \"start\") {\n\t\t\t\tresults.splice(0,0,operator.operand);\n\t\t\t} else {\n\t\t\t\tresults.push(operator.operand);\n\t\t\t}\n\t\t}\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/insertbefore.js":{"title":"$:/core/modules/filters/insertbefore.js","text":"/*\\\ntitle: $:/core/modules/filters/insertbefore.js\ntype: application/javascript\nmodule-type: filteroperator\n\nInsert an item before another item in a list\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nOrder a list\n*/\nexports.insertbefore = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\tvar target = operator.operands[1] || (options.widget && options.widget.getVariable(operator.suffix || \"currentTiddler\"));\n\tif(target !== operator.operand) {\n\t\t// Remove the entry from the list if it is present\n\t\tvar pos = results.indexOf(operator.operand);\n\t\tif(pos !== -1) {\n\t\t\tresults.splice(pos,1);\n\t\t}\n\t\t// Insert the entry before the target marker\n\t\tpos = results.indexOf(target);\n\t\tif(pos !== -1) {\n\t\t\tresults.splice(pos,0,operator.operand);\n\t\t} else {\n\t\t\tvar suffix = operator.operands.length > 1 ? operator.suffix : \"\";\n\t\t\tif(suffix == \"start\") {\n\t\t\t\tresults.splice(0,0,operator.operand);\n\t\t\t} else {\n\t\t\t\tresults.push(operator.operand);\n\t\t\t}\n\t\t}\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/is/binary.js":{"title":"$:/core/modules/filters/is/binary.js","text":"/*\\\ntitle: $:/core/modules/filters/is/binary.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[binary]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.binary = function(source,prefix,options) {\n\tvar results = [];\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!options.wiki.isBinaryTiddler(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.wiki.isBinaryTiddler(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"isfilteroperator"},"$:/core/modules/filters/is/blank.js":{"title":"$:/core/modules/filters/is/blank.js","text":"/*\\\ntitle: $:/core/modules/filters/is/blank.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[blank]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.blank = function(source,prefix,options) {\n\tvar results = [];\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(title) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!title) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"isfilteroperator"},"$:/core/modules/filters/is/current.js":{"title":"$:/core/modules/filters/is/current.js","text":"/*\\\ntitle: $:/core/modules/filters/is/current.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[current]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.current = function(source,prefix,options) {\n\tvar results = [],\n\t\tcurrTiddlerTitle = options.widget && options.widget.getVariable(\"currentTiddler\");\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(title !== currTiddlerTitle) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(title === currTiddlerTitle) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"isfilteroperator"},"$:/core/modules/filters/is/draft.js":{"title":"$:/core/modules/filters/is/draft.js","text":"/*\\\ntitle: $:/core/modules/filters/is/draft.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[draft]] analagous to [has[draft.of]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.draft = function(source,prefix,options) {\n\tvar results = [];\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!tiddler || !tiddler.isDraft()) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(tiddler && tiddler.isDraft()) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"isfilteroperator"},"$:/core/modules/filters/is/image.js":{"title":"$:/core/modules/filters/is/image.js","text":"/*\\\ntitle: $:/core/modules/filters/is/image.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[image]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.image = function(source,prefix,options) {\n\tvar results = [];\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!options.wiki.isImageTiddler(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.wiki.isImageTiddler(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"isfilteroperator"},"$:/core/modules/filters/is/missing.js":{"title":"$:/core/modules/filters/is/missing.js","text":"/*\\\ntitle: $:/core/modules/filters/is/missing.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[missing]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.missing = function(source,prefix,options) {\n\tvar results = [];\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.wiki.tiddlerExists(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!options.wiki.tiddlerExists(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"isfilteroperator"},"$:/core/modules/filters/is/orphan.js":{"title":"$:/core/modules/filters/is/orphan.js","text":"/*\\\ntitle: $:/core/modules/filters/is/orphan.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[orphan]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.orphan = function(source,prefix,options) {\n\tvar results = [],\n\t\torphanTitles = options.wiki.getOrphanTitles();\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(orphanTitles.indexOf(title) === -1) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(orphanTitles.indexOf(title) !== -1) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"isfilteroperator"},"$:/core/modules/filters/is/shadow.js":{"title":"$:/core/modules/filters/is/shadow.js","text":"/*\\\ntitle: $:/core/modules/filters/is/shadow.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[shadow]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.shadow = function(source,prefix,options) {\n\tvar results = [];\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!options.wiki.isShadowTiddler(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.wiki.isShadowTiddler(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"isfilteroperator"},"$:/core/modules/filters/is/system.js":{"title":"$:/core/modules/filters/is/system.js","text":"/*\\\ntitle: $:/core/modules/filters/is/system.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[system]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.system = function(source,prefix,options) {\n\tvar results = [];\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!options.wiki.isSystemTiddler(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.wiki.isSystemTiddler(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"isfilteroperator"},"$:/core/modules/filters/is/tag.js":{"title":"$:/core/modules/filters/is/tag.js","text":"/*\\\ntitle: $:/core/modules/filters/is/tag.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[tag]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.tag = function(source,prefix,options) {\n\tvar results = [],\n\t\ttagMap = options.wiki.getTagMap();\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!$tw.utils.hop(tagMap,title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif($tw.utils.hop(tagMap,title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"isfilteroperator"},"$:/core/modules/filters/is/tiddler.js":{"title":"$:/core/modules/filters/is/tiddler.js","text":"/*\\\ntitle: $:/core/modules/filters/is/tiddler.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[tiddler]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.tiddler = function(source,prefix,options) {\n\tvar results = [];\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!options.wiki.tiddlerExists(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.wiki.tiddlerExists(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"isfilteroperator"},"$:/core/modules/filters/is/variable.js":{"title":"$:/core/modules/filters/is/variable.js","text":"/*\\\ntitle: $:/core/modules/filters/is/variable.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[variable]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.variable = function(source,prefix,options) {\n\tvar results = [];\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.widget.getVariable(title) === undefined) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.widget.getVariable(title) !== undefined) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"isfilteroperator"},"$:/core/modules/filters/is.js":{"title":"$:/core/modules/filters/is.js","text":"/*\\\ntitle: $:/core/modules/filters/is.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for checking tiddler properties\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar isFilterOperators;\n\nfunction getIsFilterOperators() {\n\tif(!isFilterOperators) {\n\t\tisFilterOperators = {};\n\t\t$tw.modules.applyMethods(\"isfilteroperator\",isFilterOperators);\n\t}\n\treturn isFilterOperators;\n}\n\n/*\nExport our filter function\n*/\nexports.is = function(source,operator,options) {\n\t// Dispatch to the correct isfilteroperator\n\tvar isFilterOperators = getIsFilterOperators();\n\tif(operator.operand) {\n\t\tvar isFilterOperator = isFilterOperators[operator.operand];\n\t\tif(isFilterOperator) {\n\t\t\treturn isFilterOperator(source,operator.prefix,options);\n\t\t} else {\n\t\t\treturn [$tw.language.getString(\"Error/IsFilterOperator\")];\n\t\t}\n\t} else {\n\t\t// Return all tiddlers if the operand is missing\n\t\tvar results = [];\n\t\tsource(function(tiddler,title) {\n\t\t\tresults.push(title);\n\t\t});\n\t\treturn results;\n\t}\n};\n\n})();","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/json-ops.js":{"title":"$:/core/modules/filters/json-ops.js","text":"/*\\\ntitle: $:/core/modules/filters/json-ops.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operators for JSON operations\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"jsonget\"] = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar data = $tw.utils.parseJSONSafe(title,title);\n\t\tif(data) {\n\t\t\tvar items = getDataItemValueAsStrings(data,operator.operands);\n\t\t\tif(items !== undefined) {\n\t\t\t\tresults.push.apply(results,items);\n\t\t\t}\n\t\t}\n\t});\n\treturn results;\n};\n\nexports[\"jsonextract\"] = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar data = $tw.utils.parseJSONSafe(title,title);\n\t\tif(data) {\n\t\t\tvar item = getDataItem(data,operator.operands);\n\t\t\tif(item !== undefined) {\n\t\t\t\tresults.push(JSON.stringify(item));\n\t\t\t}\n\t\t}\n\t});\n\treturn results;\n};\n\nexports[\"jsonindexes\"] = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar data = $tw.utils.parseJSONSafe(title,title);\n\t\tif(data) {\n\t\t\tvar items = getDataItemKeysAsStrings(data,operator.operands);\n\t\t\tif(items !== undefined) {\n\t\t\t\tresults.push.apply(results,items);\n\t\t\t}\n\t\t}\n\t});\n\treturn results;\n};\n\nexports[\"jsontype\"] = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar data = $tw.utils.parseJSONSafe(title,title);\n\t\tif(data) {\n\t\t\tvar item = getDataItemType(data,operator.operands);\n\t\t\tif(item !== undefined) {\n\t\t\t\tresults.push(item);\n\t\t\t}\n\t\t}\n\t});\n\treturn results;\n};\n\nexports[\"jsonset\"] = function(source,operator,options) {\n\tvar suffixes = operator.suffixes || [],\n\t\ttype = suffixes[0] && suffixes[0][0],\n\t\tindexes = operator.operands.slice(0,-1),\n\t\tvalue = operator.operands[operator.operands.length - 1],\n\t\tresults = [];\n\tif(operator.operands.length === 1 && operator.operands[0] === \"\") {\n\t\tvalue = undefined; // Prevents the value from being assigned\n\t}\n\tswitch(type) {\n\t\tcase \"string\":\n\t\t\t// Use value unchanged\n\t\t\tbreak;\n\t\tcase \"boolean\":\n\t\t\tvalue = (value === \"true\" ? true : (value === \"false\" ? false : undefined));\n\t\t\tbreak;\n\t\tcase \"number\":\n\t\t\tvalue = $tw.utils.parseNumber(value);\n\t\t\tbreak;\n\t\tcase \"array\":\n\t\t\tindexes = operator.operands;\n\t\t\tvalue = [];\n\t\t\tbreak;\n\t\tcase \"object\":\n\t\t\tindexes = operator.operands;\n\t\t\tvalue = {};\n\t\t\tbreak;\n\t\tcase \"null\":\n\t\t\tindexes = operator.operands;\n\t\t\tvalue = null;\n\t\t\tbreak;\n\t\tcase \"json\":\n\t\t\tvalue = $tw.utils.parseJSONSafe(value,function() {return undefined;});\n\t\t\tbreak;\n\t\tdefault:\n\t\t\t// Use value unchanged\n\t\t\tbreak;\n\t}\n\tsource(function(tiddler,title) {\n\t\tvar data = $tw.utils.parseJSONSafe(title,title);\n\t\tif(data) {\n\t\t\tdata = setDataItem(data,indexes,value);\n\t\t\tresults.push(JSON.stringify(data));\n\t\t}\n\t});\n\treturn results;\n};\n\n/*\nGiven a JSON data structure and an array of index strings, return an array of the string representation of the values at the end of the index chain, or \"undefined\" if any of the index strings are invalid\n*/\nfunction getDataItemValueAsStrings(data,indexes) {\n\t// Get the item\n\tvar item = getDataItem(data,indexes);\n\t// Return the item as a string list\n\treturn convertDataItemValueToStrings(item);\n}\n\n/*\nGiven a JSON data structure and an array of index strings, return an array of the string representation of the keys of the item at the end of the index chain, or \"undefined\" if any of the index strings are invalid\n*/\nfunction getDataItemKeysAsStrings(data,indexes) {\n\t// Get the item\n\tvar item = getDataItem(data,indexes);\n\t// Return the item keys as a string\n\treturn convertDataItemKeysToStrings(item);\n}\n\n/*\nReturn an array of the string representation of the values of a data item, or \"undefined\" if the item is undefined\n*/\nfunction convertDataItemValueToStrings(item) {\n\t// Return the item as a string\n\tif(item === undefined) {\n\t\treturn undefined;\n\t} else if(item === null) {\n\t\treturn [\"null\"]\n\t} else if(typeof item === \"object\") {\n\t\tvar results = [],i,t;\n\t\tif($tw.utils.isArray(item)) {\n\t\t\t// Return all the items in arrays recursively\n\t\t\tfor(i=0; i<item.length; i++) {\n\t\t\t\tt = convertDataItemValueToStrings(item[i])\n\t\t\t\tif(t !== undefined) {\n\t\t\t\t\tresults.push.apply(results,t);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// Return all the values in objects recursively\n\t\t\t$tw.utils.each(Object.keys(item).sort(),function(key) {\n\t\t\t\tt = convertDataItemValueToStrings(item[key]);\n\t\t\t\tif(t !== undefined) {\n\t\t\t\t\tresults.push.apply(results,t);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\treturn results;\n\t}\n\treturn [item.toString()];\n}\n\n/*\nReturn an array of the string representation of the keys of a data item, or \"undefined\" if the item is undefined\n*/\nfunction convertDataItemKeysToStrings(item) {\n\t// Return the item as a string\n\tif(item === undefined) {\n\t\treturn item;\n\t} else if(typeof item === \"object\") {\n\t\tif(item === null) {\n\t\t\treturn [];\n\t\t}\n\t\tvar results = [];\n\t\tif($tw.utils.isArray(item)) {\n\t\t\tfor(var i=0; i<item.length; i++) {\n\t\t\t\tresults.push(i.toString());\n\t\t\t}\n\t\t\treturn results;\n\t\t} else {\n\t\t\t$tw.utils.each(Object.keys(item).sort(),function(key) {\n\t\t\t\tresults.push(key);\n\t\t\t});\n\t\t\treturn results;\n\t\t}\n\t}\n\treturn [];\n}\n\nfunction getDataItemType(data,indexes) {\n\t// Get the item\n\tvar item = getDataItem(data,indexes);\n\t// Return the item type\n\tif(item === undefined) {\n\t\treturn item;\n\t} else if(item === null) {\n\t\treturn \"null\";\n\t} else if($tw.utils.isArray(item)) {\n\t\treturn \"array\";\n\t} else if(typeof item === \"object\") {\n\t\treturn \"object\";\n\t} else {\n\t\treturn typeof item;\n\t}\n}\n\nfunction getItemAtIndex(item,index) {\n\tif($tw.utils.hop(item,index)) {\n\t\treturn item[index];\n\t} else if($tw.utils.isArray(item)) {\n\t\tindex = $tw.utils.parseInt(index);\n\t\tif(index < 0) { index = index + item.length };\n\t\treturn item[index]; // Will be undefined if index was out-of-bounds\n\t} else {\n\t\treturn undefined;\n\t}\n}\n\n/*\nGiven a JSON data structure and an array of index strings, return the value at the end of the index chain, or \"undefined\" if any of the index strings are invalid\n*/\nfunction getDataItem(data,indexes) {\n\tif(indexes.length === 0 || (indexes.length === 1 && indexes[0] === \"\")) {\n\t\treturn data;\n\t}\n\t// Get the item\n\tvar item = data;\n\tfor(var i=0; i<indexes.length; i++) {\n\t\tif(item !== undefined) {\n\t\t\tif(item !== null && [\"number\",\"string\",\"boolean\"].indexOf(typeof item) === -1) {\n\t\t\t\titem = getItemAtIndex(item,indexes[i]);\n\t\t\t} else {\n\t\t\t\titem = undefined;\n\t\t\t}\n\t\t}\n\t}\n\treturn item;\n}\n\n/*\nGiven a JSON data structure, an array of index strings and a value, return the data structure with the value added at the end of the index chain. If any of the index strings are invalid then the JSON data structure is returned unmodified. If the root item is targetted then a different data object will be returned\n*/\nfunction setDataItem(data,indexes,value) {\n\t// Ignore attempts to assign undefined\n\tif(value === undefined) {\n\t\treturn data;\n\t}\n\t// Check for the root item\n\tif(indexes.length === 0 || (indexes.length === 1 && indexes[0] === \"\")) {\n\t\treturn value;\n\t}\n\t// Traverse the JSON data structure using the index chain\n\tvar current = data;\n\tfor(var i = 0; i < indexes.length - 1; i++) {\n\t\tcurrent = getItemAtIndex(current,indexes[i]);\n\t\tif(current === undefined) {\n\t\t\t// Return the original JSON data structure if any of the index strings are invalid\n\t\t\treturn data;\n\t\t}\n\t}\n\t// Add the value to the end of the index chain\n\tvar lastIndex = indexes[indexes.length - 1];\n\tif($tw.utils.isArray(current)) {\n\t\tlastIndex = $tw.utils.parseInt(lastIndex);\n\t\tif(lastIndex < 0) { lastIndex = lastIndex + current.length };\n\t}\n\t// Only set indexes on objects and arrays\n\tif(typeof current === \"object\") {\n\t\tcurrent[lastIndex] = value;\n\t}\n\treturn data;\n}\n\n})();\n\t","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/limit.js":{"title":"$:/core/modules/filters/limit.js","text":"/*\\\ntitle: $:/core/modules/filters/limit.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for chopping the results to a specified maximum number of entries\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.limit = function(source,operator,options) {\n\tvar results = [];\n\t// Convert to an array\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\t// Slice the array if necessary\n\tvar limit = Math.min(results.length,parseInt(operator.operand,10));\n\tif(operator.prefix === \"!\") {\n\t\tresults = results.slice(-limit);\n\t} else {\n\t\tresults = results.slice(0,limit);\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/links.js":{"title":"$:/core/modules/filters/links.js","text":"/*\\\ntitle: $:/core/modules/filters/links.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning all the links from a tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.links = function(source,operator,options) {\n\tvar results = new $tw.utils.LinkedList();\n\tsource(function(tiddler,title) {\n\t\tresults.pushTop(options.wiki.getTiddlerLinks(title));\n\t});\n\treturn results.makeTiddlerIterator(options.wiki);\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/list.js":{"title":"$:/core/modules/filters/list.js","text":"/*\\\ntitle: $:/core/modules/filters/list.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning the tiddlers whose title is listed in the operand tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.list = function(source,operator,options) {\n\tvar results = [],\n\t\ttr = $tw.utils.parseTextReference(operator.operand),\n\t\tcurrTiddlerTitle = options.widget && options.widget.getVariable(\"currentTiddler\"),\n\t\tlist = options.wiki.getTiddlerList(tr.title || currTiddlerTitle,tr.field,tr.index);\n\tif(operator.prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(list.indexOf(title) === -1) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tresults = list;\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/listed.js":{"title":"$:/core/modules/filters/listed.js","text":"/*\\\ntitle: $:/core/modules/filters/listed.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning all tiddlers that have the selected tiddlers in a list\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.listed = function(source,operator,options) {\n\tvar field = operator.operand || \"list\",\n\t\tresults = [];\n\tsource(function(tiddler,title) {\n\t\t$tw.utils.pushTop(results,options.wiki.findListingsOfTiddler(title,field));\n\t});\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/listops.js":{"title":"$:/core/modules/filters/listops.js","text":"/*\\\ntitle: $:/core/modules/filters/listops.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operators for manipulating the current selection list\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nOrder a list\n*/\nexports.order = function(source,operator,options) {\n\tvar results = [];\n\tif(operator.operand.toLowerCase() === \"reverse\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tresults.unshift(title);\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tresults.push(title);\n\t\t});\n\t}\n\treturn results;\n};\n\n/*\nReverse list\n*/\nexports.reverse = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.unshift(title);\n\t});\n\treturn results;\n};\n\n/*\nFirst entry/entries in list\n*/\nexports.first = function(source,operator,options) {\n\tvar count = $tw.utils.getInt(operator.operand,1),\n\t\tresults = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\treturn results.slice(0,count);\n};\n\n/*\nLast entry/entries in list\n*/\nexports.last = function(source,operator,options) {\n\tvar count = $tw.utils.getInt(operator.operand,1),\n\t\tresults = [];\n\tif(count === 0) return results;\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\treturn results.slice(-count);\n};\n\n/*\nAll but the first entry/entries of the list\n*/\nexports.rest = function(source,operator,options) {\n\tvar count = $tw.utils.getInt(operator.operand,1),\n\t\tresults = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\treturn results.slice(count);\n};\nexports.butfirst = exports.rest;\nexports.bf = exports.rest;\n\n/*\nAll but the last entry/entries of the list\n*/\nexports.butlast = function(source,operator,options) {\n\tvar count = $tw.utils.getInt(operator.operand,1),\n\t\tresults = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\tvar index = count === 0 ? results.length : -count;\n\treturn results.slice(0,index);\n};\nexports.bl = exports.butlast;\n\n/*\nThe nth member of the list\n*/\nexports.nth = function(source,operator,options) {\n\tvar count = $tw.utils.getInt(operator.operand,1),\n\t\tresults = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\treturn results.slice(count - 1,count);\n};\n\n/*\nThe zero based nth member of the list\n*/\nexports.zth = function(source,operator,options) {\n\tvar count = $tw.utils.getInt(operator.operand,0),\n\t\tresults = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\treturn results.slice(count,count + 1);\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/lookup.js":{"title":"$:/core/modules/filters/lookup.js","text":"/*\\\ntitle: $:/core/modules/filters/lookup.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator that looks up values via a title prefix\n\n[lookup:<defaultvalue>:<field OR index>[<prefix>],[<field-name OR index-name>]]\n\nPrepends the prefix to the selected items and returns the specified \nfield or index value. If the 2nd suffix does not exist, it defaults to field.\nIf the second operand is missing it defaults to \"text\" for fields, and \"0\" for indexes\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.lookup = function(source,operator,options) {\n\tvar results = [],\n\t\tsuffixes = operator.suffixes || [],\n\t\tdefaultSuffix = suffixes[0] ? (suffixes[0][0] || \"\") : \"\",\n\t\tindexSuffix = (suffixes[1] && suffixes[1][0] === \"index\") ? true : false,\n\t\ttarget;\n\tif(operator.operands.length == 2) {\n\t\ttarget = operator.operands[1]\n\t} else {\n\t\ttarget = indexSuffix ? \"0\": \"text\";\n\t}\n\tif(indexSuffix) {\n\t\tsource(function(tiddler,title) {\n\t\t\tvar data = options.wiki.extractTiddlerDataItem(operator.operands[0]+title,target,defaultSuffix);\n\t\t\tresults.push(data);\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tvar value = defaultSuffix;\n\t\t\tvar targetTiddler = options.wiki.getTiddler(operator.operands[0]+title);\n\t\t\tif(targetTiddler && targetTiddler.getFieldString(target)) {\n\t\t\t\tvalue = targetTiddler.getFieldString(target);\n\t\t\t}\n\t\t\tresults.push(value);\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/match.js":{"title":"$:/core/modules/filters/match.js","text":"/*\\\ntitle: $:/core/modules/filters/match.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for checking if a title matches a string\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.match = function(source,operator,options) {\n\tvar results = [],\n\t\tsuffixes = (operator.suffixes || [])[0] || [];\n\tif(suffixes.indexOf(\"caseinsensitive\") !== -1) {\n\t\tif(operator.prefix === \"!\") {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(title.toLowerCase() !== (operator.operand || \"\").toLowerCase()) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(title.toLowerCase() === (operator.operand || \"\").toLowerCase()) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t} else {\n\t\tif(operator.prefix === \"!\") {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(title !== operator.operand) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(title === operator.operand) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/math.js":{"title":"$:/core/modules/filters/math.js","text":"/*\\\ntitle: $:/core/modules/filters/math.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operators for math. Unary/binary operators work on each item in turn, and return a new item list.\n\nSum/product/maxall/minall operate on the entire list, returning a single item.\n\nNote that strings are converted to numbers automatically. Trailing non-digits are ignored.\n\n* \"\" converts to 0\n* \"12kk\" converts to 12\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.negate = makeNumericBinaryOperator(\n\tfunction(a) {return -a}\n);\n\nexports.abs = makeNumericBinaryOperator(\n\tfunction(a) {return Math.abs(a)}\n);\n\nexports.ceil = makeNumericBinaryOperator(\n\tfunction(a) {return Math.ceil(a)}\n);\n\nexports.floor = makeNumericBinaryOperator(\n\tfunction(a) {return Math.floor(a)}\n);\n\nexports.round = makeNumericBinaryOperator(\n\tfunction(a) {return Math.round(a)}\n);\n\nexports.trunc = makeNumericBinaryOperator(\n\tfunction(a) {return Math.trunc(a)}\n);\n\nexports.untrunc = makeNumericBinaryOperator(\n\tfunction(a) {return Math.ceil(Math.abs(a)) * Math.sign(a)}\n);\n\nexports.sign = makeNumericBinaryOperator(\n\tfunction(a) {return Math.sign(a)}\n);\n\nexports.add = makeNumericBinaryOperator(\n\tfunction(a,b) {return a + b;}\n);\n\nexports.subtract = makeNumericBinaryOperator(\n\tfunction(a,b) {return a - b;}\n);\n\nexports.multiply = makeNumericBinaryOperator(\n\tfunction(a,b) {return a * b;}\n);\n\nexports.divide = makeNumericBinaryOperator(\n\tfunction(a,b) {return a / b;}\n);\n\nexports.remainder = makeNumericBinaryOperator(\n\tfunction(a,b) {return a % b;}\n);\n\nexports.max = makeNumericBinaryOperator(\n\tfunction(a,b) {return Math.max(a,b);}\n);\n\nexports.min = makeNumericBinaryOperator(\n\tfunction(a,b) {return Math.min(a,b);}\n);\n\nexports.fixed = makeNumericBinaryOperator(\n\tfunction(a,b) {return Number.prototype.toFixed.call(a,Math.min(Math.max(b,0),100));}\n);\n\nexports.precision = makeNumericBinaryOperator(\n\tfunction(a,b) {return Number.prototype.toPrecision.call(a,Math.min(Math.max(b,1),100));}\n);\n\nexports.exponential = makeNumericBinaryOperator(\n\tfunction(a,b) {return Number.prototype.toExponential.call(a,Math.min(Math.max(b,0),100));}\n);\n\nexports.power = makeNumericBinaryOperator(\n\tfunction(a,b) {return Math.pow(a,b);}\n);\n\nexports.log = makeNumericBinaryOperator(\n\tfunction(a,b) {\n\t\tif(b) {\n\t\t\treturn Math.log(a)/Math.log(b);\n\t\t} else {\n\t\t\treturn Math.log(a);\n\t\t}\n\t}\n);\n\nexports.sum = makeNumericReducingOperator(\n\tfunction(accumulator,value) {return accumulator + value},\n\t0 // Initial value\n);\n\nexports.product = makeNumericReducingOperator(\n\tfunction(accumulator,value) {return accumulator * value},\n\t1 // Initial value\n);\n\nexports.maxall = makeNumericReducingOperator(\n\tfunction(accumulator,value) {return Math.max(accumulator,value)},\n\t-Infinity // Initial value\n);\n\nexports.minall = makeNumericReducingOperator(\n\tfunction(accumulator,value) {return Math.min(accumulator,value)},\n\tInfinity // Initial value\n);\n\nexports.median = makeNumericArrayOperator(\n\tfunction(values) {\n\t\tvar len = values.length, median;\n\t\tvalues.sort();\n\t\tif(len % 2) { \n\t\t\t// Odd, return the middle number\n\t\t\tmedian = values[(len - 1) / 2];\n\t\t} else {\n\t\t\t// Even, return average of two middle numbers\n\t\t\tmedian = (values[len / 2 - 1] + values[len / 2]) / 2;\n\t\t}\n\t\treturn [median];\n\t}\n);\n\nexports.average = makeNumericReducingOperator(\n\tfunction(accumulator,value) {return accumulator + value},\n\t0, // Initial value\n\tfunction(finalValue,numberOfValues) {\n\t\treturn finalValue/numberOfValues;\n\t}\n);\n\nexports.variance = makeNumericReducingOperator(\n\tfunction(accumulator,value) {return accumulator + value},\n\t0,\n\tfunction(finalValue,numberOfValues,originalValues) {\n\t\treturn getVarianceFromArray(originalValues,finalValue/numberOfValues);\n\t}\n);\n\nexports[\"standard-deviation\"] = makeNumericReducingOperator(\n\tfunction(accumulator,value) {return accumulator + value},\n\t0,\n\tfunction(finalValue,numberOfValues,originalValues) {\n\t\tvar variance = getVarianceFromArray(originalValues,finalValue/numberOfValues);\n\t\treturn Math.sqrt(variance);\n\t}\n);\n\n//trigonometry\nexports.cos = makeNumericBinaryOperator(\n\tfunction(a) {return Math.cos(a)}\n);\n\nexports.sin = makeNumericBinaryOperator(\n\tfunction(a) {return Math.sin(a)}\n);\n\nexports.tan = makeNumericBinaryOperator(\n\tfunction(a) {return Math.tan(a)}\n);\n\nexports.acos = makeNumericBinaryOperator(\n\tfunction(a) {return Math.acos(a)}\n);\n\nexports.asin = makeNumericBinaryOperator(\n\tfunction(a) {return Math.asin(a)}\n);\n\nexports.atan = makeNumericBinaryOperator(\n\tfunction(a) {return Math.atan(a)}\n);\n\nexports.atan2 = makeNumericBinaryOperator(\n\tfunction(a,b) {return Math.atan2(a,b)}\n);\n\n//Calculate the variance of a population of numbers in an array given its mean\nfunction getVarianceFromArray(values,mean) {\n\tvar deviationTotal = values.reduce(function(accumulator,value) {\n\t\treturn accumulator + Math.pow(value - mean, 2);\n\t},0);\n\treturn deviationTotal/values.length;\n};\n\nfunction makeNumericBinaryOperator(fnCalc) {\n\treturn function(source,operator,options) {\n\t\tvar result = [],\n\t\t\tnumOperand = $tw.utils.parseNumber(operator.operand);\n\t\tsource(function(tiddler,title) {\n\t\t\tresult.push($tw.utils.stringifyNumber(fnCalc($tw.utils.parseNumber(title),numOperand)));\n\t\t});\n\t\treturn result;\n\t};\n};\n\nfunction makeNumericReducingOperator(fnCalc,initialValue,fnFinal) {\n\tinitialValue = initialValue || 0;\n\treturn function(source,operator,options) {\n\t\tvar result = [];\n\t\tsource(function(tiddler,title) {\n\t\t\tresult.push($tw.utils.parseNumber(title));\n\t\t});\n\t\tvar value = result.reduce(function(accumulator,currentValue) {\n\t\t\t\treturn fnCalc(accumulator,currentValue);\n\t\t\t},initialValue);\n\t\tif(fnFinal) {\n\t\t\tvalue = fnFinal(value,result.length,result);\n\t\t}\n\t\treturn [$tw.utils.stringifyNumber(value)];\n\t};\n};\n\nfunction makeNumericArrayOperator(fnCalc) {\n\treturn function(source,operator,options) {\n\t\tvar results = [];\n\t\tsource(function(tiddler,title) {\n\t\t\tresults.push($tw.utils.parseNumber(title));\n\t\t});\n\t\tresults = fnCalc(results);\n\t\t$tw.utils.each(results,function(value,index) {\n\t\t\tresults[index] = $tw.utils.stringifyNumber(value);\n\t\t});\n\t\treturn results;\n\t};\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/minlength.js":{"title":"$:/core/modules/filters/minlength.js","text":"/*\\\ntitle: $:/core/modules/filters/minlength.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for filtering out titles that don't meet the minimum length in the operand\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.minlength = function(source,operator,options) {\n\tvar results = [],\n\t\tminLength = parseInt(operator.operand || \"\",10) || 0;\n\tsource(function(tiddler,title) {\n\t\tif(title.length >= minLength) {\n\t\t\tresults.push(title);\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/moduleproperty.js":{"title":"$:/core/modules/filters/moduleproperty.js","text":"/*\\\ntitle: $:/core/modules/filters/moduleproperty.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter [[module-name]moduleproperty[name]] retrieve a module property\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.moduleproperty = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar value = require(title)[operator.operand || \"\"];\n\t\tif(value !== undefined) {\n\t\t\tresults.push(value);\n\t\t}\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/modules.js":{"title":"$:/core/modules/filters/modules.js","text":"/*\\\ntitle: $:/core/modules/filters/modules.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the titles of the modules of a given type in this wiki\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.modules = function(source,operator,options) {\n\tvar results = [];\n\tif(operator.operands.length >= 2) {\n\t\t// Return the modules that have the module property specified in the first operand with the value in the second operand\n\t\tsource(function(tiddler,title) {\n\t\t\t$tw.utils.each($tw.modules.types[title],function(moduleInfo,moduleName) {\n\t\t\t\tif(require(moduleName)[operator.operands[0]] === operator.operands[1]) {\n\t\t\t\t\tresults.push(moduleName);\t\t\t\t\t\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t} else {\n\t\t// Return all the module names without filtering\n\t\tsource(function(tiddler,title) {\n\t\t\t$tw.utils.each($tw.modules.types[title],function(moduleInfo,moduleName) {\n\t\t\t\tresults.push(moduleName);\n\t\t\t});\n\t\t});\n\t}\n\tresults.sort();\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/moduletypes.js":{"title":"$:/core/modules/filters/moduletypes.js","text":"/*\\\ntitle: $:/core/modules/filters/moduletypes.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the names of the module types in this wiki\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.moduletypes = function(source,operator,options) {\n\tvar results = [];\n\t$tw.utils.each($tw.modules.types,function(moduleInfo,type) {\n\t\tresults.push(type);\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/next.js":{"title":"$:/core/modules/filters/next.js","text":"/*\\\ntitle: $:/core/modules/filters/next.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning the tiddler whose title occurs next in the list supplied in the operand tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.next = function(source,operator,options) {\n\tvar results = [],\n\t\tlist = options.wiki.getTiddlerList(operator.operand);\n\tsource(function(tiddler,title) {\n\t\tvar match = list.indexOf(title);\n\t\t// increment match and then test if result is in range\n\t\tmatch++;\n\t\tif(match > 0 && match < list.length) {\n\t\t\tresults.push(list[match]);\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/plugintiddlers.js":{"title":"$:/core/modules/filters/plugintiddlers.js","text":"/*\\\ntitle: $:/core/modules/filters/plugintiddlers.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the titles of the shadow tiddlers within a plugin\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.plugintiddlers = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar pluginInfo = options.wiki.getPluginInfo(title) || options.wiki.getTiddlerDataCached(title,{tiddlers:[]});\n\t\tif(pluginInfo && pluginInfo.tiddlers) {\n\t\t\t$tw.utils.each(pluginInfo.tiddlers,function(fields,title) {\n\t\t\t\tresults.push(title);\n\t\t\t});\n\t\t}\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/prefix.js":{"title":"$:/core/modules/filters/prefix.js","text":"/*\\\ntitle: $:/core/modules/filters/prefix.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for checking if a title starts with a prefix\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.prefix = function(source,operator,options) {\n\tvar results = [],\n\t\tsuffixes = (operator.suffixes || [])[0] || [];\n\tif(suffixes.indexOf(\"caseinsensitive\") !== -1) {\n\t\tvar operand = operator.operand.toLowerCase();\n\t\tif(operator.prefix === \"!\") {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(title.toLowerCase().substr(0,operand.length) !== operand) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(title.toLowerCase().substr(0,operand.length) === operand) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t} else {\n\t\tif(operator.prefix === \"!\") {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(title.substr(0,operator.operand.length) !== operator.operand) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(title.substr(0,operator.operand.length) === operator.operand) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/previous.js":{"title":"$:/core/modules/filters/previous.js","text":"/*\\\ntitle: $:/core/modules/filters/previous.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning the tiddler whose title occurs immediately prior in the list supplied in the operand tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.previous = function(source,operator,options) {\n\tvar results = [],\n\t\tlist = options.wiki.getTiddlerList(operator.operand);\n\tsource(function(tiddler,title) {\n\t\tvar match = list.indexOf(title);\n\t\t// increment match and then test if result is in range\n\t\tmatch--;\n\t\tif(match >= 0) {\n\t\t\tresults.push(list[match]);\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/range.js":{"title":"$:/core/modules/filters/range.js","text":"/*\\\ntitle: $:/core/modules/filters/range.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for generating a numeric range.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.range = function(source,operator,options) {\n\tvar results = [];\n\t// For backwards compatibility, if there is only one operand, try to split it using one of the delimiters\n\tvar parts = operator.operands || [];\n\tif(parts.length === 1) {\n\t\tparts = operator.operand.split(/[,:;]/g);\n\t}\n\t// Process the parts\n\tvar beg, end, inc, i, fixed = 0;\n\tfor (i=0; i<parts.length; i++) {\n\t\t// Validate real number\n\t\tif(!/^\\s*[+-]?((\\d+(\\.\\d*)?)|(\\.\\d+))\\s*$/.test(parts[i])) {\n\t\t\treturn [\"range: bad number \\\"\" + parts[i] + \"\\\"\"];\n\t\t}\n\t\t// Count digits; the most precise number determines decimal places in output.\n\t\tvar frac = /\\.\\d+/.exec(parts[i]);\n\t\tif(frac) {\n\t\t\tfixed = Math.max(fixed,frac[0].length-1);\n\t\t}\n\t\tparts[i] = parseFloat(parts[i]);\n\t}\n\tswitch(parts.length) {\n\t\tcase 1:\n\t\t\tend = parts[0];\n\t\t\tif (end >= 1) {\n\t\t\t\tbeg = 1;\n\t\t\t}\n\t\t\telse if (end <= -1) {\n\t\t\t\tbeg = -1;\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t\tinc = 1;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tbeg = parts[0];\n\t\t\tend = parts[1];\n\t\t\tinc = 1;\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tbeg = parts[0];\n\t\t\tend = parts[1];\n\t\t\tinc = Math.abs(parts[2]);\n\t\t\tbreak;\n\t}\n\tif(inc === 0) {\n\t\treturn [\"range: increment 0 causes infinite loop\"];\n\t}\n\t// May need to count backwards\n\tvar direction = ((end < beg) ? -1 : 1);\n\tinc *= direction;\n\t// Estimate number of resulting elements\n\tif((end - beg) / inc > 10000) {\n\t\treturn [\"range: too many steps (over 10K)\"];\n\t}\n\t// Avoid rounding error on last step\n\tend += direction * 0.5 * Math.pow(0.1,fixed);\n\tvar safety = 10010;\n\t// Enumerate the range\n\tif (end<beg) {\n\t\tfor(i=beg; i>end; i+=inc) {\n\t\t\tresults.push(i.toFixed(fixed));\n\t\t\tif(--safety<0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tfor(i=beg; i<end; i+=inc) {\n\t\t\tresults.push(i.toFixed(fixed));\n\t\t\tif(--safety<0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\tif(safety<0) {\n\t\treturn [\"range: unexpectedly large output\"];\n\t}\n\t// Reverse?\n\tif(operator.prefix === \"!\") {\n\t\tresults.reverse();\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/reduce.js":{"title":"$:/core/modules/filters/reduce.js","text":"/*\\\ntitle: $:/core/modules/filters/reduce.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator evaluates a subfilter for each item, making the running total available in the variable `accumulator`, and the current index available in the variable `index`\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.reduce = function(source,operator,options) {\n\t// Accumulate the list\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\t// Run the filter over each item\n\tvar filterFn = options.wiki.compileFilter(operator.operand),\n\t\taccumulator = operator.operands[1] || \"\";\n\tfor(var index=0; index<results.length; index++) {\n\t\tvar title = results[index],\n\t\t\tlist = filterFn.call(options.wiki,options.wiki.makeTiddlerIterator([title]),options.widget.makeFakeWidgetWithVariables({\n\t\t\t\t\"currentTiddler\": \"\" + title,\n\t\t\t\t\"..currentTiddler\": options.widget.getVariable(\"currentTiddler\"),\n\t\t\t\t\"accumulator\": \"\" + accumulator,\n\t\t\t\t\"index\": \"\" + index,\n\t\t\t\t\"revIndex\": \"\" + (results.length - 1 - index),\n\t\t\t\t\"length\": \"\" + results.length\n\t\t\t}));\n\t\tif(list.length > 0) {\n\t\t\taccumulator = \"\" +  list[0];\n\t\t}\n\t}\n\tif(results.length > 0) {\n\t\treturn [accumulator];\n\t} else {\n\t\treturn [];\n\t}\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/regexp.js":{"title":"$:/core/modules/filters/regexp.js","text":"/*\\\ntitle: $:/core/modules/filters/regexp.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for regexp matching\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.regexp = function(source,operator,options) {\n\tvar results = [],\n\t\tfieldname = operator.suffix || \"title\",\n\t\tregexpString, regexp, flags = \"\", match,\n\t\tgetFieldString = function(tiddler,title) {\n\t\t\tif(tiddler) {\n\t\t\t\treturn tiddler.getFieldString(fieldname);\n\t\t\t} else if(fieldname === \"title\") {\n\t\t\t\treturn title;\n\t\t\t} else {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t};\n\t// Process flags and construct regexp\n\tregexpString = operator.operand;\n\tmatch = /^\\(\\?([gim]+)\\)/.exec(regexpString);\n\tif(match) {\n\t\tflags = match[1];\n\t\tregexpString = regexpString.substr(match[0].length);\n\t} else {\n\t\tmatch = /\\(\\?([gim]+)\\)$/.exec(regexpString);\n\t\tif(match) {\n\t\t\tflags = match[1];\n\t\t\tregexpString = regexpString.substr(0,regexpString.length - match[0].length);\n\t\t}\n\t}\n\ttry {\n\t\tregexp = new RegExp(regexpString,flags);\n\t} catch(e) {\n\t\treturn [\"\" + e];\n\t}\n\t// Process the incoming tiddlers\n\tif(operator.prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tvar text = getFieldString(tiddler,title);\n\t\t\tif(text !== null) {\n\t\t\t\tif(!regexp.exec(text)) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tvar text = getFieldString(tiddler,title);\n\t\t\tif(text !== null) {\n\t\t\t\tif(!!regexp.exec(text)) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/removeprefix.js":{"title":"$:/core/modules/filters/removeprefix.js","text":"/*\\\ntitle: $:/core/modules/filters/removeprefix.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for removing a prefix from each title in the list. Titles that do not start with the prefix are removed.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.removeprefix = function(source,operator,options) {\n\tvar results = [],\n\t\tsuffixes = (operator.suffixes || [])[0] || [];\n\tif(suffixes.indexOf(\"caseinsensitive\") !== -1) {\n\t\tvar operand = operator.operand.toLowerCase();\n\t\tsource(function(tiddler,title) {\n\t\t\tif(title.toLowerCase().substr(0,operand.length) === operand) {\n\t\t\t\tresults.push(title.substr(operand.length));\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(title.substr(0,operator.operand.length) === operator.operand) {\n\t\t\t\tresults.push(title.substr(operator.operand.length));\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/removesuffix.js":{"title":"$:/core/modules/filters/removesuffix.js","text":"/*\\\ntitle: $:/core/modules/filters/removesuffix.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for removing a suffix from each title in the list. Titles that do not end with the suffix are removed.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.removesuffix = function(source,operator,options) {\n\tvar results = [],\n\t\tsuffixes = (operator.suffixes || [])[0] || [];\n\tif (!operator.operand) {\n\t\tsource(function(tiddler,title) {\n\t\t\tresults.push(title);\n\t\t});\n\t} else if(suffixes.indexOf(\"caseinsensitive\") !== -1) {\n\t\tvar operand = operator.operand.toLowerCase();\n\t\tsource(function(tiddler,title) {\n\t\t\tif(title && title.toLowerCase().substr(-operand.length) === operand) {\n\t\t\t\tresults.push(title.substr(0,title.length - operand.length));\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(title && title.substr(-operator.operand.length) === operator.operand) {\n\t\t\t\tresults.push(title.substr(0,title.length - operator.operand.length));\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/sameday.js":{"title":"$:/core/modules/filters/sameday.js","text":"/*\\\ntitle: $:/core/modules/filters/sameday.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator that selects tiddlers with a modified date field on the same day as the provided value.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.sameday = function(source,operator,options) {\n\tvar results = [],\n\t\tfieldName = operator.suffix || \"modified\",\n\t\ttargetDate = (new Date($tw.utils.parseDate(operator.operand))).setHours(0,0,0,0);\n\t// Function to convert a date/time to a date integer\n\tsource(function(tiddler,title) {\n\t\tif(tiddler) {\n\t\t\tif(tiddler.getFieldDay(fieldName) === targetDate) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/search.js":{"title":"$:/core/modules/filters/search.js","text":"/*\\\ntitle: $:/core/modules/filters/search.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for searching for the text in the operand tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.search = function(source,operator,options) {\n\tvar invert = operator.prefix === \"!\";\n\tif(operator.suffixes) {\n\t\tvar hasFlag = function(flag) {\n\t\t\t\treturn (operator.suffixes[1] || []).indexOf(flag) !== -1;\n\t\t\t},\n\t\t\texcludeFields = false,\n\t\t\tfieldList = operator.suffixes[0] || [],\n\t\t\tfirstField = fieldList[0] || \"\", \n\t\t\tfirstChar = firstField.charAt(0),\n\t\t\tfields;\n\t\tif(firstChar === \"-\") {\n\t\t\tfields = [firstField.slice(1)].concat(fieldList.slice(1));\n\t\t\texcludeFields = true;\n\t\t} else if(fieldList[0] === \"*\"){\n\t\t\tfields = [];\n\t\t\texcludeFields = true;\n\t\t} else {\n\t\t\tfields = fieldList.slice(0);\n\t\t}\n\t\treturn options.wiki.search(operator.operand,{\n\t\t\tsource: source,\n\t\t\tinvert: invert,\n\t\t\tfield: fields,\n\t\t\texcludeField: excludeFields,\n\t\t\tsome: hasFlag(\"some\"),\n\t\t\tcaseSensitive: hasFlag(\"casesensitive\"),\n\t\t\tliteral: hasFlag(\"literal\"),\n\t\t\twhitespace: hasFlag(\"whitespace\"),\n\t\t\tanchored: hasFlag(\"anchored\"),\n\t\t\tregexp: hasFlag(\"regexp\"),\n\t\t\twords: hasFlag(\"words\")\n\t\t});\n\t} else {\n\t\treturn options.wiki.search(operator.operand,{\n\t\t\tsource: source,\n\t\t\tinvert: invert\n\t\t});\n\t}\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/shadowsource.js":{"title":"$:/core/modules/filters/shadowsource.js","text":"/*\\\ntitle: $:/core/modules/filters/shadowsource.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the source plugins for shadow tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.shadowsource = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar source = options.wiki.getShadowSource(title);\n\t\tif(source) {\n\t\t\t$tw.utils.pushTop(results,source);\n\t\t}\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/slugify.js":{"title":"$:/core/modules/filters/slugify.js","text":"/*\\\ntitle: $:/core/modules/filters/slugify.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for slugifying a tiddler title\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.slugify = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(options.wiki.slugify(title));\n\t});\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/sort.js":{"title":"$:/core/modules/filters/sort.js","text":"/*\\\ntitle: $:/core/modules/filters/sort.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for sorting\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.sort = function(source,operator,options) {\n\tvar results = prepare_results(source);\n\toptions.wiki.sortTiddlers(results,operator.operand || \"title\",operator.prefix === \"!\",false,false);\n\treturn results;\n};\n\nexports.nsort = function(source,operator,options) {\n\tvar results = prepare_results(source);\n\toptions.wiki.sortTiddlers(results,operator.operand || \"title\",operator.prefix === \"!\",false,true);\n\treturn results;\n};\n\nexports.sortan = function(source, operator, options) {\n\tvar results = prepare_results(source);\n\toptions.wiki.sortTiddlers(results, operator.operand || \"title\", operator.prefix === \"!\",false,false,true);\n\treturn results;\n};\n\nexports.sortcs = function(source,operator,options) {\n\tvar results = prepare_results(source);\n\toptions.wiki.sortTiddlers(results,operator.operand || \"title\",operator.prefix === \"!\",true,false);\n\treturn results;\n};\n\nexports.nsortcs = function(source,operator,options) {\n\tvar results = prepare_results(source);\n\toptions.wiki.sortTiddlers(results,operator.operand || \"title\",operator.prefix === \"!\",true,true);\n\treturn results;\n};\n\nvar prepare_results = function (source) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/sortsub.js":{"title":"$:/core/modules/filters/sortsub.js","text":"/*\\\ntitle: $:/core/modules/filters/sortsub.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for sorting by a subfilter\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.sortsub = function(source,operator,options) {\n\t// Compile the subfilter\n\tvar filterFn = options.wiki.compileFilter(operator.operand);\n\t// Collect the input titles and the corresponding sort keys\n\tvar inputTitles = [],\n\t\tsortKeys = [];\n\tsource(function(tiddler,title) {\n\t\tinputTitles.push(title);\n\t\tvar r = filterFn.call(options.wiki,function(iterator) {\n\t\t\titerator(options.wiki.getTiddler(title),title);\n\t\t},options.widget.makeFakeWidgetWithVariables({\n\t\t\t\"currentTiddler\": \"\" + title,\n\t\t\t\"..currentTiddler\": options.widget.getVariable(\"currentTiddler\")\n\t\t}));\n\t\tsortKeys.push(r[0] || \"\");\n\t});\n\t// Rather than sorting the titles array, we'll sort the indexes so that we can consult both arrays\n\tvar indexes = new Array(inputTitles.length);\n\tfor(var t=0; t<inputTitles.length; t++) {\n\t\tindexes[t] = t;\n\t}\n\t// Sort the indexes\n\tvar compareFn = $tw.utils.makeCompareFunction(operator.suffix,{defaultType: \"string\",invert: operator.prefix === \"!\"});\n\tindexes = indexes.sort(function(a,b) {\n\t\treturn compareFn(sortKeys[a],sortKeys[b]);\n\t});\n\t// Make the results array in order\n\tvar results = [];\n\t$tw.utils.each(indexes,function(index) {\n\t\tresults.push(inputTitles[index]);\n\t});\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/splitbefore.js":{"title":"$:/core/modules/filters/splitbefore.js","text":"/*\\\ntitle: $:/core/modules/filters/splitbefore.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator that splits each result on the first occurance of the specified separator and returns the unique values.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.splitbefore = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar parts = title.split(operator.operand);\n\t\tif(parts.length === 1) {\n\t\t\t$tw.utils.pushTop(results,parts[0]);\n\t\t} else {\n\t\t\t$tw.utils.pushTop(results,parts[0] + operator.operand);\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/storyviews.js":{"title":"$:/core/modules/filters/storyviews.js","text":"/*\\\ntitle: $:/core/modules/filters/storyviews.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the names of the story views in this wiki\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.storyviews = function(source,operator,options) {\n\tvar results = [],\n\t\tstoryviews = {};\n\t$tw.modules.applyMethods(\"storyview\",storyviews);\n\t$tw.utils.each(storyviews,function(info,name) {\n\t\tresults.push(name);\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/strings.js":{"title":"$:/core/modules/filters/strings.js","text":"/*\\\ntitle: $:/core/modules/filters/strings.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operators for strings. Unary/binary operators work on each item in turn, and return a new item list.\n\nSum/product/maxall/minall operate on the entire list, returning a single item.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.length = makeStringBinaryOperator(\n\tfunction(a) {return [\"\" + (\"\" + a).length];}\n);\n\nexports.uppercase = makeStringBinaryOperator(\n\tfunction(a) {return [(\"\" + a).toUpperCase()];}\n);\n\nexports.lowercase = makeStringBinaryOperator(\n\tfunction(a) {return [(\"\" + a).toLowerCase()];}\n);\n\nexports.sentencecase = makeStringBinaryOperator(\n\tfunction(a) {return [$tw.utils.toSentenceCase(a)];}\n);\n\nexports.titlecase = makeStringBinaryOperator(\n\tfunction(a) {return [$tw.utils.toTitleCase(a)];}\n);\n\nexports.trim = function(source,operator,options) {\n\tvar result = [],\n\t\tsuffix = operator.suffix || \"\",\n\t\toperand = (operator.operand || \"\"),\n\t\tfnCalc;\n\tif(suffix === \"prefix\") {\n\t\tfnCalc = function(a,b) {return [$tw.utils.trimPrefix(a,b)];}\n\t} else if(suffix === \"suffix\") {\n\t\tfnCalc = function(a,b) {return [$tw.utils.trimSuffix(a,b)];}\n\t} else {\n\t\tif(operand === \"\") {\n\t\t\tfnCalc = function(a) {return [$tw.utils.trim(a)];}\n\t\t} else {\n\t\t\tfnCalc = function(a,b) {return [$tw.utils.trimSuffix($tw.utils.trimPrefix(a,b),b)];}\n\t\t}\n\t}\n\tsource(function(tiddler,title) {\n\t\tArray.prototype.push.apply(result,fnCalc(title,operand));\n\t});\n\treturn result;\n};\n\nexports.split = makeStringBinaryOperator(\n\tfunction(a,b) {return (\"\" + a).split(b);}\n);\n\nexports[\"enlist-input\"] = makeStringBinaryOperator(\n\tfunction(a,o,s) {return $tw.utils.parseStringArray(\"\" + a,(s === \"raw\"));}\n);\n\nexports.join = makeStringReducingOperator(\n\tfunction(accumulator,value,operand) {\n\t\tif(accumulator === null) {\n\t\t\treturn value;\n\t\t} else {\n\t\t\treturn accumulator + operand + value;\n\t\t}\n\t},null\n);\n\nvar dmp = require(\"$:/core/modules/utils/diff-match-patch/diff_match_patch.js\");\n\nexports.levenshtein = makeStringBinaryOperator(\n\tfunction(a,b) {\n\t\tvar dmpObject = new dmp.diff_match_patch(),\n\t\t\tdiffs = dmpObject.diff_main(a,b);\n\t\treturn [dmpObject.diff_levenshtein(diffs) + \"\"];\n\t}\n);\n\n// these two functions are adapted from https://github.com/google/diff-match-patch/wiki/Line-or-Word-Diffs\nfunction diffLineWordMode(text1,text2,mode) {\n\tvar dmpObject = new dmp.diff_match_patch();\n\tvar a = diffPartsToChars(text1,text2,mode);\n\tvar lineText1 = a.chars1;\n\tvar lineText2 = a.chars2;\n\tvar lineArray = a.lineArray;\n\tvar diffs = dmpObject.diff_main(lineText1,lineText2,false);\n\tdmpObject.diff_charsToLines_(diffs,lineArray);\n\treturn diffs;\n}\n\nfunction diffPartsToChars(text1,text2,mode) {\n\tvar lineArray = [];\n\tvar lineHash = {};\n\tlineArray[0] = '';\n\n    function diff_linesToPartsMunge_(text,mode) {\n        var chars = '';\n        var lineStart = 0;\n        var lineEnd = -1;\n        var lineArrayLength = lineArray.length,\n            regexpResult;\n        var searchRegexp = /\\W+/g;\n        while(lineEnd < text.length - 1) {\n\t        if(mode === \"words\") {\n                regexpResult = searchRegexp.exec(text);\n                lineEnd = searchRegexp.lastIndex;\n                if(regexpResult === null) {\n                lineEnd = text.length;\n                }\n                lineEnd = --lineEnd;\n            } else {\n                lineEnd = text.indexOf('\\n', lineStart);\n                if(lineEnd == -1) {\n                    lineEnd = text.length - 1;\n                }\n            }\n            var line = text.substring(lineStart, lineEnd + 1);\n\n            if(lineHash.hasOwnProperty ? lineHash.hasOwnProperty(line) : (lineHash[line] !== undefined)) {\n\t\t\t\tchars += String.fromCharCode(lineHash[line]);\n            } else {\n                if(lineArrayLength == maxLines) {\n                  line = text.substring(lineStart);\n                  lineEnd = text.length;\n                }\n                chars += String.fromCharCode(lineArrayLength);\n                lineHash[line] = lineArrayLength;\n                lineArray[lineArrayLength++] = line;\n            }\n            lineStart = lineEnd + 1;\n        }\n        return chars;\n    }\n    var maxLines = 40000;\n    var chars1 = diff_linesToPartsMunge_(text1,mode);\n    maxLines = 65535;\n    var chars2 = diff_linesToPartsMunge_(text2,mode);\n    return {chars1: chars1, chars2: chars2, lineArray: lineArray};\n};\n\nexports.makepatches = function(source,operator,options) {\n\tvar dmpObject = new dmp.diff_match_patch(),\n\t\tsuffix = operator.suffix || \"\",\n\t\tresult = [];\n\t\t\n\t\tsource(function(tiddler,title) {\n\t\t\tvar diffs, patches;\n\t\t\tif(suffix === \"lines\" || suffix === \"words\") {\n\t\t\t\tdiffs = diffLineWordMode(title,operator.operand,suffix);\n\t\t\t\tpatches = dmpObject.patch_make(title,diffs);\n\t\t\t} else {\n\t\t\t\tpatches = dmpObject.patch_make(title,operator.operand);\n\t\t\t}\n\t\t\tArray.prototype.push.apply(result,[dmpObject.patch_toText(patches)]);\n\t\t});\n\n\treturn result;\n};\n\nexports.applypatches = makeStringBinaryOperator(\n\tfunction(a,b) {\n\t\tvar dmpObject = new dmp.diff_match_patch(),\n\t\t\tpatches;\n\t\ttry {\n\t\t\tpatches = dmpObject.patch_fromText(b);\n\t\t} catch(e) {\n\t\t}\n\t\tif(patches) {\n\t\t\treturn [dmpObject.patch_apply(patches,a)[0]];\n\t\t} else {\n\t\t\treturn [a];\n\t\t}\n\t}\n);\n\nfunction makeStringBinaryOperator(fnCalc) {\n\treturn function(source,operator,options) {\n\t\tvar result = [];\n\t\tsource(function(tiddler,title) {\n\t\t\tArray.prototype.push.apply(result,fnCalc(title,operator.operand || \"\",operator.suffix || \"\"));\n\t\t});\n\t\treturn result;\n\t};\n}\n\nfunction makeStringReducingOperator(fnCalc,initialValue) {\n\treturn function(source,operator,options) {\n\t\tvar result = [];\n\t\tsource(function(tiddler,title) {\n\t\t\tresult.push(title);\n\t\t});\n\t\tif(result.length === 0) {\n\t\t\treturn [];\n\t\t}\n\t\treturn [result.reduce(function(accumulator,currentValue) {\n\t\t\treturn fnCalc(accumulator,currentValue,operator.operand || \"\");\n\t\t},initialValue) || \"\"];\n\t};\n}\n\nexports.splitregexp = function(source,operator,options) {\n\tvar result = [],\n\t\tsuffix = operator.suffix || \"\",\n\t\tflags = (suffix.indexOf(\"m\") !== -1 ? \"m\" : \"\") + (suffix.indexOf(\"i\") !== -1 ? \"i\" : \"\"),\n\t\tregExp;\n\ttry {\n\t\tregExp = new RegExp(operator.operand || \"\",flags);\n\t} catch(ex) {\n\t\treturn [\"RegExp error: \" + ex];\n\t}\n\tsource(function(tiddler,title) {\n\t\tvar parts = title.split(regExp).map(function(part){\n\t\t\treturn part || \"\";\t// make sure it's a string\n\t\t});\n\t\tArray.prototype.push.apply(result,parts);\n\t});\n\treturn result;\n};\n\nexports[\"search-replace\"] = function(source,operator,options) {\n\tvar results = [],\n\t\tsuffixes = operator.suffixes || [],\n\t\tflagSuffix = (suffixes[0] ? (suffixes[0][0] || \"\") : \"\"),\n\t\tflags = (flagSuffix.indexOf(\"g\") !== -1 ? \"g\" : \"\") + (flagSuffix.indexOf(\"i\") !== -1 ? \"i\" : \"\") + (flagSuffix.indexOf(\"m\") !== -1 ? \"m\" : \"\"),\n\t\tisRegExp = (suffixes[1] && suffixes[1][0] === \"regexp\") ? true : false,\n\t\t//Escape regexp characters if the operand is not a regular expression\n\t\tsearchTerm = isRegExp ? operator.operand : $tw.utils.escapeRegExp(operator.operand),\n\t\t//Escape $ character in replacement string if not in regular expression mode\n\t\treplacement = isRegExp ? operator.operands[1] : (operator.operands[1]||\"\").replace(/\\$/g,\"$$$$\"),\n\t\tregExp;\n\ttry {\n\t\tregExp = new RegExp(searchTerm,flags);\n\t} catch(ex) {\n\t\treturn [\"RegExp error: \" + ex];\n\t}\n\n\tsource(function(tiddler,title) {\n\t\tif(title && (operator.operands.length > 1)) {\n\t\t\tresults.push(\n\t\t\t\ttitle.replace(regExp,replacement)\n\t\t\t);\n\t\t\tregExp.lastIndex = 0;\n\t\t} else {\n\t\t\tresults.push(title);\n\t\t}\n\t});\n\treturn results;\n};\n\nexports.pad = function(source,operator,options) {\n\tvar results = [],\n\t\ttargetLength = operator.operand ? parseInt(operator.operand) : 0,\n\t\tfill = operator.operands[1] || \"0\";\n\n\tsource(function(tiddler,title) {\n\t\tif(title && title.length) {\n\t\t\tif(title.length >= targetLength) {\n\t\t\t\tresults.push(title);\n\t\t\t} else {\n\t\t\t\tvar padString = \"\",\n\t\t\t\t\tpadStringLength = targetLength - title.length;\n\t\t\t\twhile(padStringLength > padString.length) {\n\t\t\t\t\tpadString += fill;\n\t\t\t\t}\n\t\t\t\t//make sure we do not exceed the specified length\n\t\t\t\tpadString = padString.slice(0,padStringLength);\n\t\t\t\tif(operator.suffix && (operator.suffix === \"suffix\")) {\n\t\t\t\t\ttitle = title + padString;\n\t\t\t\t} else {\n\t\t\t\t\ttitle = padString + title;\n\t\t\t\t}\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t}\n\t});\n\treturn results;\n}\n\nexports.charcode = function(source,operator,options) {\n\tvar chars = [];\n\t$tw.utils.each(operator.operands,function(operand) {\n\t\tif(operand !== \"\") {\n\t\t\tchars.push(String.fromCharCode($tw.utils.parseInt(operand)));\n\t\t}\n\t});\n\treturn [chars.join(\"\")];\n};\n\n})();","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/subfilter.js":{"title":"$:/core/modules/filters/subfilter.js","text":"/*\\\ntitle: $:/core/modules/filters/subfilter.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning its operand evaluated as a filter\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.subfilter = function(source,operator,options) {\n\tvar list = options.wiki.filterTiddlers(operator.operand,options.widget,source);\n\tif(operator.prefix === \"!\") {\n\t\tvar results = [];\n\t\tsource(function(tiddler,title) {\n\t\t\tif(list.indexOf(title) === -1) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t\treturn results;\n\t} else {\n\t\treturn list;\n\t}\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/substitute.js":{"title":"$:/core/modules/filters/substitute.js","text":"/*\\\ntitle: $:/core/modules/filters/substitute.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for substituting variables and embedded filter expressions with their corresponding values\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.substitute = function(source,operator,options) {\n\tvar results = [],\n\t\toperands = [];\n\t$tw.utils.each(operator.operands,function(operand,index){\n\t\toperands.push({\n\t\t\tname: (index + 1).toString(),\n\t\t\tvalue: operand\n\t\t});\n\t});\n\tsource(function(tiddler,title) {\n\t\tif(title) {\n\t\t\tresults.push(options.wiki.getSubstitutedText(title,options.widget,{substitutions:operands}));\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n ","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/subtiddlerfields.js":{"title":"$:/core/modules/filters/subtiddlerfields.js","text":"/*\\\ntitle: $:/core/modules/filters/subtiddlerfields.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the names of the fields on the selected subtiddlers of the plugin named in the operand\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.subtiddlerfields = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar subtiddler = options.wiki.getSubTiddler(operator.operand,title);\n\t\tif(subtiddler) {\n\t\t\tfor(var fieldName in subtiddler.fields) {\n\t\t\t\t$tw.utils.pushTop(results,fieldName);\n\t\t\t}\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/suffix.js":{"title":"$:/core/modules/filters/suffix.js","text":"/*\\\ntitle: $:/core/modules/filters/suffix.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for checking if a title ends with a suffix\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.suffix = function(source,operator,options) {\n\tvar results = [],\n\t\tsuffixes = (operator.suffixes || [])[0] || [];\n\tif (!operator.operand) {\n\t\tsource(function(tiddler,title) {\n\t\t\tresults.push(title);\n\t\t});\n\t} else if(suffixes.indexOf(\"caseinsensitive\") !== -1) {\n\t\tvar operand = operator.operand.toLowerCase();\n\t\tif(operator.prefix === \"!\") {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(title.toLowerCase().substr(-operand.length) !== operand) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(title.toLowerCase().substr(-operand.length) === operand) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t} else {\n\t\tif(operator.prefix === \"!\") {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(title.substr(-operator.operand.length) !== operator.operand) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(title.substr(-operator.operand.length) === operator.operand) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/tag.js":{"title":"$:/core/modules/filters/tag.js","text":"/*\\\ntitle: $:/core/modules/filters/tag.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for checking for the presence of a tag\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.tag = function(source,operator,options) {\n\tvar results = [],indexedResults;\n\tif((operator.suffix || \"\").toLowerCase() === \"strict\" && !operator.operand) {\n\t\t// New semantics:\n\t\t// Always return copy of input if operator.operand is missing\n\t\tsource(function(tiddler,title) {\n\t\t\tresults.push(title);\n\t\t});\n\t} else {\n\t\t// Old semantics:\n\t\tvar tiddlers;\n\t\tif(operator.prefix === \"!\") {\n\t\t\t// Returns a copy of the input if operator.operand is missing\n\t\t\ttiddlers = options.wiki.getTiddlersWithTag(operator.operand);\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddlers.indexOf(title) === -1) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\t// Returns empty results if operator.operand is missing\n\t\t\tif(source.byTag) {\n\t\t\t\tindexedResults = source.byTag(operator.operand);\n\t\t\t\tif(indexedResults) {\n\t\t\t\t\treturn indexedResults;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ttiddlers = options.wiki.getTiddlersWithTag(operator.operand);\n\t\t\t\tsource(function(tiddler,title) {\n\t\t\t\t\tif(tiddlers.indexOf(title) !== -1) {\n\t\t\t\t\t\tresults.push(title);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tresults = options.wiki.sortByList(results,operator.operand);\n\t\t\t}\n\t\t}\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/tagging.js":{"title":"$:/core/modules/filters/tagging.js","text":"/*\\\ntitle: $:/core/modules/filters/tagging.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning all tiddlers that are tagged with the selected tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.tagging = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\t$tw.utils.pushTop(results,options.wiki.getTiddlersWithTag(title));\n\t});\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/tags.js":{"title":"$:/core/modules/filters/tags.js","text":"/*\\\ntitle: $:/core/modules/filters/tags.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning all the tags of the selected tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.tags = function(source,operator,options) {\n\tvar tags = {};\n\tsource(function(tiddler,title) {\n\t\tvar t, length;\n\t\tif(tiddler && tiddler.fields.tags) {\n\t\t\tfor(t=0, length=tiddler.fields.tags.length; t<length; t++) {\n\t\t\t\ttags[tiddler.fields.tags[t]] = true;\n\t\t\t}\n\t\t}\n\t});\n\treturn Object.keys(tags);\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/then.js":{"title":"$:/core/modules/filters/then.js","text":"/*\\\ntitle: $:/core/modules/filters/then.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for replacing any titles with a constant\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.then = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(operator.operand);\n\t});\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/title.js":{"title":"$:/core/modules/filters/title.js","text":"/*\\\ntitle: $:/core/modules/filters/title.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for comparing title fields for equality\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.title = function(source,operator,options) {\n\tvar results = [];\n\tif(operator.prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(tiddler && tiddler.fields.title !== operator.operand) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tresults.push(operator.operand);\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/transcludes.js":{"title":"$:/core/modules/filters/transcludes.js","text":"/*\\\ntitle: $:/core/modules/filters/transcludes.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning all the transcludes from a tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.transcludes = function(source,operator,options) {\n\tvar results = new $tw.utils.LinkedList();\n\tsource(function(tiddler,title) {\n\t\tresults.pushTop(options.wiki.getTiddlerTranscludes(title));\n\t});\n\treturn results.makeTiddlerIterator(options.wiki);\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/unknown.js":{"title":"$:/core/modules/filters/unknown.js","text":"/*\\\ntitle: $:/core/modules/filters/unknown.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for handling unknown filter operators.\n\nNot intended to be used directly by end users, hence the square brackets around the name.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar fieldFilterOperatorFn = require(\"$:/core/modules/filters/field.js\").field;\n\n/*\nExport our filter function\n*/\nexports[\"[unknown]\"] = function(source,operator,options) {\n\t// Check for a user defined filter operator\n\tif(operator.operator.indexOf(\".\") !== -1) {\n\t\tvar params = [];\n\t\t$tw.utils.each(operator.operands,function(param) {\n\t\t\tparams.push({value: param});\n\t\t});\t\n\t\tvar variableInfo = options.widget && options.widget.getVariableInfo && options.widget.getVariableInfo(operator.operator,{params: params, source: source});\n\t\tif(variableInfo && variableInfo.srcVariable) {\n\t\t\tvar list = variableInfo.resultList ? variableInfo.resultList : [variableInfo.text];\n\t\t\tif(operator.prefix === \"!\") {\n\t\t\t\tvar results = [];\n\t\t\t\tsource(function(tiddler,title) {\n\t\t\t\t\tif(list.indexOf(title) === -1) {\n\t\t\t\t\t\tresults.push(title);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn results;\n\t\t\t} else {\n\t\t\t\treturn list;\n\t\t\t}\n\t\t}\n\t}\n\t// Otherwise, use the \"field\" operator\n\treturn fieldFilterOperatorFn(source,operator,options);\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/untagged.js":{"title":"$:/core/modules/filters/untagged.js","text":"/*\\\ntitle: $:/core/modules/filters/untagged.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning all the selected tiddlers that are untagged\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.untagged = function(source,operator,options) {\n\tvar results = [],\n\t\texpected = (operator.prefix === \"!\");\n\tsource(function(tiddler,title) {\n\t\tif(((tiddler && $tw.utils.isArray(tiddler.fields.tags) && tiddler.fields.tags.length > 0) === expected) || (!tiddler && !expected)) {\n\t\t\tresults.push(title);\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/variables.js":{"title":"$:/core/modules/filters/variables.js","text":"/*\\\ntitle: $:/core/modules/filters/variables.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the names of the active variables\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.variables = function(source,operator,options) {\n\tvar names = [],\n\t\twidget = options.widget;\n\twhile(widget && !widget.hasOwnProperty(\"variables\")) {\n\t\twidget = widget.parentWidget;\n\t}\n\tif(widget && widget.variables) {\n\t\tfor(var variable in widget.variables) {\n\t\t\tnames.push(variable);\n\t\t}\n\t}\n\treturn names.sort();\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/wikiparserrules.js":{"title":"$:/core/modules/filters/wikiparserrules.js","text":"/*\\\ntitle: $:/core/modules/filters/wikiparserrules.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the names of the wiki parser rules in this wiki\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.wikiparserrules = function(source,operator,options) {\n\tvar results = [],\n\t\toperand = operator.operand;\n\t$tw.utils.each($tw.modules.types.wikirule,function(mod) {\n\t\tvar exp = mod.exports;\n\t\tif(!operand || exp.types[operand]) {\n\t\t\tresults.push(exp.name);\n\t\t}\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters/x-listops.js":{"title":"$:/core/modules/filters/x-listops.js","text":"/*\\\ntitle: $:/core/modules/filters/x-listops.js\ntype: application/javascript\nmodule-type: filteroperator\n\nExtended filter operators to manipulate the current list.\n\n\\*/\n(function () {\n\n\t/*jslint node: true, browser: true */\n\t/*global $tw: false */\n\t\"use strict\";\n\n\t/*\n\tFetch titles from the current list\n\t*/\n\tvar prepare_results = function (source) {\n\tvar results = [];\n\t\tsource(function (tiddler, title) {\n\t\t\tresults.push(title);\n\t\t});\n\t\treturn results;\n\t};\n\n\t/*\n\tMoves a number of items from the tail of the current list before the item named in the operand\n\t*/\n\texports.putbefore = function (source, operator) {\n\t\tvar results = prepare_results(source),\n\t\t\tindex = results.indexOf(operator.operand),\n\t\t\tcount = $tw.utils.getInt(operator.suffix,1);\n\t\treturn (index === -1) ?\n\t\t\tresults.slice(0, -1) :\n\t\t\tresults.slice(0, index).concat(results.slice(-count)).concat(results.slice(index, -count));\n\t};\n\n\t/*\n\tMoves a number of items from the tail of the current list after the item named in the operand\n\t*/\n\texports.putafter = function (source, operator) {\n\t\tvar results = prepare_results(source),\n\t\t\tindex = results.indexOf(operator.operand),\n\t\t\tcount = $tw.utils.getInt(operator.suffix,1);\n\t\treturn (index === -1) ?\n\t\t\tresults.slice(0, -1) :\n\t\t\tresults.slice(0, index + 1).concat(results.slice(-count)).concat(results.slice(index + 1, -count));\n\t};\n\n\t/*\n\tReplaces the item named in the operand with a number of items from the tail of the current list\n\t*/\n\texports.replace = function (source, operator) {\n\t\tvar results = prepare_results(source),\n\t\t\tindex = results.indexOf(operator.operand),\n\t\t\tcount = $tw.utils.getInt(operator.suffix,1);\n\t\treturn (index === -1) ?\n\t\t\tresults.slice(0, -count) :\n\t\t\tresults.slice(0, index).concat(results.slice(-count)).concat(results.slice(index + 1, -count));\n\t};\n\n\t/*\n\tMoves a number of items from the tail of the current list to the head of the list\n\t*/\n\texports.putfirst = function (source, operator) {\n\t\tvar results = prepare_results(source),\n\t\t\tcount = $tw.utils.getInt(operator.suffix,1);\n\t\treturn results.slice(-count).concat(results.slice(0, -count));\n\t};\n\n\t/*\n\tMoves a number of items from the head of the current list to the tail of the list\n\t*/\n\texports.putlast = function (source, operator) {\n\t\tvar results = prepare_results(source),\n\t\t\tcount = $tw.utils.getInt(operator.suffix,1);\n\t\treturn results.slice(count).concat(results.slice(0, count));\n\t};\n\n\t/*\n\tMoves the item named in the operand a number of places forward or backward in the list\n\t*/\n\texports.move = function (source, operator) {\n\t\tvar results = prepare_results(source),\n\t\t\tindex = results.indexOf(operator.operand),\n\t\t\tcount = $tw.utils.getInt(operator.suffix,1),\n\t\t\tmarker = results.splice(index, 1),\n\t\t\toffset =  (index + count) > 0 ? index + count : 0;\n\t\treturn results.slice(0, offset).concat(marker).concat(results.slice(offset));\n\t};\n\n\t/*\n\tReturns the items from the current list that are after the item named in the operand\n\t*/\n\texports.allafter = function (source, operator) {\n\t\tvar results = prepare_results(source),\n\t\t\tindex = results.indexOf(operator.operand);\n\t\treturn (index === -1) ? [] :\n\t\t\t(operator.suffix) ? results.slice(index) :\n\t\t\tresults.slice(index + 1);\n\t};\n\n\t/*\n\tReturns the items from the current list that are before the item named in the operand\n\t*/\n\texports.allbefore = function (source, operator) {\n\t\tvar results = prepare_results(source),\n\t\t\tindex = results.indexOf(operator.operand);\n\t\treturn (index === -1) ? [] :\n\t\t\t(operator.suffix) ? results.slice(0, index + 1) :\n\t\t\tresults.slice(0, index);\n\t};\n\n\t/*\n\tAppends the items listed in the operand array to the tail of the current list\n\t*/\n\texports.append = function (source, operator) {\n\t\tvar append = $tw.utils.parseStringArray(operator.operand, \"true\"),\n\t\t\tresults = prepare_results(source),\n\t\t\tcount = parseInt(operator.suffix) || append.length;\n\t\treturn (append.length === 0) ? results :\n\t\t\t(operator.prefix) ? results.concat(append.slice(-count)) :\n\t\t\tresults.concat(append.slice(0, count));\n\t};\n\n\t/*\n\tPrepends the items listed in the operand array to the head of the current list\n\t*/\n\texports.prepend = function (source, operator) {\n\t\tvar prepend = $tw.utils.parseStringArray(operator.operand, \"true\"),\n\t\t\tresults = prepare_results(source),\n\t\t\tcount = $tw.utils.getInt(operator.suffix,prepend.length);\n\t\treturn (prepend.length === 0) ? results :\n\t\t\t(operator.prefix) ? prepend.slice(-count).concat(results) :\n\t\t\tprepend.slice(0, count).concat(results);\n\t};\n\n\t/*\n\tReturns all items from the current list except the items listed in the operand array\n\t*/\n\texports.remove = function (source, operator) {\n\t\tvar array = $tw.utils.parseStringArray(operator.operand, \"true\"),\n\t\t\tresults = prepare_results(source),\n\t\t\tcount = parseInt(operator.suffix) || array.length,\n\t\t\tp,\n\t\t\tlen,\n\t\t\tindex;\n\t\tlen = array.length - 1;\n\t\tfor (p = 0; p < count; ++p) {\n\t\t\tif (operator.prefix) {\n\t\t\t\tindex = results.indexOf(array[len - p]);\n\t\t\t} else {\n\t\t\t\tindex = results.indexOf(array[p]);\n\t\t\t}\n\t\t\tif (index !== -1) {\n\t\t\t\tresults.splice(index, 1);\n\t\t\t}\n\t\t}\n\t\treturn results;\n\t};\n\n\t/*\n\tReturns all items from the current list sorted in the order of the items in the operand array\n\t*/\n\texports.sortby = function (source, operator) {\n\t\tvar results = prepare_results(source);\n\t\tif (!results || results.length < 2) {\n\t\t\treturn results;\n\t\t}\n\t\tvar lookup = $tw.utils.parseStringArray(operator.operand, \"true\");\n\t\tresults.sort(function (a, b) {\n\t\t\treturn lookup.indexOf(a) - lookup.indexOf(b);\n\t\t});\n\t\treturn results;\n\t};\n\n\t/*\n\tRemoves all duplicate items from the current list\n\t*/\n\texports.unique = function (source, operator) {\n\t\tvar results = prepare_results(source);\n\t\tvar set = results.reduce(function (a, b) {\n\t\t\tif (a.indexOf(b) < 0) {\n\t\t\t\ta.push(b);\n\t\t\t}\n\t\t\treturn a;\n\t\t}, []);\n\t\treturn set;\n\t};\n\n\tvar cycleValueInArray = function(results,operands,stepSize) {\n\t\tvar resultsIndex,\n\t\t\tstep = stepSize || 1,\n\t\t\ti = 0,\n\t\t\topLength = operands.length,\n\t\t\tnextOperandIndex;\n\t\tfor(i; i < opLength; i++) {\n\t\t\tresultsIndex = results.indexOf(operands[i]);\n\t\t\tif(resultsIndex !== -1) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif(resultsIndex !== -1) {\n\t\t\ti = i + step;\n\t\t\tnextOperandIndex = (i < opLength ? i : i % opLength);\n\t\t\tif(operands.length > 1) {\n\t\t\t\tresults.splice(resultsIndex,1,operands[nextOperandIndex]);\n\t\t\t} else {\n\t\t\t\tresults.splice(resultsIndex,1);\n\t\t\t}\n\t\t} else {\n\t\t\tresults.push(operands[0]);\n\t\t}\n\t\treturn results;\n\t}\n\n\t/*\n\tToggles an item in the current list.\n\t*/\n\texports.toggle = function(source,operator) {\n\t\treturn cycleValueInArray(prepare_results(source),operator.operands);\n\t}\n\n\texports.cycle = function(source,operator) {\n\t\tvar results = prepare_results(source),\n\t\t\toperands = (operator.operand.length ? $tw.utils.parseStringArray(operator.operand, \"true\") : [\"\"]),\n\t\t\tstep = $tw.utils.getInt(operator.operands[1]||\"\",1);\n\t\tif(step < 0) {\n\t\t\toperands.reverse();\n\t\t\tstep = Math.abs(step);\n\t\t}\n\t\treturn cycleValueInArray(results,operands,step);\n\t}\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/core/modules/filters.js":{"title":"$:/core/modules/filters.js","text":"/*\\\ntitle: $:/core/modules/filters.js\ntype: application/javascript\nmodule-type: wikimethod\n\nAdds tiddler filtering methods to the $tw.Wiki object.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widgetClass = require(\"$:/core/modules/widgets/widget.js\").widget;\n\n/* Maximum permitted filter recursion depth */\nvar MAX_FILTER_DEPTH = 300;\n\n/*\nParses an operation (i.e. a run) within a filter string\n\toperators: Array of array of operator nodes into which results should be inserted\n\tfilterString: filter string\n\tp: start position within the string\nReturns the new start position, after the parsed operation\n*/\nfunction parseFilterOperation(operators,filterString,p) {\n\tvar nextBracketPos, operator;\n\t// Skip the starting square bracket\n\tif(filterString.charAt(p++) !== \"[\") {\n\t\tthrow \"Missing [ in filter expression\";\n\t}\n\t// Process each operator in turn\n\tdo {\n\t\toperator = {};\n\t\t// Check for an operator prefix\n\t\tif(filterString.charAt(p) === \"!\") {\n\t\t\toperator.prefix = filterString.charAt(p++);\n\t\t}\n\t\t// Get the operator name\n\t\tnextBracketPos = filterString.substring(p).search(/[\\[\\{<\\/]/);\n\t\tif(nextBracketPos === -1) {\n\t\t\tthrow \"Missing [ in filter expression\";\n\t\t}\n\t\tnextBracketPos += p;\n\t\tvar bracket = filterString.charAt(nextBracketPos);\n\t\toperator.operator = filterString.substring(p,nextBracketPos);\n\t\t// Any suffix?\n\t\tvar colon = operator.operator.indexOf(':');\n\t\tif(colon > -1) {\n\t\t\t// The raw suffix for older filters\n\t\t\toperator.suffix = operator.operator.substring(colon + 1);\n\t\t\toperator.operator = operator.operator.substring(0,colon) || \"field\";\n\t\t\t// The processed suffix for newer filters\n\t\t\toperator.suffixes = [];\n\t\t\t$tw.utils.each(operator.suffix.split(\":\"),function(subsuffix) {\n\t\t\t\toperator.suffixes.push([]);\n\t\t\t\t$tw.utils.each(subsuffix.split(\",\"),function(entry) {\n\t\t\t\t\tentry = $tw.utils.trim(entry);\n\t\t\t\t\tif(entry) {\n\t\t\t\t\t\toperator.suffixes[operator.suffixes.length - 1].push(entry); \n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\t\t// Empty operator means: title\n\t\telse if(operator.operator === \"\") {\n\t\t\toperator.operator = \"title\";\n\t\t}\n\t\toperator.operands = [];\n\t\tvar parseOperand = function(bracketType) {\n\t\t\tvar operand = {};\n\t\t\tswitch (bracketType) {\n\t\t\t\tcase \"{\": // Curly brackets\n\t\t\t\t\toperand.indirect = true;\n\t\t\t\t\tnextBracketPos = filterString.indexOf(\"}\",p);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"[\": // Square brackets\n\t\t\t\t\tnextBracketPos = filterString.indexOf(\"]\",p);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"<\": // Angle brackets\n\t\t\t\t\toperand.variable = true;\n\t\t\t\t\tnextBracketPos = filterString.indexOf(\">\",p);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"/\": // regexp brackets\n\t\t\t\t\tvar rex = /^((?:[^\\\\\\/]|\\\\.)*)\\/(?:\\(([mygi]+)\\))?/g,\n\t\t\t\t\t\trexMatch = rex.exec(filterString.substring(p));\n\t\t\t\t\tif(rexMatch) {\n\t\t\t\t\t\toperator.regexp = new RegExp(rexMatch[1], rexMatch[2]);\n\t// DEPRECATION WARNING\n\tconsole.log(\"WARNING: Filter\",operator.operator,\"has a deprecated regexp operand\",operator.regexp);\n\t\t\t\t\t\tnextBracketPos = p + rex.lastIndex - 1;\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthrow \"Unterminated regular expression in filter expression\";\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif(nextBracketPos === -1) {\n\t\t\t\tthrow \"Missing closing bracket in filter expression\";\n\t\t\t}\n\t\t\tif(operator.regexp) {\n\t\t\t\toperand.text = \"\";\n\t\t\t} else {\n\t\t\t\toperand.text = filterString.substring(p,nextBracketPos);\n\t\t\t}\n\t\t\toperator.operands.push(operand);\n\t\t\tp = nextBracketPos + 1;\n\t\t}\n\n\t\tp = nextBracketPos + 1;\n\t\tparseOperand(bracket);\n\n\t\t// Check for multiple operands\n\t\twhile(filterString.charAt(p) === \",\") {\n\t\t\tp++;\n\t\t\tif(/^[\\[\\{<\\/]/.test(filterString.substring(p))) {\n\t\t\t\tnextBracketPos = p;\n\t\t\t\tp++;\n\t\t\t\tparseOperand(filterString.charAt(nextBracketPos));\n\t\t\t} else {\n\t\t\t\tthrow \"Missing [ in filter expression\";\n\t\t\t}\n\t\t}\n\n\t\t// Push this operator\n\t\toperators.push(operator);\n\t} while(filterString.charAt(p) !== \"]\");\n\t// Skip the ending square bracket\n\tif(filterString.charAt(p++) !== \"]\") {\n\t\tthrow \"Missing ] in filter expression\";\n\t}\n\t// Return the parsing position\n\treturn p;\n}\n\n/*\nParse a filter string\n*/\nexports.parseFilter = function(filterString) {\n\tfilterString = filterString || \"\";\n\tvar results = [], // Array of arrays of operator nodes {operator:,operand:}\n\t\tp = 0, // Current position in the filter string\n\t\tmatch;\n\tvar whitespaceRegExp = /(\\s+)/mg,\n\t\toperandRegExp = /((?:\\+|\\-|~|=|\\:(\\w+)(?:\\:([\\w\\:, ]*))?)?)(?:(\\[)|(?:\"([^\"]*)\")|(?:'([^']*)')|([^\\s\\[\\]]+))/mg;\n\twhile(p < filterString.length) {\n\t\t// Skip any whitespace\n\t\twhitespaceRegExp.lastIndex = p;\n\t\tmatch = whitespaceRegExp.exec(filterString);\n\t\tif(match && match.index === p) {\n\t\t\tp = p + match[0].length;\n\t\t}\n\t\t// Match the start of the operation\n\t\tif(p < filterString.length) {\n\t\t\toperandRegExp.lastIndex = p;\n\t\t\tmatch = operandRegExp.exec(filterString);\n\t\t\tif(!match || match.index !== p) {\n\t\t\t\tthrow $tw.language.getString(\"Error/FilterSyntax\");\n\t\t\t}\n\t\t\tvar operation = {\n\t\t\t\tprefix: \"\",\n\t\t\t\toperators: []\n\t\t\t};\n\t\t\tif(match[1]) {\n\t\t\t\toperation.prefix = match[1];\n\t\t\t\tp = p + operation.prefix.length;\n\t\t\t\tif(match[2]) {\n\t\t\t\t\toperation.namedPrefix = match[2];\n\t\t\t\t}\n\t\t\t\tif(match[3]) {\n\t\t\t\t\toperation.suffixes = [];\n\t\t\t\t\t $tw.utils.each(match[3].split(\":\"),function(subsuffix) {\n\t\t\t\t\t\toperation.suffixes.push([]);\n\t\t\t\t\t\t$tw.utils.each(subsuffix.split(\",\"),function(entry) {\n\t\t\t\t\t\t\tentry = $tw.utils.trim(entry);\n\t\t\t\t\t\t\tif(entry) {\n\t\t\t\t\t\t\t\toperation.suffixes[operation.suffixes.length -1].push(entry);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t });\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(match[4]) { // Opening square bracket\n\t\t\t\tp = parseFilterOperation(operation.operators,filterString,p);\n\t\t\t} else {\n\t\t\t\tp = match.index + match[0].length;\n\t\t\t}\n\t\t\tif(match[5] || match[6] || match[7]) { // Double quoted string, single quoted string or unquoted title\n\t\t\t\toperation.operators.push(\n\t\t\t\t\t{operator: \"title\", operands: [{text: match[5] || match[6] || match[7]}]}\n\t\t\t\t);\n\t\t\t}\n\t\t\tresults.push(operation);\n\t\t}\n\t}\n\treturn results;\n};\n\nexports.getFilterOperators = function() {\n\tif(!this.filterOperators) {\n\t\t$tw.Wiki.prototype.filterOperators = {};\n\t\t$tw.modules.applyMethods(\"filteroperator\",this.filterOperators);\n\t}\n\treturn this.filterOperators;\n};\n\nexports.getFilterRunPrefixes = function() {\n\tif(!this.filterRunPrefixes) {\n\t\t$tw.Wiki.prototype.filterRunPrefixes = {};\n\t\t$tw.modules.applyMethods(\"filterrunprefix\",this.filterRunPrefixes);\n\t}\n\treturn this.filterRunPrefixes;\n}\n\nexports.filterTiddlers = function(filterString,widget,source) {\n\tvar fn = this.compileFilter(filterString);\n\treturn fn.call(this,source,widget);\n};\n\n/*\nCompile a filter into a function with the signature fn(source,widget) where:\nsource: an iterator function for the source tiddlers, called source(iterator), where iterator is called as iterator(tiddler,title)\nwidget: an optional widget node for retrieving the current tiddler etc.\n*/\nexports.compileFilter = function(filterString) {\n\tif(!this.filterCache) {\n\t\tthis.filterCache = Object.create(null);\n\t\tthis.filterCacheCount = 0;\n\t}\n\tif(this.filterCache[filterString] !== undefined) {\n\t\treturn this.filterCache[filterString];\n\t}\n\tvar filterParseTree;\n\ttry {\n\t\tfilterParseTree = this.parseFilter(filterString);\n\t} catch(e) {\n\t\t// We do not cache this result, so it adjusts along with localization changes\n\t\treturn function(source,widget) {\n\t\t\treturn [$tw.language.getString(\"Error/Filter\") + \": \" + e];\n\t\t};\n\t}\n\t// Get the hashmap of filter operator functions\n\tvar filterOperators = this.getFilterOperators();\n\t// Assemble array of functions, one for each operation\n\tvar operationFunctions = [];\n\t// Step through the operations\n\tvar self = this;\n\t$tw.utils.each(filterParseTree,function(operation) {\n\t\t// Create a function for the chain of operators in the operation\n\t\tvar operationSubFunction = function(source,widget) {\n\t\t\tvar accumulator = source,\n\t\t\t\tresults = [],\n\t\t\t\tcurrTiddlerTitle = widget && widget.getVariable(\"currentTiddler\");\n\t\t\t$tw.utils.each(operation.operators,function(operator) {\n\t\t\t\tvar operands = [],\n\t\t\t\t\toperatorFunction;\n\t\t\t\tif(!operator.operator) {\n\t\t\t\t\t// Use the \"title\" operator if no operator is specified\n\t\t\t\t\toperatorFunction = filterOperators.title;\n\t\t\t\t} else if(!filterOperators[operator.operator]) {\n\t\t\t\t\t// Unknown operators treated as \"[unknown]\" - at run time we can distinguish between a custom operator and falling back to the default \"field\" operator\n\t\t\t\t\toperatorFunction = filterOperators[\"[unknown]\"];\n\t\t\t\t} else {\n\t\t\t\t\t// Use the operator function\n\t\t\t\t\toperatorFunction = filterOperators[operator.operator];\n\t\t\t\t}\n\t\t\t\t$tw.utils.each(operator.operands,function(operand) {\n\t\t\t\t\tif(operand.indirect) {\n\t\t\t\t\t\toperand.value = self.getTextReference(operand.text,\"\",currTiddlerTitle);\n\t\t\t\t\t} else if(operand.variable) {\n\t\t\t\t\t\tvar varTree = $tw.utils.parseFilterVariable(operand.text);\n\t\t\t\t\t\toperand.value = widgetClass.evaluateVariable(widget,varTree.name,{params: varTree.params, source: source})[0] || \"\";\n\t\t\t\t\t} else {\n\t\t\t\t\t\toperand.value = operand.text;\n\t\t\t\t\t}\n\t\t\t\t\toperands.push(operand.value);\n\t\t\t\t});\n\n\t\t\t\t// Invoke the appropriate filteroperator module\n\t\t\t\tresults = operatorFunction(accumulator,{\n\t\t\t\t\t\t\toperator: operator.operator,\n\t\t\t\t\t\t\toperand: operands.length > 0 ? operands[0] : undefined,\n\t\t\t\t\t\t\toperands: operands,\n\t\t\t\t\t\t\tprefix: operator.prefix,\n\t\t\t\t\t\t\tsuffix: operator.suffix,\n\t\t\t\t\t\t\tsuffixes: operator.suffixes,\n\t\t\t\t\t\t\tregexp: operator.regexp\n\t\t\t\t\t\t},{\n\t\t\t\t\t\t\twiki: self,\n\t\t\t\t\t\t\twidget: widget\n\t\t\t\t\t\t});\n\t\t\t\tif($tw.utils.isArray(results)) {\n\t\t\t\t\taccumulator = self.makeTiddlerIterator(results);\n\t\t\t\t} else {\n\t\t\t\t\taccumulator = results;\n\t\t\t\t}\n\t\t\t});\n\t\t\tif($tw.utils.isArray(results)) {\n\t\t\t\treturn results;\n\t\t\t} else {\n\t\t\t\tvar resultArray = [];\n\t\t\t\tresults(function(tiddler,title) {\n\t\t\t\t\tresultArray.push(title);\n\t\t\t\t});\n\t\t\t\treturn resultArray;\n\t\t\t}\n\t\t};\n\t\tvar filterRunPrefixes = self.getFilterRunPrefixes();\n\t\t// Wrap the operator functions in a wrapper function that depends on the prefix\n\t\toperationFunctions.push((function() {\n\t\t\tvar options = {wiki: self, suffixes: operation.suffixes || []};\n\t\t\tswitch(operation.prefix || \"\") {\n\t\t\t\tcase \"\": // No prefix means that the operation is unioned into the result\n\t\t\t\t\treturn filterRunPrefixes[\"or\"](operationSubFunction, options);\n\t\t\t\tcase \"=\": // The results of the operation are pushed into the result without deduplication\n\t\t\t\t\treturn filterRunPrefixes[\"all\"](operationSubFunction, options);\n\t\t\t\tcase \"-\": // The results of this operation are removed from the main result\n\t\t\t\t\treturn filterRunPrefixes[\"except\"](operationSubFunction, options);\n\t\t\t\tcase \"+\": // This operation is applied to the main results so far\n\t\t\t\t\treturn filterRunPrefixes[\"and\"](operationSubFunction, options);\n\t\t\t\tcase \"~\": // This operation is unioned into the result only if the main result so far is empty\n\t\t\t\t\treturn filterRunPrefixes[\"else\"](operationSubFunction, options);\n\t\t\t\tdefault: \n\t\t\t\t\tif(operation.namedPrefix && filterRunPrefixes[operation.namedPrefix]) {\n\t\t\t\t\t\treturn filterRunPrefixes[operation.namedPrefix](operationSubFunction, options);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn function(results,source,widget) {\n\t\t\t\t\t\t\tresults.clear();\n\t\t\t\t\t\t\tresults.push($tw.language.getString(\"Error/FilterRunPrefix\"));\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t}\n\t\t})());\n\t});\n\t// Return a function that applies the operations to a source iterator of tiddler titles\n\tvar fnMeasured = $tw.perf.measure(\"filter: \" + filterString,function filterFunction(source,widget) {\n\t\tif(!source) {\n\t\t\tsource = self.each;\n\t\t} else if(typeof source === \"object\") { // Array or hashmap\n\t\t\tsource = self.makeTiddlerIterator(source);\n\t\t}\n\t\tif(!widget) {\n\t\t\twidget = $tw.rootWidget;\n\t\t}\n\t\tvar results = new $tw.utils.LinkedList();\n\t\tself.filterRecursionCount = (self.filterRecursionCount || 0) + 1;\n\t\tif(self.filterRecursionCount < MAX_FILTER_DEPTH) {\n\t\t\t$tw.utils.each(operationFunctions,function(operationFunction) {\n\t\t\t\toperationFunction(results,source,widget);\n\t\t\t});\n\t\t} else {\n\t\t\tresults.push(\"/**-- Excessive filter recursion --**/\");\n\t\t}\n\t\tself.filterRecursionCount = self.filterRecursionCount - 1;\n\t\treturn results.toArray();\n\t});\n\tif(this.filterCacheCount >= 2000) {\n\t\t// To prevent memory leak, we maintain an upper limit for cache size.\n\t\t// Reset if exceeded. This should give us 95% of the benefit\n\t\t// that no cache limit would give us.\n\t\tthis.filterCache = Object.create(null);\n\t\tthis.filterCacheCount = 0;\n\t}\n\tthis.filterCache[filterString] = fnMeasured;\n\tthis.filterCacheCount++;\n\treturn fnMeasured;\n};\n\n})();\n","type":"application/javascript","module-type":"wikimethod"},"$:/core/modules/indexers/back-indexer.js":{"title":"$:/core/modules/indexers/back-indexer.js","text":"/*\\\ntitle: $:/core/modules/indexers/back-indexer.js\ntype: application/javascript\nmodule-type: indexer\n\nBy parsing the tiddler text, indexes the tiddlers' back links, back transclusions, block level back links.\n\n\\*/\nfunction BackIndexer(wiki) {\n\tthis.wiki = wiki;\n}\n\nBackIndexer.prototype.init = function() {\n\tthis.subIndexers = {\n\t\tlink: new BackSubIndexer(this,\"extractLinks\"),\n\t\ttransclude: new BackSubIndexer(this,\"extractTranscludes\"),\n\t};\n};\n\nBackIndexer.prototype.rebuild = function() {\n\t$tw.utils.each(this.subIndexers,function(subIndexer) {\n\t\tsubIndexer.rebuild();\n\t});\n};\n\nBackIndexer.prototype.update = function(updateDescriptor) {\n\t$tw.utils.each(this.subIndexers,function(subIndexer) {\n\t\tsubIndexer.update(updateDescriptor);\n\t});\n};\nfunction BackSubIndexer(indexer,extractor) {\n\tthis.wiki = indexer.wiki;\n\tthis.indexer = indexer;\n\tthis.extractor = extractor;\n\t/**\n\t * {\n\t *   [target title, e.g. tiddler title being linked to]:\n\t *     {\n\t * \t\t   [source title, e.g. tiddler title that has link syntax in its text]: true\n\t * \t   }\n\t * }\n\t */\n\tthis.index = null;\n}\n\nBackSubIndexer.prototype.init = function() {\n\t// lazy init until first lookup\n\tthis.index = null;\n}\n\nBackSubIndexer.prototype._init = function() {\n\tthis.index = Object.create(null);\n\tvar self = this;\n\tthis.wiki.forEachTiddler(function(sourceTitle,tiddler) {\n\t\tvar newTargets = self._getTarget(tiddler);\n\t\t$tw.utils.each(newTargets, function(target) {\n\t\t\tif(!self.index[target]) {\n\t\t\t\tself.index[target] = Object.create(null);\n\t\t\t}\n\t\t\tself.index[target][sourceTitle] = true;\n\t\t});\n\t});\n}\n\nBackSubIndexer.prototype.rebuild = function() {\n\tthis.index = null;\n}\n\n/*\n* Get things that is being referenced in the text, e.g. tiddler names in the link syntax.\n*/\nBackSubIndexer.prototype._getTarget = function(tiddler) {\n\tif(this.wiki.isBinaryTiddler(tiddler.fields.text)) {\n\t\treturn [];\n\t}\n\tvar parser = this.wiki.parseText(tiddler.fields.type, tiddler.fields.text, {});\n\tif(parser) {\n\t\treturn this.wiki[this.extractor](parser.tree, tiddler.fields.title);\n\t}\n\treturn [];\n}\n\nBackSubIndexer.prototype.update = function(updateDescriptor) {\n\t// lazy init/update until first lookup\n\tif(!this.index) {\n\t\treturn;\n\t}\n\tvar newTargets = [],\n\t    oldTargets = [],\n\t    self = this;\n\tif(updateDescriptor.old.exists) {\n\t\toldTargets = this._getTarget(updateDescriptor.old.tiddler);\n\t}\n\tif(updateDescriptor.new.exists) {\n\t\tnewTargets = this._getTarget(updateDescriptor.new.tiddler);\n\t}\n\n\t$tw.utils.each(oldTargets,function(target) {\n\t\tif(self.index[target]) {\n\t\t\tdelete self.index[target][updateDescriptor.old.tiddler.fields.title];\n\t\t}\n\t});\n\t$tw.utils.each(newTargets,function(target) {\n\t\tif(!self.index[target]) {\n\t\t\tself.index[target] = Object.create(null);\n\t\t}\n\t\tself.index[target][updateDescriptor.new.tiddler.fields.title] = true;\n\t});\n}\n\nBackSubIndexer.prototype.lookup = function(title) {\n\tif(!this.index) {\n\t\tthis._init();\n\t}\n\tif(this.index[title]) {\n\t\treturn Object.keys(this.index[title]);\n\t} else {\n\t\treturn [];\n\t}\n}\n\nexports.BackIndexer = BackIndexer;\n","type":"application/javascript","module-type":"indexer"},"$:/core/modules/indexers/field-indexer.js":{"title":"$:/core/modules/indexers/field-indexer.js","text":"/*\\\ntitle: $:/core/modules/indexers/field-indexer.js\ntype: application/javascript\nmodule-type: indexer\n\nIndexes the tiddlers with each field value\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global modules: false */\n\"use strict\";\n\nvar DEFAULT_MAXIMUM_INDEXED_VALUE_LENGTH = 128;\n\nfunction FieldIndexer(wiki) {\n\tthis.wiki = wiki;\n}\n\nFieldIndexer.prototype.init = function() {\n\tthis.index = null;\n\tthis.maxIndexedValueLength = DEFAULT_MAXIMUM_INDEXED_VALUE_LENGTH;\n\tthis.addIndexMethods();\n}\n\n// Provided for testing\nFieldIndexer.prototype.setMaxIndexedValueLength = function(length) {\n\tthis.index = null;\n\tthis.maxIndexedValueLength = length;\n};\n\nFieldIndexer.prototype.addIndexMethods = function() {\n\tvar self = this;\n\t// get all tiddlers, including those overwrite shadow tiddlers\n\tthis.wiki.each.byField = function(name,value) {\n\t\tvar lookup = self.lookup(name,value);\n\t\treturn lookup && lookup.filter(function(title) {\n\t\t\treturn self.wiki.tiddlerExists(title)\n\t\t});\n\t};\n\t// get shadow tiddlers, including shadow tiddlers that is overwritten\n\tthis.wiki.eachShadow.byField = function(name,value) {\n\t\tvar lookup = self.lookup(name,value);\n\t\treturn lookup && lookup.filter(function(title) {\n\t\t\treturn self.wiki.isShadowTiddler(title)\n\t\t});\n\t};\n\tthis.wiki.eachTiddlerPlusShadows.byField = function(name,value) {\n\t\tvar lookup = self.lookup(name,value);\n\t\treturn lookup ? lookup.slice(0) : null;\n\t};\n\tthis.wiki.eachShadowPlusTiddlers.byField = function(name,value) {\n\t\tvar lookup = self.lookup(name,value);\n\t\treturn lookup ? lookup.slice(0) : null;\n\t};\n};\n\n/*\nTear down and then rebuild the index as if all tiddlers have changed\n*/\nFieldIndexer.prototype.rebuild = function() {\n\t// Invalidate the index so that it will be rebuilt when it is next used\n\tthis.index = null;\n};\n\n/*\nBuild the index for a particular field\n*/\nFieldIndexer.prototype.buildIndexForField = function(name) {\n\tvar self = this;\n\t// Hashmap by field name of hashmap by field value of array of tiddler titles\n\tthis.index = this.index || Object.create(null);\n\tthis.index[name] = Object.create(null);\n\tvar baseIndex = this.index[name];\n\t// Update the index for each tiddler\n\tthis.wiki.eachTiddlerPlusShadows(function(tiddler,title) {\n\t\tif(name in tiddler.fields) {\n\t\t\tvar value = tiddler.getFieldString(name);\n\t\t\t// Skip any values above the maximum length\n\t\t\tif(value.length < self.maxIndexedValueLength) {\n\t\t\t\tbaseIndex[value] = baseIndex[value] || [];\n\t\t\t\tbaseIndex[value].push(title);\n\t\t\t}\n\t\t}\n\t});\n};\n\n/*\nUpdate the index in the light of a tiddler value changing; note that the title must be identical. (Renames are handled as a separate delete and create)\nupdateDescriptor: {old: {tiddler: <tiddler>, shadow: <boolean>, exists: <boolean>},new: {tiddler: <tiddler>, shadow: <boolean>, exists: <boolean>}}\n*/\nFieldIndexer.prototype.update = function(updateDescriptor) {\n\tvar self = this;\n\t// Don't do anything if the index hasn't been built yet\n\tif(this.index === null) {\n\t\treturn;\n\t}\n\t// Remove the old tiddler from the index\n\tif(updateDescriptor.old.tiddler) {\n\t\t$tw.utils.each(this.index,function(indexEntry,name) {\n\t\t\tif(name in updateDescriptor.old.tiddler.fields) {\n\t\t\t\tvar value = updateDescriptor.old.tiddler.getFieldString(name),\n\t\t\t\t\ttiddlerList = indexEntry[value];\n\t\t\t\tif(tiddlerList) {\n\t\t\t\t\tvar index = tiddlerList.indexOf(updateDescriptor.old.tiddler.fields.title);\n\t\t\t\t\tif(index !== -1) {\n\t\t\t\t\t\ttiddlerList.splice(index,1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\t// Add the new tiddler to the index\n\tif(updateDescriptor[\"new\"].tiddler) {\n\t\t$tw.utils.each(this.index,function(indexEntry,name) {\n\t\t\tif(name in updateDescriptor[\"new\"].tiddler.fields) {\n\t\t\t\tvar value = updateDescriptor[\"new\"].tiddler.getFieldString(name);\n\t\t\t\tif(value.length < self.maxIndexedValueLength) {\n\t\t\t\t\tindexEntry[value] = indexEntry[value] || [];\n\t\t\t\t\tindexEntry[value].push(updateDescriptor[\"new\"].tiddler.fields.title);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n};\n\n// Lookup the given field returning a list of tiddler titles\nFieldIndexer.prototype.lookup = function(name,value) {\n\t// Fail the lookup if the value is too long\n\tif(value.length >= this.maxIndexedValueLength) {\n\t\treturn null;\n\t}\n\t// Update the index if it has yet to be built\n\tif(this.index === null || !this.index[name]) {\n\t\tthis.buildIndexForField(name);\n\t}\n\treturn this.index[name][value] || [];\n};\n\nexports.FieldIndexer = FieldIndexer;\n\n})();\n","type":"application/javascript","module-type":"indexer"},"$:/core/modules/indexers/tag-indexer.js":{"title":"$:/core/modules/indexers/tag-indexer.js","text":"/*\\\ntitle: $:/core/modules/indexers/tag-indexer.js\ntype: application/javascript\nmodule-type: indexer\n\nIndexes the tiddlers with each tag\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global modules: false */\n\"use strict\";\n\nfunction TagIndexer(wiki) {\n\tthis.wiki = wiki;\n}\n\nTagIndexer.prototype.init = function() {\n\tthis.subIndexers = [\n\t\tnew TagSubIndexer(this,\"each\"),\n\t\tnew TagSubIndexer(this,\"eachShadow\"),\n\t\tnew TagSubIndexer(this,\"eachTiddlerPlusShadows\"),\n\t\tnew TagSubIndexer(this,\"eachShadowPlusTiddlers\")\n\t];\n\t$tw.utils.each(this.subIndexers,function(subIndexer) {\n\t\tsubIndexer.addIndexMethod();\n\t});\n};\n\nTagIndexer.prototype.rebuild = function() {\n\t$tw.utils.each(this.subIndexers,function(subIndexer) {\n\t\tsubIndexer.rebuild();\n\t});\n};\n\nTagIndexer.prototype.update = function(updateDescriptor) {\n\t$tw.utils.each(this.subIndexers,function(subIndexer) {\n\t\tsubIndexer.update(updateDescriptor);\n\t});\n};\n\nfunction TagSubIndexer(indexer,iteratorMethod) {\n\tthis.indexer = indexer;\n\tthis.iteratorMethod = iteratorMethod;\n\tthis.index = null; // Hashmap of tag title to {isSorted: bool, titles: [array]} or null if not yet initialised\n}\n\nTagSubIndexer.prototype.addIndexMethod = function() {\n\tvar self = this;\n\tthis.indexer.wiki[this.iteratorMethod].byTag = function(tag) {\n\t\treturn self.lookup(tag).slice(0);\n\t};\n};\n\nTagSubIndexer.prototype.rebuild = function() {\n\tvar self = this;\n\t// Hashmap by tag of array of {isSorted:, titles:[]}\n\tthis.index = Object.create(null);\n\t// Add all the tags\n\tthis.indexer.wiki[this.iteratorMethod](function(tiddler,title) {\n\t\t$tw.utils.each(tiddler.fields.tags,function(tag) {\n\t\t\tif(!self.index[tag]) {\n\t\t\t\tself.index[tag] = {isSorted: false, titles: [title]};\n\t\t\t} else {\n\t\t\t\tself.index[tag].titles.push(title);\n\t\t\t}\n\t\t});\n\t});\n};\n\nTagSubIndexer.prototype.update = function(updateDescriptor) {\n\tthis.index = null;\n};\n\nTagSubIndexer.prototype.lookup = function(tag) {\n\t// Update the index if it has yet to be built\n\tif(this.index === null) {\n\t\tthis.rebuild();\n\t}\n\tvar indexRecord = this.index[tag];\n\tif(indexRecord) {\n\t\tif(!indexRecord.isSorted) {\n\t\t\tif(this.indexer.wiki.sortByList) {\n\t\t\t\tindexRecord.titles = this.indexer.wiki.sortByList(indexRecord.titles,tag);\n\t\t\t}\n\t\t\tindexRecord.isSorted = true;\n\t\t}\n\t\treturn indexRecord.titles;\n\t} else {\n\t\treturn [];\n\t}\n};\n\n\nexports.TagIndexer = TagIndexer;\n\n})();\n","type":"application/javascript","module-type":"indexer"},"$:/core/modules/info/platform.js":{"title":"$:/core/modules/info/platform.js","text":"/*\\\ntitle: $:/core/modules/info/platform.js\ntype: application/javascript\nmodule-type: info\n\nInitialise basic platform $:/info/ tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.getInfoTiddlerFields = function(updateInfoTiddlersCallback) {\n\tvar mapBoolean = function(value) {return value ? \"yes\" : \"no\";},\n\t\tinfoTiddlerFields = [];\n\t// Basics\n\tinfoTiddlerFields.push({title: \"$:/info/browser\", text: mapBoolean(!!$tw.browser)});\n\tinfoTiddlerFields.push({title: \"$:/info/node\", text: mapBoolean(!!$tw.node)});\n\tinfoTiddlerFields.push({title: \"$:/info/startup-timestamp\", text: $tw.utils.stringifyDate(new Date())});\n\tif($tw.browser) {\n\t\t// Document location\n\t\tvar setLocationProperty = function(name,value) {\n\t\t\t\tinfoTiddlerFields.push({title: \"$:/info/url/\" + name, text: value});\n\t\t\t},\n\t\t\tlocation = document.location;\n\t\tsetLocationProperty(\"full\", (location.toString()).split(\"#\")[0]);\n\t\tsetLocationProperty(\"host\", location.host);\n\t\tsetLocationProperty(\"hostname\", location.hostname);\n\t\tsetLocationProperty(\"protocol\", location.protocol);\n\t\tsetLocationProperty(\"port\", location.port);\n\t\tsetLocationProperty(\"pathname\", location.pathname);\n\t\tsetLocationProperty(\"search\", location.search);\n\t\tsetLocationProperty(\"origin\", location.origin);\n\t\t// Screen size\n\t\tinfoTiddlerFields.push({title: \"$:/info/browser/screen/width\", text: window.screen.width.toString()});\n\t\tinfoTiddlerFields.push({title: \"$:/info/browser/screen/height\", text: window.screen.height.toString()});\n \t\t// Dark mode through event listener on MediaQueryList\n \t\tvar mqList = window.matchMedia(\"(prefers-color-scheme: dark)\"),\n \t\t\tgetDarkModeTiddler = function() {return {title: \"$:/info/darkmode\", text: mqList.matches ? \"yes\" : \"no\"};};\n \t\tinfoTiddlerFields.push(getDarkModeTiddler());\n \t\tmqList.addListener(function(event) {\n \t\t\tupdateInfoTiddlersCallback([getDarkModeTiddler()]);\n \t\t});\n\t\t// Language\n\t\tinfoTiddlerFields.push({title: \"$:/info/browser/language\", text: navigator.language || \"\"});\n\t}\n\treturn infoTiddlerFields;\n};\n\n})();\n","type":"application/javascript","module-type":"info"},"$:/core/modules/keyboard.js":{"title":"$:/core/modules/keyboard.js","text":"/*\\\ntitle: $:/core/modules/keyboard.js\ntype: application/javascript\nmodule-type: global\n\nKeyboard handling utilities\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar namedKeys = {\n\t\"cancel\": 3,\n\t\"help\": 6,\n\t\"backspace\": 8,\n\t\"tab\": 9,\n\t\"clear\": 12,\n\t\"return\": 13,\n\t\"enter\": 13,\n\t\"pause\": 19,\n\t\"escape\": 27,\n\t\"space\": 32,\n\t\"page_up\": 33,\n\t\"page_down\": 34,\n\t\"end\": 35,\n\t\"home\": 36,\n\t\"left\": 37,\n\t\"up\": 38,\n\t\"right\": 39,\n\t\"down\": 40,\n\t\"printscreen\": 44,\n\t\"insert\": 45,\n\t\"delete\": 46,\n\t\"0\": 48,\n\t\"1\": 49,\n\t\"2\": 50,\n\t\"3\": 51,\n\t\"4\": 52,\n\t\"5\": 53,\n\t\"6\": 54,\n\t\"7\": 55,\n\t\"8\": 56,\n\t\"9\": 57,\n\t\"firefoxsemicolon\": 59,\n\t\"firefoxequals\": 61,\n\t\"a\": 65,\n\t\"b\": 66,\n\t\"c\": 67,\n\t\"d\": 68,\n\t\"e\": 69,\n\t\"f\": 70,\n\t\"g\": 71,\n\t\"h\": 72,\n\t\"i\": 73,\n\t\"j\": 74,\n\t\"k\": 75,\n\t\"l\": 76,\n\t\"m\": 77,\n\t\"n\": 78,\n\t\"o\": 79,\n\t\"p\": 80,\n\t\"q\": 81,\n\t\"r\": 82,\n\t\"s\": 83,\n\t\"t\": 84,\n\t\"u\": 85,\n\t\"v\": 86,\n\t\"w\": 87,\n\t\"x\": 88,\n\t\"y\": 89,\n\t\"z\": 90,\n\t\"numpad0\": 96,\n\t\"numpad1\": 97,\n\t\"numpad2\": 98,\n\t\"numpad3\": 99,\n\t\"numpad4\": 100,\n\t\"numpad5\": 101,\n\t\"numpad6\": 102,\n\t\"numpad7\": 103,\n\t\"numpad8\": 104,\n\t\"numpad9\": 105,\n\t\"multiply\": 106,\n\t\"add\": 107,\n\t\"separator\": 108,\n\t\"subtract\": 109,\n\t\"decimal\": 110,\n\t\"divide\": 111,\n\t\"f1\": 112,\n\t\"f2\": 113,\n\t\"f3\": 114,\n\t\"f4\": 115,\n\t\"f5\": 116,\n\t\"f6\": 117,\n\t\"f7\": 118,\n\t\"f8\": 119,\n\t\"f9\": 120,\n\t\"f10\": 121,\n\t\"f11\": 122,\n\t\"f12\": 123,\n\t\"f13\": 124,\n\t\"f14\": 125,\n\t\"f15\": 126,\n\t\"f16\": 127,\n\t\"f17\": 128,\n\t\"f18\": 129,\n\t\"f19\": 130,\n\t\"f20\": 131,\n\t\"f21\": 132,\n\t\"f22\": 133,\n\t\"f23\": 134,\n\t\"f24\": 135,\n\t\"firefoxminus\": 173,\n\t\"semicolon\": 186,\n\t\"equals\": 187,\n\t\"comma\": 188,\n\t\"dash\": 189,\n\t\"period\": 190,\n\t\"slash\": 191,\n\t\"backquote\": 192,\n\t\"openbracket\": 219,\n\t\"backslash\": 220,\n\t\"closebracket\": 221,\n\t\"quote\": 222\n};\n\nfunction KeyboardManager(options) {\n\tvar self = this;\n\toptions = options || \"\";\n\t// Save the named key hashmap\n\tthis.namedKeys = namedKeys;\n\t// Create a reverse mapping of code to keyname\n\tthis.keyNames = [];\n\t$tw.utils.each(namedKeys,function(keyCode,name) {\n\t\tself.keyNames[keyCode] = name.substr(0,1).toUpperCase() + name.substr(1);\n\t});\n\t// Save the platform-specific name of the \"meta\" key\n\tthis.metaKeyName = $tw.platform.isMac ? \"cmd-\" : \"win-\";\n\tthis.shortcutKeysList = [], // Stores the shortcut-key descriptors\n\tthis.shortcutActionList = [], // Stores the corresponding action strings\n\tthis.shortcutParsedList = []; // Stores the parsed key descriptors\n\tthis.shortcutPriorityList = []; // Stores the parsed shortcut priority\n\tthis.lookupNames = [\"shortcuts\"];\n\tthis.lookupNames.push($tw.platform.isMac ? \"shortcuts-mac\" : \"shortcuts-not-mac\")\n\tthis.lookupNames.push($tw.platform.isWindows ? \"shortcuts-windows\" : \"shortcuts-not-windows\");\n\tthis.lookupNames.push($tw.platform.isLinux ? \"shortcuts-linux\" : \"shortcuts-not-linux\");\n\tthis.updateShortcutLists(this.getShortcutTiddlerList());\n\t$tw.wiki.addEventListener(\"change\",function(changes) {\n\t\tself.handleShortcutChanges(changes);\n\t});\n}\n\n/*\nReturn an array of keycodes for the modifier keys ctrl, shift, alt, meta\n*/\nKeyboardManager.prototype.getModifierKeys = function() {\n\treturn [\n\t\t16, // Shift\n\t\t17, // Ctrl\n\t\t18, // Alt\n\t\t20, // CAPS LOCK\n\t\t91, // Meta (left)\n\t\t93, // Meta (right)\n\t\t224 // Meta (Firefox)\n\t]\n};\n\n/*\nParses a key descriptor into the structure:\n{\n\tkeyCode: numeric keycode\n\tshiftKey: boolean\n\taltKey: boolean\n\tctrlKey: boolean\n\tmetaKey: boolean\n}\nKey descriptors have the following format:\n\tctrl+enter\n\tctrl+shift+alt+A\n*/\nKeyboardManager.prototype.parseKeyDescriptor = function(keyDescriptor,options) {\n\tvar components = keyDescriptor.split(/\\+|\\-/),\n\t\tinfo = {\n\t\t\tkeyCode: 0,\n\t\t\tshiftKey: false,\n\t\t\taltKey: false,\n\t\t\tctrlKey: false,\n\t\t\tmetaKey: false\n\t\t};\n\tfor(var t=0; t<components.length; t++) {\n\t\tvar s = components[t].toLowerCase(),\n\t\t\tc = s.charCodeAt(0);\n\t\t// Look for modifier keys\n\t\tif(s === \"ctrl\") {\n\t\t\tinfo.ctrlKey = true;\n\t\t} else if(s === \"shift\") {\n\t\t\tinfo.shiftKey = true;\n\t\t} else if(s === \"alt\") {\n\t\t\tinfo.altKey = true;\n\t\t} else if(s === \"meta\" || s === \"cmd\" || s === \"win\") {\n\t\t\tinfo.metaKey = true;\n\t\t}\n\t\t// Replace named keys with their code\n\t\tif(this.namedKeys[s]) {\n\t\t\tinfo.keyCode = this.namedKeys[s];\n\t\t}\n\t}\n\tif(options.keyDescriptor) {\n\t\tinfo.keyDescriptor = options.keyDescriptor;\n\t}\n\tif(info.keyCode) {\n\t\treturn info;\n\t} else {\n\t\treturn null;\n\t}\n};\n\n/*\nParse a list of key descriptors into an array of keyInfo objects. The key descriptors can be passed as an array of strings or a space separated string\n*/\nKeyboardManager.prototype.parseKeyDescriptors = function(keyDescriptors,options) {\n\tvar self = this;\n\toptions = options || {};\n\toptions.stack = options.stack || [];\n\tvar wiki = options.wiki || $tw.wiki;\n\tif(typeof keyDescriptors === \"string\" && keyDescriptors === \"\") {\n\t\treturn [];\n\t}\n\tif(!$tw.utils.isArray(keyDescriptors)) {\n\t\tkeyDescriptors = keyDescriptors.split(\" \");\n\t}\n\tvar result = [];\n\t$tw.utils.each(keyDescriptors,function(keyDescriptor) {\n\t\t// Look for a named shortcut\n\t\tif(keyDescriptor.substr(0,2) === \"((\" && keyDescriptor.substr(-2,2) === \"))\") {\n\t\t\tif(options.stack.indexOf(keyDescriptor) === -1) {\n\t\t\t\toptions.stack.push(keyDescriptor);\n\t\t\t\tvar name = keyDescriptor.substring(2,keyDescriptor.length - 2),\n\t\t\t\t\tlookupName = function(configName) {\n\t\t\t\t\t\tvar keyDescriptors = wiki.getTiddlerText(\"$:/config/\" + configName + \"/\" + name);\n\t\t\t\t\t\tif(keyDescriptors) {\n\t\t\t\t\t\t\toptions.keyDescriptor = keyDescriptor;\n\t\t\t\t\t\t\tresult.push.apply(result,self.parseKeyDescriptors(keyDescriptors,options));\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t$tw.utils.each(self.lookupNames,function(platformDescriptor) {\n\t\t\t\t\tlookupName(platformDescriptor);\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tresult.push(self.parseKeyDescriptor(keyDescriptor,options));\n\t\t}\n\t});\n\treturn result;\n};\n\nKeyboardManager.prototype.getPrintableShortcuts = function(keyInfoArray) {\n\tvar self = this,\n\t\tresult = [];\n\t$tw.utils.each(keyInfoArray,function(keyInfo) {\n\t\tif(keyInfo) {\n\t\t\tresult.push((keyInfo.ctrlKey ? \"ctrl-\" : \"\") + \n\t\t\t\t   (keyInfo.shiftKey ? \"shift-\" : \"\") + \n\t\t\t\t   (keyInfo.altKey ? \"alt-\" : \"\") + \n\t\t\t\t   (keyInfo.metaKey ? self.metaKeyName : \"\") + \n\t\t\t\t   (self.keyNames[keyInfo.keyCode]));\n\t\t}\n\t});\n\treturn result;\n}\n\nKeyboardManager.prototype.checkKeyDescriptor = function(event,keyInfo) {\n\treturn keyInfo &&\n\t\t\tevent.keyCode === keyInfo.keyCode && \n\t\t\tevent.shiftKey === keyInfo.shiftKey && \n\t\t\tevent.altKey === keyInfo.altKey && \n\t\t\tevent.ctrlKey === keyInfo.ctrlKey && \n\t\t\tevent.metaKey === keyInfo.metaKey;\n};\n\nKeyboardManager.prototype.checkKeyDescriptors = function(event,keyInfoArray) {\n\treturn (this.getMatchingKeyDescriptor(event,keyInfoArray) !== null);\n};\n\nKeyboardManager.prototype.getMatchingKeyDescriptor = function(event,keyInfoArray) {\n\tfor(var t=0; t<keyInfoArray.length; t++) {\n\t\tif(this.checkKeyDescriptor(event,keyInfoArray[t])) {\n\t\t\treturn keyInfoArray[t];\n\t\t}\n\t}\n\treturn null;\n};\n\nKeyboardManager.prototype.getEventModifierKeyDescriptor = function(event) {\n\treturn event.ctrlKey && !event.shiftKey\t&& !event.altKey && !event.metaKey ? \"ctrl\" : \n\t\tevent.shiftKey && !event.ctrlKey && !event.altKey && !event.metaKey ? \"shift\" : \n\t\tevent.ctrlKey && event.shiftKey && !event.altKey && !event.metaKey ? \"ctrl-shift\" : \n\t\tevent.altKey && !event.shiftKey && !event.ctrlKey && !event.metaKey ? \"alt\" : \n\t\tevent.altKey && event.shiftKey && !event.ctrlKey && !event.metaKey ? \"alt-shift\" : \n\t\tevent.altKey && event.ctrlKey && !event.shiftKey && !event.metaKey ? \"ctrl-alt\" : \n\t\tevent.altKey && event.shiftKey && event.ctrlKey && !event.metaKey ? \"ctrl-alt-shift\" : \n\t\tevent.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey ? \"meta\" : \n\t\tevent.metaKey && event.ctrlKey && !event.shiftKey && !event.altKey ? \"meta-ctrl\" :\n\t\tevent.metaKey && event.ctrlKey && event.shiftKey && !event.altKey ? \"meta-ctrl-shift\" :\n\t\tevent.metaKey && event.ctrlKey && event.shiftKey && event.altKey ? \"meta-ctrl-alt-shift\" : \"normal\";\n};\n\nKeyboardManager.prototype.getShortcutTiddlerList = function() {\n\treturn $tw.wiki.getTiddlersWithTag(\"$:/tags/KeyboardShortcut\");\n};\n\nKeyboardManager.prototype.updateShortcutLists = function(tiddlerList) {\n\tthis.shortcutTiddlers = tiddlerList;\n\tfor(var i=0; i<tiddlerList.length; i++) {\n\t\tvar title = tiddlerList[i],\n\t\t\ttiddlerFields = $tw.wiki.getTiddler(title).fields;\n\t\tthis.shortcutKeysList[i] = tiddlerFields.key !== undefined ? tiddlerFields.key : undefined;\n\t\tthis.shortcutActionList[i] = tiddlerFields.text;\n\t\tthis.shortcutParsedList[i] = this.shortcutKeysList[i] !== undefined ? this.parseKeyDescriptors(this.shortcutKeysList[i]) : undefined;\n\t\tthis.shortcutPriorityList[i] = tiddlerFields.priority === \"yes\" ? true : false;\n\t}\n};\n\n/*\nevent: the keyboard event object\noptions:\n\tonlyPriority: true if only priority global shortcuts should be invoked\n*/\nKeyboardManager.prototype.handleKeydownEvent = function(event, options) {\n\toptions = options || {};\n\tvar key, action;\n\tfor(var i=0; i<this.shortcutTiddlers.length; i++) {\n\t\tif(options.onlyPriority && this.shortcutPriorityList[i] !== true) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif(this.shortcutParsedList[i] !== undefined && this.checkKeyDescriptors(event,this.shortcutParsedList[i])) {\n\t\t\tkey = this.shortcutParsedList[i];\n\t\t\taction = this.shortcutActionList[i];\n\t\t}\n\t}\n\tif(key !== undefined) {\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t\t$tw.rootWidget.invokeActionString(action,$tw.rootWidget,event);\n\t\treturn true;\n\t}\n\treturn false;\n};\n\nKeyboardManager.prototype.detectNewShortcuts = function(changedTiddlers) {\n\tvar shortcutConfigTiddlers = [],\n\t\thandled = false;\n\t$tw.utils.each(this.lookupNames,function(platformDescriptor) {\n\t\tvar descriptorString = \"$:/config/\" + platformDescriptor + \"/\";\n\t\tObject.keys(changedTiddlers).forEach(function(configTiddler) {\n\t\t\tvar configString = configTiddler.substr(0, configTiddler.lastIndexOf(\"/\") + 1);\n\t\t\tif(configString === descriptorString) {\n\t\t\t\tshortcutConfigTiddlers.push(configTiddler);\n\t\t\t\thandled = true;\n\t\t\t}\n\t\t});\n\t});\n\tif(handled) {\n\t\treturn $tw.utils.hopArray(changedTiddlers,shortcutConfigTiddlers);\n\t} else {\n\t\treturn false;\n\t}\n};\n\nKeyboardManager.prototype.handleShortcutChanges = function(changedTiddlers) {\n\tvar newList = this.getShortcutTiddlerList();\n\tvar hasChanged = $tw.utils.hopArray(changedTiddlers,this.shortcutTiddlers) ? true :\n\t\t($tw.utils.hopArray(changedTiddlers,newList) ? true :\n\t\t(this.detectNewShortcuts(changedTiddlers))\n\t);\n\t// Re-cache shortcuts if something changed\n\tif(hasChanged) {\n\t\tthis.updateShortcutLists(newList);\n\t}\n};\n\nexports.KeyboardManager = KeyboardManager;\n\n})();\n","type":"application/javascript","module-type":"global"},"$:/core/modules/language.js":{"title":"$:/core/modules/language.js","text":"/*\\\ntitle: $:/core/modules/language.js\ntype: application/javascript\nmodule-type: global\n\nThe $tw.Language() manages translateable strings\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nCreate an instance of the language manager. Options include:\nwiki: wiki from which to retrieve translation tiddlers\n*/\nfunction Language(options) {\n\toptions = options || \"\";\n\tthis.wiki = options.wiki || $tw.wiki;\n}\n\n/*\nReturn a wikified translateable string. The title is automatically prefixed with \"$:/language/\"\nOptions include:\nvariables: optional hashmap of variables to supply to the language wikification\n*/\nLanguage.prototype.getString = function(title,options) {\n\toptions = options || {};\n\ttitle = \"$:/language/\" + title;\n\treturn this.wiki.renderTiddler(\"text/plain\",title,{variables: options.variables});\n};\n\n/*\nReturn a raw, unwikified translateable string. The title is automatically prefixed with \"$:/language/\"\n*/\nLanguage.prototype.getRawString = function(title) {\n\ttitle = \"$:/language/\" + title;\n\treturn this.wiki.getTiddlerText(title);\n};\n\nexports.Language = Language;\n\n})();\n","type":"application/javascript","module-type":"global"},"$:/core/modules/macros/changecount.js":{"title":"$:/core/modules/macros/changecount.js","text":"/*\\\ntitle: $:/core/modules/macros/changecount.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to return the changecount for the current tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"changecount\";\n\nexports.params = [];\n\n/*\nRun the macro\n*/\nexports.run = function() {\n\treturn this.wiki.getChangeCount(this.getVariable(\"currentTiddler\")) + \"\";\n};\n\n})();\n","type":"application/javascript","module-type":"macro"},"$:/core/modules/macros/contrastcolour.js":{"title":"$:/core/modules/macros/contrastcolour.js","text":"/*\\\ntitle: $:/core/modules/macros/contrastcolour.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to choose which of two colours has the highest contrast with a base colour\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"contrastcolour\";\n\nexports.params = [\n\t{name: \"target\"},\n\t{name: \"fallbackTarget\"},\n\t{name: \"colourA\"},\n\t{name: \"colourB\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(target,fallbackTarget,colourA,colourB) {\n\tvar rgbTarget = $tw.utils.parseCSSColor(target) || $tw.utils.parseCSSColor(fallbackTarget);\n\tif(!rgbTarget) {\n\t\treturn colourA;\n\t}\n\tvar rgbColourA = $tw.utils.parseCSSColor(colourA),\n\t\trgbColourB = $tw.utils.parseCSSColor(colourB);\n\tif(rgbColourA && !rgbColourB) {\n\t\treturn rgbColourA;\n\t}\n\tif(rgbColourB && !rgbColourA) {\n\t\treturn rgbColourB;\n\t}\n\tif(!rgbColourA && !rgbColourB) {\n\t\t// If neither colour is readable, return a crude inverse of the target\n\t\treturn [255 - rgbTarget[0],255 - rgbTarget[1],255 - rgbTarget[2],rgbTarget[3]];\n\t}\n\t// Colour brightness formula derived from http://www.w3.org/WAI/ER/WD-AERT/#color-contrast\n\tvar brightnessTarget = rgbTarget[0] * 0.299 + rgbTarget[1] * 0.587 + rgbTarget[2] * 0.114,\n\t\tbrightnessA = rgbColourA[0] * 0.299 + rgbColourA[1] * 0.587 + rgbColourA[2] * 0.114,\n\t\tbrightnessB = rgbColourB[0] * 0.299 + rgbColourB[1] * 0.587 + rgbColourB[2] * 0.114;\n\treturn Math.abs(brightnessTarget - brightnessA) > Math.abs(brightnessTarget - brightnessB) ? colourA : colourB;\n};\n\n})();\n","type":"application/javascript","module-type":"macro"},"$:/core/modules/macros/csvtiddlers.js":{"title":"$:/core/modules/macros/csvtiddlers.js","text":"/*\\\ntitle: $:/core/modules/macros/csvtiddlers.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to output tiddlers matching a filter to CSV\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"csvtiddlers\";\n\nexports.params = [\n\t{name: \"filter\"},\n\t{name: \"format\"},\n];\n\n/*\nRun the macro\n*/\nexports.run = function(filter,format) {\n\tvar self = this,\n\t\ttiddlers = this.wiki.filterTiddlers(filter),\n\t\ttiddler,\n\t\tfields = [],\n\t\tt,f;\n\t// Collect all the fields\n\tfor(t=0;t<tiddlers.length; t++) {\n\t\ttiddler = this.wiki.getTiddler(tiddlers[t]);\n\t\tif(tiddler) {\n\t\t\tfor(f in tiddler.fields) {\n\t\t\t\tif(fields.indexOf(f) === -1) {\n\t\t\t\t\tfields.push(f);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t// Sort the fields and bring the standard ones to the front\n\tfields.sort();\n\t\"title text modified modifier created creator\".split(\" \").reverse().forEach(function(value,index) {\n\t\tvar p = fields.indexOf(value);\n\t\tif(p !== -1) {\n\t\t\tfields.splice(p,1);\n\t\t\tfields.unshift(value)\n\t\t}\n\t});\n\t// Output the column headings\n\tvar output = [], row = [];\n\tfields.forEach(function(value) {\n\t\trow.push(quoteAndEscape(value))\n\t});\n\toutput.push(row.join(\",\"));\n\t// Output each tiddler\n\tfor(var t=0;t<tiddlers.length; t++) {\n\t\trow = [];\n\t\ttiddler = this.wiki.getTiddler(tiddlers[t]);\n\t\t\tif(tiddler) {\n\t\t\t\tfor(f=0; f<fields.length; f++) {\n\t\t\t\t\trow.push(quoteAndEscape(tiddler ? tiddler.getFieldString(fields[f]) || \"\" : \"\"));\n\t\t\t\t}\t\n\t\t\t}\n\t\toutput.push(row.join(\",\"));\n\t}\n\treturn output.join(\"\\n\");\n};\n\nfunction quoteAndEscape(value) {\n\treturn \"\\\"\" + value.replace(/\"/mg,\"\\\"\\\"\") + \"\\\"\";\n}\n\n})();\n","type":"application/javascript","module-type":"macro"},"$:/core/modules/macros/displayshortcuts.js":{"title":"$:/core/modules/macros/displayshortcuts.js","text":"/*\\\ntitle: $:/core/modules/macros/displayshortcuts.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to display a list of keyboard shortcuts in human readable form. Notably, it resolves named shortcuts like `((bold))` to the underlying keystrokes.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"displayshortcuts\";\n\nexports.params = [\n\t{name: \"shortcuts\"},\n\t{name: \"prefix\"},\n\t{name: \"separator\"},\n\t{name: \"suffix\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(shortcuts,prefix,separator,suffix) {\n\tvar shortcutArray = $tw.keyboardManager.getPrintableShortcuts($tw.keyboardManager.parseKeyDescriptors(shortcuts,{\n\t\twiki: this.wiki\n\t}));\n\tif(shortcutArray.length > 0) {\n\t\tshortcutArray.sort(function(a,b) {\n\t\t    return a.toLowerCase().localeCompare(b.toLowerCase());\n\t\t})\n\t\treturn prefix + shortcutArray.join(separator) + suffix;\n\t} else {\n\t\treturn \"\";\n\t}\n};\n\n})();\n","type":"application/javascript","module-type":"macro"},"$:/core/modules/macros/jsontiddler.js":{"title":"$:/core/modules/macros/jsontiddler.js","text":"/*\\\ntitle: $:/core/modules/macros/jsontiddler.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to output a single tiddler to JSON\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"jsontiddler\";\n\nexports.params = [\n\t{name: \"title\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(title) {\n\ttitle = title || this.getVariable(\"currentTiddler\");\n\tvar tiddler = !!title && this.wiki.getTiddler(title),\n\t\tfields = new Object();\n\tif(tiddler) {\n\t\tfor(var field in tiddler.fields) {\n\t\t\tfields[field] = tiddler.getFieldString(field);\n\t\t}\n\t}\n\treturn JSON.stringify(fields,null,$tw.config.preferences.jsonSpaces);\n};\n\n})();\n","type":"application/javascript","module-type":"macro"},"$:/core/modules/macros/jsontiddlers.js":{"title":"$:/core/modules/macros/jsontiddlers.js","text":"/*\\\ntitle: $:/core/modules/macros/jsontiddlers.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to output tiddlers matching a filter to JSON\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"jsontiddlers\";\n\nexports.params = [\n\t{name: \"filter\"},\n\t{name: \"spaces\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(filter,spaces) {\n\treturn this.wiki.getTiddlersAsJson(filter,$tw.utils.parseInt(spaces));\n};\n\n})();\n","type":"application/javascript","module-type":"macro"},"$:/core/modules/macros/makedatauri.js":{"title":"$:/core/modules/macros/makedatauri.js","text":"/*\\\ntitle: $:/core/modules/macros/makedatauri.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to convert a string of text to a data URI\n\n<<makedatauri text:\"Text to be converted\" type:\"text/vnd.tiddlywiki\">>\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"makedatauri\";\n\nexports.params = [\n\t{name: \"text\"},\n\t{name: \"type\"},\n\t{name: \"_canonical_uri\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(text,type,_canonical_uri) {\n\treturn $tw.utils.makeDataUri(text,type,_canonical_uri);\n};\n\n})();\n","type":"application/javascript","module-type":"macro"},"$:/core/modules/macros/now.js":{"title":"$:/core/modules/macros/now.js","text":"/*\\\ntitle: $:/core/modules/macros/now.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to return a formatted version of the current time\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"now\";\n\nexports.params = [\n\t{name: \"format\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(format) {\n\treturn $tw.utils.formatDateString(new Date(),format || \"0hh:0mm, DDth MMM YYYY\");\n};\n\n})();\n","type":"application/javascript","module-type":"macro"},"$:/core/modules/macros/qualify.js":{"title":"$:/core/modules/macros/qualify.js","text":"/*\\\ntitle: $:/core/modules/macros/qualify.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to qualify a state tiddler title according\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"qualify\";\n\nexports.params = [\n\t{name: \"title\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(title) {\n\treturn title + \"-\" + this.getStateQualifier();\n};\n\n})();\n","type":"application/javascript","module-type":"macro"},"$:/core/modules/macros/resolvepath.js":{"title":"$:/core/modules/macros/resolvepath.js","text":"/*\\\ntitle: $:/core/modules/macros/resolvepath.js\ntype: application/javascript\nmodule-type: macro\n\nResolves a relative path for an absolute rootpath.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"resolvepath\";\n\nexports.params = [\n\t{name: \"source\"},\n\t{name: \"root\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(source, root) {\n\treturn $tw.utils.resolvePath(source, root);\n};\n\n})();\n","type":"application/javascript","module-type":"macro"},"$:/core/modules/macros/unusedtitle.js":{"title":"$:/core/modules/macros/unusedtitle.js","text":"/*\\\ntitle: $:/core/modules/macros/unusedtitle.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to return a new title that is unused in the wiki. It can be given a name as a base.\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"unusedtitle\";\n\nexports.params = [\n\t{name: \"baseName\"},\n\t{name: \"separator\"},\n\t{name: \"template\"},\n\t{name: \"startCount\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(baseName,separator,template,startCount) {\n\tseparator = separator || \" \";\n\tstartCount = startCount || 0;\n\tif(!baseName) {\n\t\tbaseName = $tw.language.getString(\"DefaultNewTiddlerTitle\");\n\t}\n\t// $tw.wiki.generateNewTitle = function(baseTitle,options)\n\t// options.prefix must be a string!\n\treturn this.wiki.generateNewTitle(baseName, {\"prefix\": separator, \"template\": template, \"startCount\": startCount});\n};\n\n})();\n","type":"application/javascript","module-type":"macro"},"$:/core/modules/macros/version.js":{"title":"$:/core/modules/macros/version.js","text":"/*\\\ntitle: $:/core/modules/macros/version.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to return the TiddlyWiki core version number\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"version\";\n\nexports.params = [];\n\n/*\nRun the macro\n*/\nexports.run = function() {\n\treturn $tw.version;\n};\n\n})();\n","type":"application/javascript","module-type":"macro"},"$:/core/modules/parsers/audioparser.js":{"title":"$:/core/modules/parsers/audioparser.js","text":"/*\\\ntitle: $:/core/modules/parsers/audioparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe audio parser parses an audio tiddler into an embeddable HTML element\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar AudioParser = function(type,text,options) {\n\tvar element = {\n\t\t\ttype: \"element\",\n\t\t\ttag: \"audio\",\n\t\t\tattributes: {\n\t\t\t\tcontrols: {type: \"string\", value: \"controls\"},\n\t\t\t\tstyle: {type: \"string\", value: \"width: 100%; object-fit: contain\"}\n\t\t\t}\n\t\t},\n\t\tsrc;\n\tif(options._canonical_uri) {\n\t\telement.attributes.src = {type: \"string\", value: options._canonical_uri};\n\t} else if(text) {\n\t\telement.attributes.src = {type: \"string\", value: \"data:\" + type + \";base64,\" + text};\n\t}\n\tthis.tree = [element];\n\tthis.source = text;\n\tthis.type = type;\n};\n\nexports[\"audio/ogg\"] = AudioParser;\nexports[\"audio/mpeg\"] = AudioParser;\nexports[\"audio/mp3\"] = AudioParser;\nexports[\"audio/mp4\"] = AudioParser;\n\n})();\n\n","type":"application/javascript","module-type":"parser"},"$:/core/modules/parsers/binaryparser.js":{"title":"$:/core/modules/parsers/binaryparser.js","text":"/*\\\ntitle: $:/core/modules/parsers/binaryparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe binary parser parses a binary tiddler into a warning message and download link\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar BINARY_WARNING_MESSAGE = \"$:/core/ui/BinaryWarning\";\nvar EXPORT_BUTTON_IMAGE = \"$:/core/images/export-button\";\n\nvar BinaryParser = function(type,text,options) {\n\t// Transclude the binary data tiddler warning message\n\tvar warn = {\n\t\ttype: \"element\",\n\t\ttag: \"p\",\n\t\tchildren: [{\n\t\t\ttype: \"transclude\",\n\t\t\tattributes: {\n\t\t\t\t\"$tiddler\": {type: \"string\", value: BINARY_WARNING_MESSAGE}\n\t\t\t}\n\t\t}]\n\t};\n\t// Create download link based on binary tiddler title\n\tvar link = {\n\t\ttype: \"element\",\n\t\ttag: \"a\",\n\t\tattributes: {\n\t\t\ttitle: {type: \"indirect\", textReference: \"!!title\"},\n\t\t\tdownload: {type: \"indirect\", textReference: \"!!title\"}\n\t\t},\n\t\tchildren: [{\n\t\t\ttype: \"transclude\",\n\t\t\tattributes: {\n\t\t\t\t\"$tiddler\": {type: \"string\", value: EXPORT_BUTTON_IMAGE}\n\t\t\t}\n\t\t}]\n\t};\n\t// Set the link href to external or internal data URI\n\tif(options._canonical_uri) {\n\t\tlink.attributes.href = {\n\t\t\ttype: \"string\", \n\t\t\tvalue: options._canonical_uri\n\t\t};\n\t} else if(text) {\n\t\tlink.attributes.href = {\n\t\t\ttype: \"string\", \n\t\t\tvalue: \"data:\" + type + \";base64,\" + text\n\t\t};\n\t}\n\t// Combine warning message and download link in a div\n\tvar element = {\n\t\ttype: \"element\",\n\t\ttag: \"div\",\n\t\tattributes: {\n\t\t\tclass: {type: \"string\", value: \"tc-binary-warning\"}\n\t\t},\n\t\tchildren: [warn, link]\n\t}\n\tthis.tree = [element];\n\tthis.source = text;\n\tthis.type = type;\n};\n\nexports[\"application/octet-stream\"] = BinaryParser;\n\n})();\n\n","type":"application/javascript","module-type":"parser"},"$:/core/modules/parsers/csvparser.js":{"title":"$:/core/modules/parsers/csvparser.js","text":"/*\\\ntitle: $:/core/modules/parsers/csvparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe CSV text parser processes CSV files into a table wrapped in a scrollable widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar CsvParser = function(type,text,options) {\n\t// Special handler for tab-delimited files\n\tif (type === 'text/tab-delimited-values' && !options.separator) {\n\t\toptions.separator = \"\\t\";\n\t}\n\t\n\t// Table framework\n\tthis.tree = [{\n\t\t\"type\": \"scrollable\", \"children\": [{\n\t\t\t\"type\": \"element\", \"tag\": \"table\", \"children\": [{\n\t\t\t\t\"type\": \"element\", \"tag\": \"tbody\", \"children\": []\n\t\t\t}], \"attributes\": {\n\t\t\t\t\"class\": {\"type\": \"string\", \"value\": \"tc-csv-table\"}\n\t\t\t}\n\t\t}]\n\t}];\n\t// Split the text into lines\n\tvar lines = $tw.utils.parseCsvString(text, options),\n\t\ttag = \"th\";\n\tvar maxColumns = 0;\n\t$tw.utils.each(lines, function(columns) {\n\t\tmaxColumns = Math.max(columns.length, maxColumns);\n\t});\n\t\n\tfor(var line=0; line<lines.length; line++) {\n\t\tvar columns = lines[line];\n\t\tvar row = {\n\t\t\t\"type\": \"element\", \"tag\": \"tr\", \"children\": []\n\t\t};\n\t\tfor(var column=0; column<maxColumns; column++) {\n\t\t\trow.children.push({\n\t\t\t\t\"type\": \"element\", \"tag\": tag, \"children\": [{\n\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\"text\": columns[column] || ''\n\t\t\t\t}]\n\t\t\t});\n\t\t}\n\t\ttag = \"td\";\n\t\tthis.tree[0].children[0].children[0].children.push(row);\n\t}\n\tthis.source = text;\n\tthis.type = type;\n};\n\nexports[\"text/csv\"] = CsvParser;\nexports[\"text/tab-delimited-values\"] = CsvParser;\n\n})();\n\n","type":"application/javascript","module-type":"parser"},"$:/core/modules/parsers/htmlparser.js":{"title":"$:/core/modules/parsers/htmlparser.js","text":"/*\\\ntitle: $:/core/modules/parsers/htmlparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe HTML parser displays text as raw HTML\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar HtmlParser = function(type,text,options) {\n\tvar src;\n\tif(options._canonical_uri) {\n\t\tsrc = options._canonical_uri;\n\t} else if(text) {\n\t\tsrc = \"data:text/html;charset=utf-8,\" + encodeURIComponent(text);\n\t}\n\tthis.tree = [{\n\t\ttype: \"element\",\n\t\ttag: \"iframe\",\n\t\tattributes: {\n\t\t\tsrc: {type: \"string\", value: src}\n\t\t}\n\t}];\n\tif($tw.wiki.getTiddlerText(\"$:/config/HtmlParser/DisableSandbox\",\"no\") !== \"yes\") {\n\t\tthis.tree[0].attributes.sandbox = {type: \"string\", value: $tw.wiki.getTiddlerText(\"$:/config/HtmlParser/SandboxTokens\",\"\")};\n\t}\n\tthis.source = text;\n\tthis.type = type;\n};\n\nexports[\"text/html\"] = HtmlParser;\n\n})();\n\n","type":"application/javascript","module-type":"parser"},"$:/core/modules/parsers/imageparser.js":{"title":"$:/core/modules/parsers/imageparser.js","text":"/*\\\ntitle: $:/core/modules/parsers/imageparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe image parser parses an image into an embeddable HTML element\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar ImageParser = function(type,text,options) {\n\tvar element = {\n\t\t\ttype: \"element\",\n\t\t\ttag: \"img\",\n\t\t\tattributes: {}\n\t\t};\n\tif(options._canonical_uri) {\n\t\telement.attributes.src = {type: \"string\", value: options._canonical_uri};\n\t} else if(text) {\n\t\tif(type === \"image/svg+xml\" || type === \".svg\") {\n\t\t\telement.attributes.src = {type: \"string\", value: \"data:image/svg+xml,\" + encodeURIComponent(text)};\n\t\t} else {\n\t\t\telement.attributes.src = {type: \"string\", value: \"data:\" + type + \";base64,\" + text};\n\t\t}\n\t}\n\tthis.tree = [element];\n\tthis.source = text;\n\tthis.type = type;\n};\n\nexports[\"image/svg+xml\"] = ImageParser;\nexports[\"image/jpg\"] = ImageParser;\nexports[\"image/jpeg\"] = ImageParser;\nexports[\"image/png\"] = ImageParser;\nexports[\"image/gif\"] = ImageParser;\nexports[\"image/webp\"] = ImageParser;\nexports[\"image/heic\"] = ImageParser;\nexports[\"image/heif\"] = ImageParser;\nexports[\"image/x-icon\"] = ImageParser;\nexports[\"image/vnd.microsoft.icon\"] = ImageParser;\n\n})();\n\n","type":"application/javascript","module-type":"parser"},"$:/core/modules/utils/parseutils.js":{"title":"$:/core/modules/utils/parseutils.js","text":"/*\\\ntitle: $:/core/modules/utils/parseutils.js\ntype: application/javascript\nmodule-type: utils\n\nUtility functions concerned with parsing text into tokens.\n\nMost functions have the following pattern:\n\n* The parameters are:\n** `source`: the source string being parsed\n** `pos`: the current parse position within the string\n** Any further parameters are used to identify the token that is being parsed\n* The return value is:\n** null if the token was not found at the specified position\n** an object representing the token with the following standard fields:\n*** `type`: string indicating the type of the token\n*** `start`: start position of the token in the source string\n*** `end`: end position of the token in the source string\n*** Any further fields required to describe the token\n\nThe exception is `skipWhiteSpace`, which just returns the position after the whitespace.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nLook for a whitespace token. Returns null if not found, otherwise returns {type: \"whitespace\", start:, end:,}\n*/\nexports.parseWhiteSpace = function(source,pos) {\n\tvar p = pos,c;\n\twhile(true) {\n\t\tc = source.charAt(p);\n\t\tif((c === \" \") || (c === \"\\f\") || (c === \"\\n\") || (c === \"\\r\") || (c === \"\\t\") || (c === \"\\v\") || (c === \"\\u00a0\")) { // Ignores some obscure unicode spaces\n\t\t\tp++;\n\t\t} else {\n\t\t\tbreak;\n\t\t}\n\t}\n\tif(p === pos) {\n\t\treturn null;\n\t} else {\n\t\treturn {\n\t\t\ttype: \"whitespace\",\n\t\t\tstart: pos,\n\t\t\tend: p\n\t\t}\n\t}\n};\n\n/*\nConvenience wrapper for parseWhiteSpace. Returns the position after the whitespace\n*/\nexports.skipWhiteSpace = function(source,pos) {\n\tvar c;\n\twhile(true) {\n\t\tc = source.charAt(pos);\n\t\tif((c === \" \") || (c === \"\\f\") || (c === \"\\n\") || (c === \"\\r\") || (c === \"\\t\") || (c === \"\\v\") || (c === \"\\u00a0\")) { // Ignores some obscure unicode spaces\n\t\t\tpos++;\n\t\t} else {\n\t\t\treturn pos;\n\t\t}\n\t}\n};\n\n/*\nLook for a given string token. Returns null if not found, otherwise returns {type: \"token\", value:, start:, end:,}\n*/\nexports.parseTokenString = function(source,pos,token) {\n\tvar match = source.indexOf(token,pos) === pos;\n\tif(match) {\n\t\treturn {\n\t\t\ttype: \"token\",\n\t\t\tvalue: token,\n\t\t\tstart: pos,\n\t\t\tend: pos + token.length\n\t\t};\n\t}\n\treturn null;\n};\n\n/*\nLook for a token matching a regex. Returns null if not found, otherwise returns {type: \"regexp\", match:, start:, end:,}\n*/\nexports.parseTokenRegExp = function(source,pos,reToken) {\n\tvar node = {\n\t\ttype: \"regexp\",\n\t\tstart: pos\n\t};\n\treToken.lastIndex = pos;\n\tnode.match = reToken.exec(source);\n\tif(node.match && node.match.index === pos) {\n\t\tnode.end = pos + node.match[0].length;\n\t\treturn node;\n\t} else {\n\t\treturn null;\n\t}\n};\n\n/*\nLook for a string literal. Returns null if not found, otherwise returns {type: \"string\", value:, start:, end:,}\n*/\nexports.parseStringLiteral = function(source,pos) {\n\tvar node = {\n\t\ttype: \"string\",\n\t\tstart: pos\n\t};\n\tvar reString = /(?:\"\"\"([\\s\\S]*?)\"\"\"|\"([^\"]*)\")|(?:'([^']*)')/g;\n\treString.lastIndex = pos;\n\tvar match = reString.exec(source);\n\tif(match && match.index === pos) {\n\t\tnode.value = match[1] !== undefined ? match[1] :(\n\t\t\tmatch[2] !== undefined ? match[2] : match[3]\n\t\t\t\t\t);\n\t\tnode.end = pos + match[0].length;\n\t\treturn node;\n\t} else {\n\t\treturn null;\n\t}\n};\n\n/*\nReturns an array of {name:} with an optional \"default\" property. Options include:\nrequireParenthesis: require the parameter definition to be wrapped in parenthesis\n*/\nexports.parseParameterDefinition = function(paramString,options) {\n\toptions = options || {};\n\tif(options.requireParenthesis) {\n\t\tvar parenMatch = /^\\s*\\((.*)\\)\\s*$/g.exec(paramString);\n\t\tif(!parenMatch) {\n\t\t\treturn [];\n\t\t}\n\t\tparamString = parenMatch[1];\n\t}\n\tvar params = [],\n\t\treParam = /\\s*([^:),\\s]+)(?:\\s*:\\s*(?:\"\"\"([\\s\\S]*?)\"\"\"|\"([^\"]*)\"|'([^']*)'|([^,\"'\\s]+)))?/mg,\n\t\tparamMatch = reParam.exec(paramString);\n\twhile(paramMatch) {\n\t\t// Save the parameter details\n\t\tvar paramInfo = {name: paramMatch[1]},\n\t\t\tdefaultValue = paramMatch[2] || paramMatch[3] || paramMatch[4] || paramMatch[5];\n\t\tif(defaultValue !== undefined) {\n\t\t\tparamInfo[\"default\"] = defaultValue;\n\t\t}\n\t\tparams.push(paramInfo);\n\t\t// Look for the next parameter\n\t\tparamMatch = reParam.exec(paramString);\n\t}\n\treturn params;\n};\n\nexports.parseMacroParameters = function(node,source,pos) {\n\t// Process parameters\n\tvar parameter = $tw.utils.parseMacroParameter(source,pos);\n\twhile(parameter) {\n\t\tnode.params.push(parameter);\n\t\tpos = parameter.end;\n\t\t// Get the next parameter\n\t\tparameter = $tw.utils.parseMacroParameter(source,pos);\n\t}\n\tnode.end = pos;\n\treturn node;\n}\n\n/*\nLook for a macro invocation parameter. Returns null if not found, or {type: \"macro-parameter\", name:, value:, start:, end:}\n*/\nexports.parseMacroParameter = function(source,pos) {\n\tvar node = {\n\t\ttype: \"macro-parameter\",\n\t\tstart: pos\n\t};\n\t// Define our regexp\n\tvar reMacroParameter = /(?:([A-Za-z0-9\\-_]+)\\s*:)?(?:\\s*(?:\"\"\"([\\s\\S]*?)\"\"\"|\"([^\"]*)\"|'([^']*)'|\\[\\[([^\\]]*)\\]\\]|((?:(?:>(?!>))|[^\\s>\"'])+)))/g;\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for the parameter\n\tvar token = $tw.utils.parseTokenRegExp(source,pos,reMacroParameter);\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Get the parameter details\n\tnode.value = token.match[2] !== undefined ? token.match[2] : (\n\t\t\t\t\ttoken.match[3] !== undefined ? token.match[3] : (\n\t\t\t\t\t\ttoken.match[4] !== undefined ? token.match[4] : (\n\t\t\t\t\t\t\ttoken.match[5] !== undefined ? token.match[5] : (\n\t\t\t\t\t\t\t\ttoken.match[6] !== undefined ? token.match[6] : (\n\t\t\t\t\t\t\t\t\t\"\"\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t);\n\tif(token.match[1]) {\n\t\tnode.name = token.match[1];\n\t}\n\t// Update the end position\n\tnode.end = pos;\n\treturn node;\n};\n\n/*\nLook for a macro invocation. Returns null if not found, or {type: \"transclude\", attributes:, start:, end:}\n*/\nexports.parseMacroInvocationAsTransclusion = function(source,pos) {\n\tvar node = $tw.utils.parseMacroInvocation(source,pos);\n\tif(node) {\n\t\tvar positionalName = 0,\n\t\t\ttransclusion = {\n\t\t\t\ttype: \"transclude\",\n\t\t\t\tstart: node.start,\n\t\t\t\tend: node.end\n\t\t\t};\n\t\t$tw.utils.addAttributeToParseTreeNode(transclusion,\"$variable\",node.name);\n\t\t$tw.utils.each(node.params,function(param) {\n\t\t\tvar name = param.name;\n\t\t\tif(name) {\n\t\t\t\tif(name.charAt(0) === \"$\") {\n\t\t\t\t\tname = \"$\" + name;\n\t\t\t\t}\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(transclusion,{name: name,type: \"string\", value: param.value, start: param.start, end: param.end});\n\t\t\t} else {\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(transclusion,{name: (positionalName++) + \"\",type: \"string\", value: param.value, start: param.start, end: param.end});\n\t\t\t}\n\t\t});\n\t\treturn transclusion;\n\t}\n\treturn node;\n};\n\n/*\nLook for a macro invocation. Returns null if not found, or {type: \"macrocall\", name:, params:, start:, end:}\n*/\nexports.parseMacroInvocation = function(source,pos) {\n\tvar node = {\n\t\ttype: \"macrocall\",\n\t\tstart: pos,\n\t\tparams: []\n\t};\n\t// Define our regexps\n\tvar reMacroName = /([^\\s>\"'=]+)/g;\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for a double less than sign\n\tvar token = $tw.utils.parseTokenString(source,pos,\"<<\");\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Get the macro name\n\tvar name = $tw.utils.parseTokenRegExp(source,pos,reMacroName);\n\tif(!name) {\n\t\treturn null;\n\t}\n\tnode.name = name.match[1];\n\tpos = name.end;\n\tnode = $tw.utils.parseMacroParameters(node,source,pos);\n\tpos = node.end;\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for a double greater than sign\n\ttoken = $tw.utils.parseTokenString(source,pos,\">>\");\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Update the end position\n\tnode.end = pos;\n\treturn node;\n};\n\nexports.parseFilterVariable = function(source) {\n\tvar node = {\n\t\t\tname: \"\",\n\t\t\tparams: [],\n\t\t},\n\t\tpos = 0,\n\t\treName = /([^\\s\"']+)/g;\n\t// If there is no whitespace or it is an empty string then there are no macro parameters\n\tif(/^\\S*$/.test(source)) {\n\t\tnode.name = source;\n\t\treturn node;\n\t}\n\t// Get the variable name\n\tvar nameMatch = $tw.utils.parseTokenRegExp(source,pos,reName);\n\tif(nameMatch) {\n\t\tnode.name = nameMatch.match[1];\n\t\tpos = nameMatch.end;\n\t\tnode = $tw.utils.parseMacroParameters(node,source,pos);\n\t\tdelete node.end;\n\t}\n\treturn node;\n};\n\n/*\nLook for an HTML attribute definition. Returns null if not found, otherwise returns {type: \"attribute\", name:, type: \"filtered|string|indirect|macro\", value|filter|textReference:, start:, end:,}\n*/\nexports.parseAttribute = function(source,pos) {\n\tvar node = {\n\t\tstart: pos\n\t};\n\t// Define our regexps\n\tvar reAttributeName = /([^\\/\\s>\"'`=]+)/g,\n\t\treUnquotedAttribute = /([^\\/\\s<>\"'`=]+)/g,\n\t\treFilteredValue = /\\{\\{\\{([\\S\\s]+?)\\}\\}\\}/g,\n\t\treIndirectValue = /\\{\\{([^\\}]+)\\}\\}/g,\n\t\treSubstitutedValue = /(?:```([\\s\\S]*?)```|`([^`]|[\\S\\s]*?)`)/g;\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Get the attribute name\n\tvar name = $tw.utils.parseTokenRegExp(source,pos,reAttributeName);\n\tif(!name) {\n\t\treturn null;\n\t}\n\tnode.name = name.match[1];\n\tpos = name.end;\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for an equals sign\n\tvar token = $tw.utils.parseTokenString(source,pos,\"=\");\n\tif(token) {\n\t\tpos = token.end;\n\t\t// Skip whitespace\n\t\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t\t// Look for a string literal\n\t\tvar stringLiteral = $tw.utils.parseStringLiteral(source,pos);\n\t\tif(stringLiteral) {\n\t\t\tpos = stringLiteral.end;\n\t\t\tnode.type = \"string\";\n\t\t\tnode.value = stringLiteral.value;\n\t\t} else {\n\t\t\t// Look for a filtered value\n\t\t\tvar filteredValue = $tw.utils.parseTokenRegExp(source,pos,reFilteredValue);\n\t\t\tif(filteredValue) {\n\t\t\t\tpos = filteredValue.end;\n\t\t\t\tnode.type = \"filtered\";\n\t\t\t\tnode.filter = filteredValue.match[1];\n\t\t\t} else {\n\t\t\t\t// Look for an indirect value\n\t\t\t\tvar indirectValue = $tw.utils.parseTokenRegExp(source,pos,reIndirectValue);\n\t\t\t\tif(indirectValue) {\n\t\t\t\t\tpos = indirectValue.end;\n\t\t\t\t\tnode.type = \"indirect\";\n\t\t\t\t\tnode.textReference = indirectValue.match[1];\n\t\t\t\t} else {\n\t\t\t\t\t// Look for a unquoted value\n\t\t\t\t\tvar unquotedValue = $tw.utils.parseTokenRegExp(source,pos,reUnquotedAttribute);\n\t\t\t\t\tif(unquotedValue) {\n\t\t\t\t\t\tpos = unquotedValue.end;\n\t\t\t\t\t\tnode.type = \"string\";\n\t\t\t\t\t\tnode.value = unquotedValue.match[1];\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Look for a macro invocation value\n\t\t\t\t\t\tvar macroInvocation = $tw.utils.parseMacroInvocation(source,pos);\n\t\t\t\t\t\tif(macroInvocation) {\n\t\t\t\t\t\t\tpos = macroInvocation.end;\n\t\t\t\t\t\t\tnode.type = \"macro\";\n\t\t\t\t\t\t\tnode.value = macroInvocation;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tvar substitutedValue = $tw.utils.parseTokenRegExp(source,pos,reSubstitutedValue);\n\t\t\t\t\t\t\tif(substitutedValue) {\n\t\t\t\t\t\t\t\tpos = substitutedValue.end;\n\t\t\t\t\t\t\t\tnode.type = \"substituted\";\n\t\t\t\t\t\t\t\tnode.rawValue = substitutedValue.match[1] || substitutedValue.match[2];\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tnode.type = \"string\";\n\t\t\t\t\t\t\t\tnode.value = \"true\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\tnode.type = \"string\";\n\t\tnode.value = \"true\";\n\t}\n\t// Update the end position\n\tnode.end = pos;\n\treturn node;\n};\n\n})();\n","type":"application/javascript","module-type":"utils"},"$:/core/modules/parsers/pdfparser.js":{"title":"$:/core/modules/parsers/pdfparser.js","text":"/*\\\ntitle: $:/core/modules/parsers/pdfparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe PDF parser embeds a PDF viewer\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar ImageParser = function(type,text,options) {\n\tvar element = {\n\t\t\ttype: \"element\",\n\t\t\ttag: \"iframe\",\n\t\t\tattributes: {}\n\t\t},\n\t\tsrc;\n\tif(options._canonical_uri) {\n\t\telement.attributes.src = {type: \"string\", value: options._canonical_uri};\n\t} else if(text) {\n\t\telement.attributes.src = {type: \"string\", value: \"data:application/pdf;base64,\" + text};\n\t}\n\tthis.tree = [element];\n\tthis.source = text;\n\tthis.type = type;\n};\n\nexports[\"application/pdf\"] = ImageParser;\n\n})();\n\n","type":"application/javascript","module-type":"parser"},"$:/core/modules/parsers/textparser.js":{"title":"$:/core/modules/parsers/textparser.js","text":"/*\\\ntitle: $:/core/modules/parsers/textparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe plain text parser processes blocks of source text into a degenerate parse tree consisting of a single text node\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar TextParser = function(type,text,options) {\n\tthis.tree = [{\n\t\ttype: \"genesis\",\n\t\tattributes: {\n\t\t\t$type: {name: \"$type\", type: \"string\", value: \"$codeblock\"},\n\t\t\tcode: {name: \"code\", type: \"string\", value: text},\n\t\t\tlanguage: {name: \"language\", type: \"string\", value: type},\n\t\t\t$remappable: {name: \"$remappable\", type:\"string\", value: \"no\"}\n\t\t}\n\t}];\n\tthis.source = text;\n\tthis.type = type;\n};\n\nexports[\"text/plain\"] = TextParser;\nexports[\"text/x-tiddlywiki\"] = TextParser;\nexports[\"application/javascript\"] = TextParser;\nexports[\"application/json\"] = TextParser;\nexports[\"text/css\"] = TextParser;\nexports[\"application/x-tiddler-dictionary\"] = TextParser;\n\n})();\n","type":"application/javascript","module-type":"parser"},"$:/core/modules/parsers/videoparser.js":{"title":"$:/core/modules/parsers/videoparser.js","text":"/*\\\ntitle: $:/core/modules/parsers/videoparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe video parser parses a video tiddler into an embeddable HTML element\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar VideoParser = function(type,text,options) {\n\tvar element = {\n\t\t\ttype: \"element\",\n\t\t\ttag: \"video\",\n\t\t\tattributes: {\n\t\t\t\tcontrols: {type: \"string\", value: \"controls\"},\n\t\t\t\tstyle: {type: \"string\", value: \"width: 100%; object-fit: contain\"}\n\t\t\t}\n\t\t},\n\t\tsrc;\n\tif(options._canonical_uri) {\n\t\telement.attributes.src = {type: \"string\", value: options._canonical_uri};\n\t} else if(text) {\n\t\telement.attributes.src = {type: \"string\", value: \"data:\" + type + \";base64,\" + text};\n\t}\n\tthis.tree = [element];\n\tthis.source = text;\n\tthis.type = type;\n};\n\nexports[\"video/ogg\"] = VideoParser;\nexports[\"video/webm\"] = VideoParser;\nexports[\"video/mp4\"] = VideoParser;\nexports[\"video/quicktime\"] = VideoParser;\n\n})();\n","type":"application/javascript","module-type":"parser"},"$:/core/modules/parsers/wikiparser/rules/codeblock.js":{"title":"$:/core/modules/parsers/wikiparser/rules/codeblock.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/codeblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text rule for code blocks. For example:\n\n```\n\t```\n\tThis text will not be //wikified//\n\t```\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"codeblock\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match and get language if defined\n\tthis.matchRegExp = /```([\\w-]*)\\r?\\n/mg;\n};\n\nexports.parse = function() {\n\tvar reEnd = /(\\r?\\n```$)/mg;\n\tvar languageStart = this.parser.pos + 3,\n\t\tlanguageEnd = languageStart + this.match[1].length;\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\n\t// Look for the end of the block\n\treEnd.lastIndex = this.parser.pos;\n\tvar match = reEnd.exec(this.parser.source),\n\t\ttext,\n\t\tcodeStart = this.parser.pos;\n\t// Process the block\n\tif(match) {\n\t\ttext = this.parser.source.substring(this.parser.pos,match.index);\n\t\tthis.parser.pos = match.index + match[0].length;\n\t} else {\n\t\ttext = this.parser.source.substr(this.parser.pos);\n\t\tthis.parser.pos = this.parser.sourceLength;\n\t}\n\t// Return the $codeblock widget\n\treturn [{\n\t\t\ttype: \"codeblock\",\n\t\t\tattributes: {\n\t\t\t\t\tcode: {type: \"string\", value: text, start: codeStart, end: this.parser.pos},\n\t\t\t\t\tlanguage: {type: \"string\", value: this.match[1], start: languageStart, end: languageEnd}\n\t\t\t}\n\t}];\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/codeinline.js":{"title":"$:/core/modules/parsers/wikiparser/rules/codeinline.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/codeinline.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for code runs. For example:\n\n```\n\tThis is a `code run`.\n\tThis is another ``code run``\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"codeinline\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /(``?)/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\tvar reEnd = new RegExp(this.match[1], \"mg\");\n\t// Look for the end marker\n\treEnd.lastIndex = this.parser.pos;\n\tvar match = reEnd.exec(this.parser.source),\n\t\ttext,\n\t\tstart = this.parser.pos;\n\t// Process the text\n\tif(match) {\n\t\ttext = this.parser.source.substring(this.parser.pos,match.index);\n\t\tthis.parser.pos = match.index + match[0].length;\n\t} else {\n\t\ttext = this.parser.source.substr(this.parser.pos);\n\t\tthis.parser.pos = this.parser.sourceLength;\n\t}\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"code\",\n\t\tchildren: [{\n\t\t\ttype: \"text\",\n\t\t\ttext: text,\n\t\t\tstart: start,\n\t\t\tend: this.parser.pos\n\t\t}]\n\t}];\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/commentblock.js":{"title":"$:/core/modules/parsers/wikiparser/rules/commentblock.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/commentblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text block rule for HTML comments. For example:\n\n```\n<!-- This is a comment -->\n\\define macroX()\n<!-- This is a comment -->\nxxxx\n\\end\n<!-- This is a comment -->\n\n```\n\nNote that the syntax for comments is simplified to an opening \"<!--\" sequence and a closing \"-->\" sequence -- HTML itself implements a more complex format (see http://ostermiller.org/findhtmlcomment.html)\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"commentblock\";\nexports.types = {block:true, pragma:true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\tthis.matchRegExp = /<!--/mg;\n\tthis.endMatchRegExp = /-->/mg;\n};\n\nexports.findNextMatch = function(startPos) {\n\tthis.matchRegExp.lastIndex = startPos;\n\tthis.match = this.matchRegExp.exec(this.parser.source);\n\tif(this.match) {\n\t\tthis.endMatchRegExp.lastIndex = this.match.index + this.match[0].length;\n\t\tthis.endMatch = this.endMatchRegExp.exec(this.parser.source);\n\t\tif(this.endMatch) {\n\t\t\treturn this.match.index;\n\t\t}\n\t}\n\treturn undefined;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.endMatchRegExp.lastIndex;\n\t// Don't return any elements\n\treturn [];\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/commentinline.js":{"title":"$:/core/modules/parsers/wikiparser/rules/commentinline.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/commentinline.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for HTML comments. For example:\n\n```\n<!-- This is a comment -->\n```\n\nNote that the syntax for comments is simplified to an opening \"<!--\" sequence and a closing \"-->\" sequence -- HTML itself implements a more complex format (see http://ostermiller.org/findhtmlcomment.html)\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"commentinline\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\tthis.matchRegExp = /<!--/mg;\n\tthis.endMatchRegExp = /-->/mg;\n};\n\nexports.findNextMatch = function(startPos) {\n\tthis.matchRegExp.lastIndex = startPos;\n\tthis.match = this.matchRegExp.exec(this.parser.source);\n\tif(this.match) {\n\t\tthis.endMatchRegExp.lastIndex = this.match.index + this.match[0].length;\n\t\tthis.endMatch = this.endMatchRegExp.exec(this.parser.source);\n\t\tif(this.endMatch) {\n\t\t\treturn this.match.index;\n\t\t}\n\t}\n\treturn undefined;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.endMatchRegExp.lastIndex;\n\t// Don't return any elements\n\treturn [];\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/conditional.js":{"title":"$:/core/modules/parsers/wikiparser/rules/conditional.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/conditional.js\ntype: application/javascript\nmodule-type: wikirule\n\nConditional shortcut syntax\n\n```\nThis is a <%if [{something}] %>Elephant<%elseif [{else}] %>Pelican<%else%>Crocodile<%endif%>\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"conditional\";\nexports.types = {inline: true, block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\<\\%\\s*if\\s+/mg;\n\tthis.terminateIfRegExp = /\\%\\>/mg;\n};\n\nexports.findNextMatch = function(startPos) {\n\t// Look for the next <%if shortcut\n\tthis.matchRegExp.lastIndex = startPos;\n\tthis.match = this.matchRegExp.exec(this.parser.source);\n\t// If not found then return no match\n\tif(!this.match) {\n\t\treturn undefined;\n\t}\n\t// Check for the next %>\n\tthis.terminateIfRegExp.lastIndex = this.match.index;\n\tthis.terminateIfMatch = this.terminateIfRegExp.exec(this.parser.source);\n\t// If not found then return no match\n\tif(!this.terminateIfMatch) {\n\t\treturn undefined;\n\t}\n\t// Return the position at which the construction was found\n\treturn this.match.index;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Get the filter condition\n\tvar filterCondition = this.parser.source.substring(this.match.index + this.match[0].length,this.terminateIfMatch.index);\n\t// Advance the parser position to past the %>\n\tthis.parser.pos = this.terminateIfMatch.index + this.terminateIfMatch[0].length;\n\t// Parse the if clause\n\treturn this.parseIfClause(filterCondition);\n};\n\nexports.parseIfClause = function(filterCondition) {\n\t// Create the list widget\n\tvar listWidget = {\n\t\ttype: \"list\",\n\t\ttag: \"$list\",\n\t\tisBlock: this.is.block,\n\t\tchildren: [\n\t\t\t{\n\t\t\t\ttype: \"list-template\",\n\t\t\t\ttag: \"$list-template\"\n\t\t\t},\n\t\t\t{\n\t\t\t\ttype: \"list-empty\",\n\t\t\t\ttag: \"$list-empty\"\n\t\t\t}\n\t\t]\n\t};\n\t$tw.utils.addAttributeToParseTreeNode(listWidget,\"filter\",filterCondition);\n\t$tw.utils.addAttributeToParseTreeNode(listWidget,\"variable\",\"condition\");\n\t$tw.utils.addAttributeToParseTreeNode(listWidget,\"limit\",\"1\");\n\t// Check for an immediately following double linebreak\n\tvar hasLineBreak = !!$tw.utils.parseTokenRegExp(this.parser.source,this.parser.pos,/([^\\S\\n\\r]*\\r?\\n(?:[^\\S\\n\\r]*\\r?\\n|$))/g);\n\t// Parse the body looking for else or endif\n\tvar reEndString = \"\\\\<\\\\%\\\\s*(endif)\\\\s*\\\\%\\\\>|\\\\<\\\\%\\\\s*(else)\\\\s*\\\\%\\\\>|\\\\<\\\\%\\\\s*(elseif)\\\\s+([\\\\s\\\\S]+?)\\\\%\\\\>\",\n\t\tex;\n\tif(hasLineBreak) {\n\t\tex = this.parser.parseBlocksTerminatedExtended(reEndString);\n\t} else {\n\t\tvar reEnd = new RegExp(reEndString,\"mg\");\n\t\tex = this.parser.parseInlineRunTerminatedExtended(reEnd,{eatTerminator: true});\n\t}\n\t// Put the body into the list template\n\tlistWidget.children[0].children = ex.tree;\n\t// Check for an else or elseif\n\tif(ex.match) {\n\t\tif(ex.match[1] === \"endif\") {\n\t\t\t// Nothing to do if we just found an endif\n\t\t} else if(ex.match[2] === \"else\") {\n\t\t\t// Check for an immediately following double linebreak\n\t\t\thasLineBreak = !!$tw.utils.parseTokenRegExp(this.parser.source,this.parser.pos,/([^\\S\\n\\r]*\\r?\\n(?:[^\\S\\n\\r]*\\r?\\n|$))/g);\n\t\t\t// If we found an else then we need to parse the body looking for the endif\n\t\t\tvar reEndString = \"\\\\<\\\\%\\\\s*(endif)\\\\s*\\\\%\\\\>\",\n\t\t\tex;\n\t\t\tif(hasLineBreak) {\n\t\t\t\tex = this.parser.parseBlocksTerminatedExtended(reEndString);\n\t\t\t} else {\n\t\t\t\tvar reEnd = new RegExp(reEndString,\"mg\");\n\t\t\t\tex = this.parser.parseInlineRunTerminatedExtended(reEnd,{eatTerminator: true});\n\t\t\t}\n\t\t\t// Put the parsed content inside the list empty template\n\t\t\tlistWidget.children[1].children = ex.tree;\n\t\t} else if(ex.match[3] === \"elseif\") {\n\t\t\t// Parse the elseif clause by reusing this parser, passing the new filter condition\n\t\t\tlistWidget.children[1].children = this.parseIfClause(ex.match[4]);\n\t\t}\n\t}\n\t// Return the parse tree node\n\treturn [listWidget];\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/dash.js":{"title":"$:/core/modules/parsers/wikiparser/rules/dash.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/dash.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for dashes. For example:\n\n```\nThis is an en-dash: --\n\nThis is an em-dash: ---\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"dash\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /-{2,3}(?!-)/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\tvar dash = this.match[0].length === 2 ? \"&ndash;\" : \"&mdash;\";\n\treturn [{\n\t\ttype: \"entity\",\n\t\tentity: dash\n\t}];\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/emphasis/bold.js":{"title":"$:/core/modules/parsers/wikiparser/rules/emphasis/bold.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/emphasis/bold.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for emphasis - bold. For example:\n\n```\n\tThis is ''bold'' text\n```\n\nThis wikiparser can be modified using the rules eg:\n\n```\n\\rules except bold \n\\rules only bold \n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"bold\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /''/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\n\t// Parse the run including the terminator\n\tvar tree = this.parser.parseInlineRun(/''/mg,{eatTerminator: true});\n\n\t// Return the classed span\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"strong\",\n\t\tchildren: tree\n\t}];\n};\n\n})();","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/emphasis/italic.js":{"title":"$:/core/modules/parsers/wikiparser/rules/emphasis/italic.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/emphasis/italic.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for emphasis - italic. For example:\n\n```\n\tThis is //italic// text\n```\n\nThis wikiparser can be modified using the rules eg:\n\n```\n\\rules except italic\n\\rules only italic\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"italic\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\/\\//mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\n\t// Parse the run including the terminator\n\tvar tree = this.parser.parseInlineRun(/\\/\\//mg,{eatTerminator: true});\n\n\t// Return the classed span\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"em\",\n\t\tchildren: tree\n\t}];\n};\n\n})();","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/emphasis/strikethrough.js":{"title":"$:/core/modules/parsers/wikiparser/rules/emphasis/strikethrough.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/emphasis/strikethrough.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for emphasis - strikethrough. For example:\n\n```\n\tThis is ~~strikethrough~~ text\n```\n\nThis wikiparser can be modified using the rules eg:\n\n```\n\\rules except strikethrough \n\\rules only strikethrough \n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"strikethrough\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /~~/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\n\t// Parse the run including the terminator\n\tvar tree = this.parser.parseInlineRun(/~~/mg,{eatTerminator: true});\n\n\t// Return the classed span\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"strike\",\n\t\tchildren: tree\n\t}];\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/emphasis/subscript.js":{"title":"$:/core/modules/parsers/wikiparser/rules/emphasis/subscript.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/emphasis/subscript.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for emphasis - subscript. For example:\n\n```\n\tThis is ,,subscript,, text\n```\n\nThis wikiparser can be modified using the rules eg:\n\n```\n\\rules except subscript \n\\rules only subscript \n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"subscript\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /,,/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\n\t// Parse the run including the terminator\n\tvar tree = this.parser.parseInlineRun(/,,/mg,{eatTerminator: true});\n\n\t// Return the classed span\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"sub\",\n\t\tchildren: tree\n\t}];\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/emphasis/superscript.js":{"title":"$:/core/modules/parsers/wikiparser/rules/emphasis/superscript.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/emphasis/superscript.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for emphasis - superscript. For example:\n\n```\n\tThis is ^^superscript^^ text\n```\n\nThis wikiparser can be modified using the rules eg:\n\n```\n\\rules except superscript \n\\rules only superscript \n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"superscript\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\^\\^/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\n\t// Parse the run including the terminator\n\tvar tree = this.parser.parseInlineRun(/\\^\\^/mg,{eatTerminator: true});\n\n\t// Return the classed span\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"sup\",\n\t\tchildren: tree\n\t}];\n};\n\n})();","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/emphasis/underscore.js":{"title":"$:/core/modules/parsers/wikiparser/rules/emphasis/underscore.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/emphasis/underscore.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for emphasis - underscore. For example:\n\n```\n\tThis is __underscore__ text\n```\n\nThis wikiparser can be modified using the rules eg:\n\n```\n\\rules except underscore \n\\rules only underscore\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"underscore\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /__/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\n\t// Parse the run including the terminator\n\tvar tree = this.parser.parseInlineRun(/__/mg,{eatTerminator: true});\n\n\t// Return the classed span\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"u\",\n\t\tchildren: tree\n\t}];\n};\n\n})();","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/entity.js":{"title":"$:/core/modules/parsers/wikiparser/rules/entity.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/entity.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for HTML entities. For example:\n\n```\n\tThis is a copyright symbol: &copy;\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"entity\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /(&#?[a-zA-Z0-9]{2,8};)/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Get all the details of the match\n\tvar entityString = this.match[1];\n\t// Move past the macro call\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Return the entity\n\treturn [{type: \"entity\", entity: this.match[0]}];\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/extlink.js":{"title":"$:/core/modules/parsers/wikiparser/rules/extlink.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/extlink.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for external links. For example:\n\n```\nAn external link: https://www.tiddlywiki.com/\n\nA suppressed external link: ~http://www.tiddlyspace.com/\n```\n\nExternal links can be suppressed by preceding them with `~`.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"extlink\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /~?(?:file|http|https|mailto|ftp|irc|news|data|skype):[^\\s<>{}\\[\\]`|\"\\\\^]+(?:\\/|\\b)/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n    var start = this.parser.pos;\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Create the link unless it is suppressed\n\tif(this.match[0].substr(0,1) === \"~\") {\n\t\treturn [{type: \"text\", text: this.match[0].substr(1)}];\n\t} else {\n\t\treturn [{\n\t\t\ttype: \"element\",\n\t\t\ttag: \"a\",\n\t\t\tattributes: {\n\t\t\t\thref: {type: \"string\", value: this.match[0]},\n\t\t\t\t\"class\": {type: \"string\", value: \"tc-tiddlylink-external\"},\n\t\t\t\ttarget: {type: \"string\", value: \"_blank\"},\n\t\t\t\trel: {type: \"string\", value: \"noopener noreferrer\"}\n\t\t\t},\n\t\t\tchildren: [{\n\t\t\t\ttype: \"text\", text: this.match[0], start: start, end: this.parser.pos\n\t\t\t}]\n\t\t}];\n\t}\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/filteredtranscludeblock.js":{"title":"$:/core/modules/parsers/wikiparser/rules/filteredtranscludeblock.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/filteredtranscludeblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text rule for block-level filtered transclusion. For example:\n\n```\n{{{ [tag[docs]] }}}\n{{{ [tag[docs]] |tooltip}}}\n{{{ [tag[docs]] ||TemplateTitle}}}\n{{{ [tag[docs]] |tooltip||TemplateTitle}}}\n{{{ [tag[docs]] }}width:40;height:50;}.class.class\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"filteredtranscludeblock\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\{\\{\\{([^\\|]+?)(?:\\|([^\\|\\{\\}]+))?(?:\\|\\|([^\\|\\{\\}]+))?\\}\\}([^\\}]*)\\}(?:\\.(\\S+))?(?:\\r?\\n|$)/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tvar filterStart = this.parser.pos + 3;\n\tvar filterEnd = filterStart + this.match[1].length;\n\tvar toolTipStart = filterEnd + 1;\n\tvar toolTipEnd = toolTipStart + (this.match[2] ? this.match[2].length : 0);\n\tvar templateStart = toolTipEnd + 2;\n\tvar templateEnd = templateStart + (this.match[3] ? this.match[3].length : 0);\n\tvar styleStart = templateEnd + 2;\n\tvar styleEnd = styleStart + (this.match[4] ? this.match[4].length : 0);\n\tvar classesStart = styleEnd + 1;\n\tvar classesEnd = classesStart + (this.match[5] ? this.match[5].length : 0);\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Get the match details\n\tvar filter = this.match[1],\n\t\ttooltip = this.match[2],\n\t\ttemplate = $tw.utils.trim(this.match[3]),\n\t\tstyle = this.match[4],\n\t\tclasses = this.match[5];\n\t// Return the list widget\n\tvar node = {\n\t\ttype: \"list\",\n\t\tattributes: {\n\t\t\tfilter: {type: \"string\", value: filter, start: filterStart, end: filterEnd},\n\t\t},\n\t\tisBlock: true\n\t};\n\tif(tooltip) {\n\t\tnode.attributes.tooltip = {type: \"string\", value: tooltip, start: toolTipStart, end: toolTipEnd};\n\t}\n\tif(template) {\n\t\tnode.attributes.template = {type: \"string\", value: template, start: templateStart, end: templateEnd};\n\t}\n\tif(style) {\n\t\tnode.attributes.style = {type: \"string\", value: style, start: styleStart, end: styleEnd};\n\t}\n\tif(classes) {\n\t\tnode.attributes.itemClass = {type: \"string\", value: classes.split(\".\").join(\" \"), start: classesStart, end: classesEnd};\n\t}\n\treturn [node];\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/filteredtranscludeinline.js":{"title":"$:/core/modules/parsers/wikiparser/rules/filteredtranscludeinline.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/filteredtranscludeinline.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text rule for inline filtered transclusion. For example:\n\n```\n{{{ [tag[docs]] }}}\n{{{ [tag[docs]] |tooltip}}}\n{{{ [tag[docs]] ||TemplateTitle}}}\n{{{ [tag[docs]] |tooltip||TemplateTitle}}}\n{{{ [tag[docs]] }}width:40;height:50;}.class.class\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"filteredtranscludeinline\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\{\\{\\{([^\\|]+?)(?:\\|([^\\|\\{\\}]+))?(?:\\|\\|([^\\|\\{\\}]+))?\\}\\}([^\\}]*)\\}(?:\\.(\\S+))?/mg;\n};\n\nexports.parse = function() {\n\tvar filterStart = this.parser.pos + 3;\n\tvar filterEnd = filterStart + this.match[1].length;\n\tvar toolTipStart = filterEnd + 1;\n\tvar toolTipEnd = toolTipStart + (this.match[2] ? this.match[2].length : 0);\n\tvar templateStart = toolTipEnd + 2;\n\tvar templateEnd = templateStart + (this.match[3] ? this.match[3].length : 0);\n\tvar styleStart = templateEnd + 2;\n\tvar styleEnd = styleStart + (this.match[4] ? this.match[4].length : 0);\n\tvar classesStart = styleEnd + 1;\n\tvar classesEnd = classesStart + (this.match[5] ? this.match[5].length : 0);\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Get the match details\n\tvar filter = this.match[1],\n\t\ttooltip = this.match[2],\n\t\ttemplate = $tw.utils.trim(this.match[3]),\n\t\tstyle = this.match[4],\n\t\tclasses = this.match[5];\n\t// Return the list widget\n\tvar node = {\n\t\ttype: \"list\",\n\t\tattributes: {\n\t\t\tfilter: {type: \"string\", value: filter, start: filterStart, end: filterEnd},\n\t\t}\n\t};\n\tif(tooltip) {\n\t\tnode.attributes.tooltip = {type: \"string\", value: tooltip, start: toolTipStart, end: toolTipEnd};\n\t}\n\tif(template) {\n\t\tnode.attributes.template = {type: \"string\", value: template, start: templateStart, end: templateEnd};\n\t}\n\tif(style) {\n\t\tnode.attributes.style = {type: \"string\", value: style, start: styleStart, end: styleEnd};\n\t}\n\tif(classes) {\n\t\tnode.attributes.itemClass = {type: \"string\", value: classes.split(\".\").join(\" \"), start: classesStart, end: classesEnd};\n\t}\n\treturn [node];\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/fnprocdef.js":{"title":"$:/core/modules/parsers/wikiparser/rules/fnprocdef.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/fnprocdef.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki pragma rule for function, procedure and widget definitions\n\n```\n\\function name(param:defaultvalue,param2:defaultvalue)\ndefinition text\n\\end\n\n\\procedure name(param:defaultvalue,param2:defaultvalue)\ndefinition text\n\\end\n\n\\widget $mywidget(param:defaultvalue,param2:defaultvalue)\ndefinition text\n\\end\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"fnprocdef\";\nexports.types = {pragma: true};\n\n/*\nInstantiate parse rule\n*/\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\\\(function|procedure|widget)\\s+([^(\\s]+)\\((\\s*([^)]*))?\\)(\\s*\\r?\\n)?/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Move past the macro name and parameters\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Parse the parameters\n\tvar params = [];\n\tif(this.match[3]) {\n\t\tparams = $tw.utils.parseParameterDefinition(this.match[4]);\n\t}\n\t// Is the remainder of the line blank after the parameter close paren?\n\tvar reEnd;\n\tif(this.match[5]) {\n\t\t// If so, it is a multiline definition and the end of the body is marked with \\end\n\t\treEnd = new RegExp(\"((:?^|\\\\r?\\\\n)[^\\\\S\\\\n\\\\r]*\\\\\\\\end[^\\\\S\\\\n\\\\r]*(?:\" + $tw.utils.escapeRegExp(this.match[2]) + \")?(?:$|\\\\r?\\\\n))\",\"mg\");\n\t} else {\n\t\t// Otherwise, the end of the definition is marked by the end of the line\n\t\treEnd = /($|\\r?\\n)/mg;\n\t\t// Move past any whitespace\n\t\tthis.parser.pos = $tw.utils.skipWhiteSpace(this.parser.source,this.parser.pos);\n\t}\n\t// Find the end of the definition\n\treEnd.lastIndex = this.parser.pos;\n\tvar text,\n\t\tendMatch = reEnd.exec(this.parser.source);\n\tif(endMatch) {\n\t\ttext = this.parser.source.substring(this.parser.pos,endMatch.index);\n\t\tthis.parser.pos = endMatch.index + endMatch[0].length;\n\t} else {\n\t\t// We didn't find the end of the definition, so we'll make it blank\n\t\ttext = \"\";\n\t}\n\t// Save the macro definition\n\tvar parseTreeNodes = [{\n\t\ttype: \"set\",\n\t\tattributes: {},\n\t\tchildren: [],\n\t\tparams: params\n\t}];\n\t$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],\"name\",this.match[2]);\n\t$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],\"value\",text);\n\tif(this.match[1] === \"function\") {\n\t\tparseTreeNodes[0].isFunctionDefinition = true;\n\t} else if(this.match[1] === \"procedure\") {\n\t\tparseTreeNodes[0].isProcedureDefinition = true;\n\t} else if(this.match[1] === \"widget\") {\n\t\tparseTreeNodes[0].isWidgetDefinition = true;\n\t}\n\tif(this.parser.configTrimWhiteSpace) {\n\t\tparseTreeNodes[0].configTrimWhiteSpace = true;\n\t}\n\treturn parseTreeNodes;\n};\n\n})();\n\t","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/hardlinebreaks.js":{"title":"$:/core/modules/parsers/wikiparser/rules/hardlinebreaks.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/hardlinebreaks.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for marking areas with hard line breaks. For example:\n\n```\n\"\"\"\nThis is some text\nThat is set like\nIt is a Poem\nWhen it is\nClearly\nNot\n\"\"\"\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"hardlinebreaks\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\"\"\"(?:\\r?\\n)?/mg;\n};\n\nexports.parse = function() {\n\tvar reEnd = /(\"\"\")|(\\r?\\n)/mg,\n\t\ttree = [],\n\t\tmatch;\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\tdo {\n\t\t// Parse the run up to the terminator\n\t\ttree.push.apply(tree,this.parser.parseInlineRun(reEnd,{eatTerminator: false}));\n\t\t// Redo the terminator match\n\t\treEnd.lastIndex = this.parser.pos;\n\t\tmatch = reEnd.exec(this.parser.source);\n\t\tif(match) {\n\t\t\tvar start = this.parser.pos;\n\t\t\tthis.parser.pos = reEnd.lastIndex;\n\t\t\t// Add a line break if the terminator was a line break\n\t\t\tif(match[2]) {\n\t\t\t\ttree.push({type: \"element\", tag: \"br\", start: start, end: this.parser.pos});\n\t\t\t}\n\t\t}\n\t} while(match && !match[1]);\n\t// Return the nodes\n\treturn tree;\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/heading.js":{"title":"$:/core/modules/parsers/wikiparser/rules/heading.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/heading.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text block rule for headings\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"heading\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /(!{1,6})/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Get all the details of the match\n\tvar headingLevel = this.match[1].length;\n\t// Move past the !s\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Parse any classes, whitespace and then the heading itself\n\tvar classStart = this.parser.pos;\n\tvar classes = this.parser.parseClasses();\n\tvar classEnd = this.parser.pos;\n\tthis.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});\n\tvar tree = this.parser.parseInlineRun(/(\\r?\\n)/mg);\n\t// Return the heading\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"h\" + headingLevel,\n\t\tattributes: {\n\t\t\t\"class\": {type: \"string\", value: classes.join(\" \"), start: classStart, end: classEnd}\n\t\t},\n\t\tchildren: tree\n\t}];\n};\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/horizrule.js":{"title":"$:/core/modules/parsers/wikiparser/rules/horizrule.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/horizrule.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text block rule for rules. For example:\n\n```\n---\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"horizrule\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /-{3,}\\r?(?:\\n|$)/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\treturn [{type: \"element\", tag: \"hr\"}];\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/html.js":{"title":"$:/core/modules/parsers/wikiparser/rules/html.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/html.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki rule for HTML elements and widgets. For example:\n\n{{{\n<aside>\nThis is an HTML5 aside element\n</aside>\n\n<$slider target=\"MyTiddler\">\nThis is a widget invocation\n</$slider>\n\n}}}\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"html\";\nexports.types = {inline: true, block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n};\n\nexports.findNextMatch = function(startPos) {\n\t// Find the next tag\n\tthis.nextTag = this.findNextTag(this.parser.source,startPos,{\n\t\trequireLineBreak: this.is.block\n\t});\n\treturn this.nextTag ? this.nextTag.start : undefined;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Retrieve the most recent match so that recursive calls don't overwrite it\n\tvar tag = this.nextTag;\n\tif (!tag.isSelfClosing) {\n\t\ttag.openTagStart = tag.start;\n\t\ttag.openTagEnd = tag.end;\n\t}\n\tthis.nextTag = null;\n\t// Advance the parser position to past the tag\n\tthis.parser.pos = tag.end;\n\t// Check for an immediately following double linebreak\n\tvar hasLineBreak = !tag.isSelfClosing && !!$tw.utils.parseTokenRegExp(this.parser.source,this.parser.pos,/([^\\S\\n\\r]*\\r?\\n(?:[^\\S\\n\\r]*\\r?\\n|$))/g);\n\t// Set whether we're in block mode\n\ttag.isBlock = this.is.block || hasLineBreak;\n\t// Parse the body if we need to\n\tif(!tag.isSelfClosing && $tw.config.htmlVoidElements.indexOf(tag.tag) === -1) {\n\t\tvar reEndString = \"</\" + $tw.utils.escapeRegExp(tag.tag) + \">\";\n\t\tif(hasLineBreak) {\n\t\t\ttag.children = this.parser.parseBlocks(reEndString);\n\t\t} else {\n\t\t\tvar reEnd = new RegExp(\"(\" + reEndString + \")\",\"mg\");\n\t\t\ttag.children = this.parser.parseInlineRun(reEnd,{eatTerminator: true});\n\t\t}\n\t\ttag.end = this.parser.pos;\n\t\ttag.closeTagEnd = tag.end;\n\t\tif (tag.closeTagEnd === tag.openTagEnd || this.parser.source[tag.closeTagEnd - 1] !== '>') {\n\t\t\ttag.closeTagStart = tag.end;\n\t\t} else {\n\t\t\ttag.closeTagStart = tag.closeTagEnd - 2;\n\t\t\tvar closeTagMinPos = tag.children.length > 0 ? tag.children[tag.children.length-1].end : tag.openTagEnd;\n\t\t\tif (!Number.isSafeInteger(closeTagMinPos)) closeTagMinPos = tag.openTagEnd;\n\t\t\twhile (tag.closeTagStart >= closeTagMinPos) {\n\t\t\t\tvar char = this.parser.source[tag.closeTagStart];\n\t\t\t\tif (char === '>') {\n\t\t\t\t\ttag.closeTagStart = -1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (char === '<') break;\n\t\t\t\ttag.closeTagStart -= 1;\n\t\t\t}\n\t\t\tif (tag.closeTagStart < closeTagMinPos) {\n\t\t\t\ttag.closeTagStart = tag.end;\n\t\t\t}\n\t\t}\n\t}\n\t// Return the tag\n\treturn [tag];\n};\n\n/*\nLook for an HTML tag. Returns null if not found, otherwise returns {type: \"element\", name:, attributes: {}, orderedAttributes: [], isSelfClosing:, start:, end:,}\n*/\nexports.parseTag = function(source,pos,options) {\n\toptions = options || {};\n\tvar token,\n\t\tnode = {\n\t\t\ttype: \"element\",\n\t\t\tstart: pos,\n\t\t\tattributes: {},\n\t\t\torderedAttributes: []\n\t\t};\n\t// Define our regexps\n\tvar reTagName = /([a-zA-Z0-9\\-\\$\\.]+)/g;\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for a less than sign\n\ttoken = $tw.utils.parseTokenString(source,pos,\"<\");\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Get the tag name\n\ttoken = $tw.utils.parseTokenRegExp(source,pos,reTagName);\n\tif(!token) {\n\t\treturn null;\n\t}\n\tnode.tag = token.match[1];\n\tif(node.tag.charAt(0) === \"$\") {\n\t\tnode.type = node.tag.substr(1);\n\t}\n\tpos = token.end;\n\t// Check that the tag is terminated by a space, / or >\n\tif(!$tw.utils.parseWhiteSpace(source,pos) && !(source.charAt(pos) === \"/\") && !(source.charAt(pos) === \">\") ) {\n\t\treturn null;\n\t}\n\t// Process attributes\n\tvar attribute = $tw.utils.parseAttribute(source,pos);\n\twhile(attribute) {\n\t\tnode.orderedAttributes.push(attribute);\n\t\tnode.attributes[attribute.name] = attribute;\n\t\tpos = attribute.end;\n\t\t// Get the next attribute\n\t\tattribute = $tw.utils.parseAttribute(source,pos);\n\t}\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for a closing slash\n\ttoken = $tw.utils.parseTokenString(source,pos,\"/\");\n\tif(token) {\n\t\tpos = token.end;\n\t\tnode.isSelfClosing = true;\n\t}\n\t// Look for a greater than sign\n\ttoken = $tw.utils.parseTokenString(source,pos,\">\");\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Check for a required line break\n\tif(options.requireLineBreak) {\n\t\ttoken = $tw.utils.parseTokenRegExp(source,pos,/([^\\S\\n\\r]*\\r?\\n(?:[^\\S\\n\\r]*\\r?\\n|$))/g);\n\t\tif(!token) {\n\t\t\treturn null;\n\t\t}\n\t}\n\t// Update the end position\n\tnode.end = pos;\n\treturn node;\n};\n\nexports.findNextTag = function(source,pos,options) {\n\t// A regexp for finding candidate HTML tags\n\tvar reLookahead = /<([a-zA-Z\\-\\$\\.]+)/g;\n\t// Find the next candidate\n\treLookahead.lastIndex = pos;\n\tvar match = reLookahead.exec(source);\n\twhile(match) {\n\t\t// Try to parse the candidate as a tag\n\t\tvar tag = this.parseTag(source,match.index,options);\n\t\t// Return success\n\t\tif(tag && this.isLegalTag(tag)) {\n\t\t\treturn tag;\n\t\t}\n\t\t// Look for the next match\n\t\treLookahead.lastIndex = match.index + 1;\n\t\tmatch = reLookahead.exec(source);\n\t}\n\t// Failed\n\treturn null;\n};\n\nexports.isLegalTag = function(tag) {\n\t// Widgets are always OK\n\tif(tag.type !== \"element\") {\n\t\treturn true;\n\t// If it's an HTML tag that starts with a dash then it's not legal\n\t} else if(tag.tag.charAt(0) === \"-\") {\n\t\treturn false;\n\t} else {\n\t\t// Otherwise it's OK\n\t\treturn true;\n\t}\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/image.js":{"title":"$:/core/modules/parsers/wikiparser/rules/image.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/image.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for embedding images. For example:\n\n```\n[img[https://tiddlywiki.com/fractalveg.jpg]]\n[img width=23 height=24 [https://tiddlywiki.com/fractalveg.jpg]]\n[img width={{!!width}} height={{!!height}} [https://tiddlywiki.com/fractalveg.jpg]]\n[img[Description of image|https://tiddlywiki.com/fractalveg.jpg]]\n[img[TiddlerTitle]]\n[img[Description of image|TiddlerTitle]]\n```\n\nGenerates the `<$image>` widget.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"image\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n};\n\nexports.findNextMatch = function(startPos) {\n\t// Find the next tag\n\tthis.nextImage = this.findNextImage(this.parser.source,startPos);\n\treturn this.nextImage ? this.nextImage.start : undefined;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.nextImage.end;\n\tvar node = {\n\t\ttype: \"image\",\n\t\tattributes: this.nextImage.attributes\n\t};\n\treturn [node];\n};\n\n/*\nFind the next image from the current position\n*/\nexports.findNextImage = function(source,pos) {\n\t// A regexp for finding candidate HTML tags\n\tvar reLookahead = /(\\[img)/g;\n\t// Find the next candidate\n\treLookahead.lastIndex = pos;\n\tvar match = reLookahead.exec(source);\n\twhile(match) {\n\t\t// Try to parse the candidate as a tag\n\t\tvar tag = this.parseImage(source,match.index);\n\t\t// Return success\n\t\tif(tag) {\n\t\t\treturn tag;\n\t\t}\n\t\t// Look for the next match\n\t\treLookahead.lastIndex = match.index + 1;\n\t\tmatch = reLookahead.exec(source);\n\t}\n\t// Failed\n\treturn null;\n};\n\n/*\nLook for an image at the specified position. Returns null if not found, otherwise returns {type: \"image\", attributes: [], isSelfClosing:, start:, end:,}\n*/\nexports.parseImage = function(source,pos) {\n\tvar token,\n\t\tnode = {\n\t\t\ttype: \"image\",\n\t\t\tstart: pos,\n\t\t\tattributes: {}\n\t\t};\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for the `[img`\n\ttoken = $tw.utils.parseTokenString(source,pos,\"[img\");\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Process attributes\n\tif(source.charAt(pos) !== \"[\") {\n\t\tvar attribute = $tw.utils.parseAttribute(source,pos);\n\t\twhile(attribute) {\n\t\t\tnode.attributes[attribute.name] = attribute;\n\t\t\tpos = attribute.end;\n\t\t\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t\t\tif(source.charAt(pos) !== \"[\") {\n\t\t\t\t// Get the next attribute\n\t\t\t\tattribute = $tw.utils.parseAttribute(source,pos);\n\t\t\t} else {\n\t\t\t\tattribute = null;\n\t\t\t}\n\t\t}\n\t}\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for the `[` after the attributes\n\ttoken = $tw.utils.parseTokenString(source,pos,\"[\");\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Get the source up to the terminating `]]`\n\ttoken = $tw.utils.parseTokenRegExp(source,pos,/(?:([^|\\]]*?)\\|)?([^\\]]+?)\\]\\]/g);\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\tif(token.match[1]) {\n\t\tnode.attributes.tooltip = {type: \"string\", value: token.match[1].trim(),start: token.start,end:token.start + token.match[1].length - 1};\n\t}\n\tnode.attributes.source = {type: \"string\", value: (token.match[2] || \"\").trim(), start: token.start + (token.match[1] ? token.match[1].length : 0), end: token.end - 2};\n\t// Update the end position\n\tnode.end = pos;\n\treturn node;\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/import.js":{"title":"$:/core/modules/parsers/wikiparser/rules/import.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/import.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki pragma rule for importing variable definitions\n\n```\n\\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"import\";\nexports.types = {pragma: true};\n\n/*\nInstantiate parse rule\n*/\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\\\import[^\\S\\n]/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\tvar self = this;\n\t// Move past the pragma invocation\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Parse the filter terminated by a line break\n\tvar reMatch = /(.*)(?:$|\\r?\\n)/mg;\n\treMatch.lastIndex = this.parser.pos;\n\tvar filterStart = this.parser.source;\n\tvar match = reMatch.exec(this.parser.source);\n\tthis.parser.pos = reMatch.lastIndex;\n\t// Parse tree nodes to return\n\treturn [{\n\t\ttype: \"importvariables\",\n\t\tattributes: {\n\t\t\tfilter: {type: \"string\", value: match[1], start: filterStart, end: this.parser.pos}\n\t\t},\n\t\tchildren: []\n\t}];\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/list.js":{"title":"$:/core/modules/parsers/wikiparser/rules/list.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/list.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text block rule for lists. For example:\n\n```\n* This is an unordered list\n* It has two items\n\n# This is a numbered list\n## With a subitem\n# And a third item\n\n; This is a term that is being defined\n: This is the definition of that term\n```\n\nNote that lists can be nested arbitrarily:\n\n```\n#** One\n#* Two\n#** Three\n#**** Four\n#**# Five\n#**## Six\n## Seven\n### Eight\n## Nine\n```\n\nA CSS class can be applied to a list item as follows:\n\n```\n* List item one\n*.active List item two has the class `active`\n* List item three\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"list\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /([\\*#;:>]+)/mg;\n};\n\nvar listTypes = {\n\t\"*\": {listTag: \"ul\", itemTag: \"li\"},\n\t\"#\": {listTag: \"ol\", itemTag: \"li\"},\n\t\";\": {listTag: \"dl\", itemTag: \"dt\"},\n\t\":\": {listTag: \"dl\", itemTag: \"dd\"},\n\t\">\": {listTag: \"blockquote\", itemTag: \"div\"}\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Array of parse tree nodes for the previous row of the list\n\tvar listStack = [];\n\t// Cycle through the items in the list\n\twhile(true) {\n\t\t// Match the list marker\n\t\tvar reMatch = /([\\*#;:>]+)/mg;\n\t\treMatch.lastIndex = this.parser.pos;\n\t\tvar start = this.parser.pos;\n\t\tvar match = reMatch.exec(this.parser.source);\n\t\tif(!match || match.index !== this.parser.pos) {\n\t\t\tbreak;\n\t\t}\n\t\t// Check whether the list type of the top level matches\n\t\tvar listInfo = listTypes[match[0].charAt(0)];\n\t\tif(listStack.length > 0 && listStack[0].tag !== listInfo.listTag) {\n\t\t\tbreak;\n\t\t}\n\t\t// Move past the list marker\n\t\tthis.parser.pos = match.index + match[0].length;\n\t\t// Walk through the list markers for the current row\n\t\tfor(var t=0; t<match[0].length; t++) {\n\t\t\tlistInfo = listTypes[match[0].charAt(t)];\n\t\t\t// Remove any stacked up element if we can't re-use it because the list type doesn't match\n\t\t\tif(listStack.length > t && listStack[t].tag !== listInfo.listTag) {\n\t\t\t\tlistStack.splice(t,listStack.length - t);\n\t\t\t}\n\t\t\t// Construct the list element or reuse the previous one at this level\n\t\t\tif(listStack.length <= t) {\n\t\t\t\tvar listElement = {\n\t\t\t\t\ttype: \"element\",\n\t\t\t\t\ttag: listInfo.listTag,\n\t\t\t\t\tchildren: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"element\",\n\t\t\t\t\t\t\ttag: listInfo.itemTag,\n\t\t\t\t\t\t\tchildren: [],\n\t\t\t\t\t\t\tstart: start,\n\t\t\t\t\t\t\tend: this.parser.pos,\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\tstart: start,\n\t\t\t\t\tend: this.parser.pos,\n\t\t\t\t};\n\t\t\t\t// Link this list element into the last child item of the parent list item\n\t\t\t\tif(t) {\n\t\t\t\t\tvar prevListItem = listStack[t-1].children[listStack[t-1].children.length-1];\n\t\t\t\t\tprevListItem.children.push(listElement);\n\t\t\t\t}\n\t\t\t\t// Save this element in the stack\n\t\t\t\tlistStack[t] = listElement;\n\t\t\t} else if(t === (match[0].length - 1)) {\n\t\t\t\tlistStack[t].children.push({\n\t\t\t\t\ttype: \"element\",\n\t\t\t\t\ttag: listInfo.itemTag,\n\t\t\t\t\tchildren: [],\n\t\t\t\t\tstart: start,\n\t\t\t\t\tend: this.parser.pos,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tif(listStack.length > match[0].length) {\n\t\t\tlistStack.splice(match[0].length,listStack.length - match[0].length);\n\t\t}\n\t\t// Process the body of the list item into the last list item\n\t\tvar classStart = this.parser.pos;\n\t\tvar lastListChildren = listStack[listStack.length-1].children,\n\t\t\tlastListItem = lastListChildren[lastListChildren.length-1],\n\t\t\tclasses = this.parser.parseClasses();\n\t\tvar classEnd = this.parser.pos;\n\t\tthis.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});\n\t\tvar tree = this.parser.parseInlineRun(/(\\r?\\n)/mg);\n\t\tlastListItem.children.push.apply(lastListItem.children,tree);\n\t\tlastListItem.end = this.parser.pos;\n\t\tlistStack[listStack.length-1].end = this.parser.pos;\n\t\tif(classes.length > 0) {\n\t\t\t$tw.utils.addClassToParseTreeNode(lastListItem,classes.join(\" \"));\n\t\t\tlastListItem.attributes.class.start = classStart;\n\t\t\tlastListItem.attributes.class.end = classEnd;\n\t\t}\n\t\t// Consume any whitespace following the list item\n\t\tthis.parser.skipWhitespace();\n\t}\n\t// Return the root element of the list\n\treturn [listStack[0]];\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/macrocallblock.js":{"title":"$:/core/modules/parsers/wikiparser/rules/macrocallblock.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/macrocallblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki rule for block macro calls\n\n```\n<<name value value2>>\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"macrocallblock\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n};\n\nexports.findNextMatch = function(startPos) {\n\tvar nextStart = startPos;\n\t// Try parsing at all possible macrocall openers until we match\n\twhile((nextStart = this.parser.source.indexOf(\"<<\",nextStart)) >= 0) {\n\t\tvar nextCall = $tw.utils.parseMacroInvocationAsTransclusion(this.parser.source,nextStart);\n\t\tif(nextCall) {\n\t\t\tvar c = this.parser.source.charAt(nextCall.end);\n\t\t\t// Ensure EOL after parsed macro\n\t\t\t// If we didn't need to support IE, we'd just use /(?:\\r?\\n|$)/ym\n\t\t\tif ((c === \"\") || (c === \"\\n\") || ((c === \"\\r\") && this.parser.source.charAt(nextCall.end+1) === \"\\n\")) {\n\t\t\t\tthis.nextCall = nextCall;\n\t\t\t\treturn nextStart;\n\t\t\t}\n\t\t}\n\t\tnextStart += 2;\n\t}\n\treturn undefined;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\tvar call = this.nextCall;\n\tcall.isBlock = true;\n\tthis.nextCall = null;\n\tthis.parser.pos = call.end;\n\treturn [call];\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/macrocallinline.js":{"title":"$:/core/modules/parsers/wikiparser/rules/macrocallinline.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/macrocallinline.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki rule for macro calls\n\n```\n<<name value value2>>\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"macrocallinline\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n};\n\nexports.findNextMatch = function(startPos) {\n\tvar nextStart = startPos;\n\t// Try parsing at all possible macrocall openers until we match\n\twhile((nextStart = this.parser.source.indexOf(\"<<\",nextStart)) >= 0) {\n\t\tthis.nextCall = $tw.utils.parseMacroInvocationAsTransclusion(this.parser.source,nextStart);\n\t\tif(this.nextCall) {\n\t\t\treturn nextStart;\n\t\t}\n\t\tnextStart += 2;\n\t}\n\treturn undefined;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\tvar call = this.nextCall;\n\tthis.nextCall = null;\n\tthis.parser.pos = call.end;\n\treturn [call];\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/macrodef.js":{"title":"$:/core/modules/parsers/wikiparser/rules/macrodef.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/macrodef.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki pragma rule for macro definitions\n\n```\n\\define name(param:defaultvalue,param2:defaultvalue)\ndefinition text, including $param$ markers\n\\end\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"macrodef\";\nexports.types = {pragma: true};\n\n/*\nInstantiate parse rule\n*/\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\\\define\\s+([^(\\s]+)\\(\\s*([^)]*)\\)(\\s*\\r?\\n)?/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Move past the macro name and parameters\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Parse the parameters\n\tvar paramString = this.match[2],\n\t\tparams = [];\n\tif(paramString !== \"\") {\n\t\tvar reParam = /\\s*([A-Za-z0-9\\-_]+)(?:\\s*:\\s*(?:\"\"\"([\\s\\S]*?)\"\"\"|\"([^\"]*)\"|'([^']*)'|\\[\\[([^\\]]*)\\]\\]|([^\"'\\s]+)))?/mg,\n\t\t\tparamMatch = reParam.exec(paramString);\n\t\twhile(paramMatch) {\n\t\t\t// Save the parameter details\n\t\t\tvar paramInfo = {name: paramMatch[1]},\n\t\t\t\tdefaultValue = paramMatch[2] || paramMatch[3] || paramMatch[4] || paramMatch[5] || paramMatch[6];\n\t\t\tif(defaultValue) {\n\t\t\t\tparamInfo[\"default\"] = defaultValue;\n\t\t\t}\n\t\t\tparams.push(paramInfo);\n\t\t\t// Look for the next parameter\n\t\t\tparamMatch = reParam.exec(paramString);\n\t\t}\n\t}\n\t// Is the remainder of the \\define line blank after the parameter close paren?\n\tvar reEnd;\n\tif(this.match[3]) {\n\t\t// If so, it is a multiline definition and the end of the body is marked with \\end\n\t\treEnd = new RegExp(\"((?:^|\\\\r?\\\\n)[^\\\\S\\\\n\\\\r]*\\\\\\\\end[^\\\\S\\\\n\\\\r]*(?:\" + $tw.utils.escapeRegExp(this.match[1]) + \")?(?:$|\\\\r?\\\\n))\",\"mg\");\n\t} else {\n\t\t// Otherwise, the end of the definition is marked by the end of the line\n\t\treEnd = /($|\\r?\\n)/mg;\n\t\t// Move past any whitespace\n\t\tthis.parser.pos = $tw.utils.skipWhiteSpace(this.parser.source,this.parser.pos);\n\t}\n\t// Find the end of the definition\n\treEnd.lastIndex = this.parser.pos;\n\tvar text,\n\t\tendMatch = reEnd.exec(this.parser.source);\n\tif(endMatch) {\n\t\ttext = this.parser.source.substring(this.parser.pos,endMatch.index);\n\t\tthis.parser.pos = endMatch.index + endMatch[0].length;\n\t} else {\n\t\t// We didn't find the end of the definition, so we'll make it blank\n\t\ttext = \"\";\n\t}\n\t// Save the macro definition\n\tvar parseTreeNodes = [{\n\t\ttype: \"set\",\n\t\tattributes: {},\n\t\tchildren: [],\n\t\tparams: params,\n\t\tisMacroDefinition: true\n\t}];\n\t$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],\"name\",this.match[1]);\n\t$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],\"value\",text);\n\treturn parseTreeNodes;\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/parameters.js":{"title":"$:/core/modules/parsers/wikiparser/rules/parameters.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/parameters.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki pragma rule for parameter definitions\n\n```\n\\parameters(param:defaultvalue,param2:defaultvalue)\ndefinition text\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"parameters\";\nexports.types = {pragma: true};\n\n/*\nInstantiate parse rule\n*/\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\\\parameters\\s*\\(([^)]*)\\)(\\s*\\r?\\n)?/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Move past the macro name and parameters\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Parse the parameters\n\tvar params = $tw.utils.parseParameterDefinition(this.match[1]);\n\tvar attributes = Object.create(null),\n\t\torderedAttributes = [];\n\t$tw.utils.each(params,function(param) {\n\t\tvar name = param.name;\n\t\t// Parameter names starting with dollar must be escaped to double dollars for the parameters widget\n\t\tif(name.charAt(0) === \"$\") {\n\t\t\tname = \"$\" + name;\n\t\t}\n\t\tvar attribute = {name: name, type: \"string\", value: param[\"default\"] || \"\"};\n\t\tattributes[name] = attribute;\n\t\torderedAttributes.push(attribute);\n\t});\n\t// Save the macro definition\n\treturn [{\n\t\ttype: \"parameters\",\n\t\tattributes: attributes,\n\t\torderedAttributes: orderedAttributes\n\t}];\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/parsermode.js":{"title":"$:/core/modules/parsers/wikiparser/rules/parsermode.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/parsermode.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki pragma rule for parser mode specifications\n\n```\n\\parsermode block\n\\parsermode inline\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"parsermode\";\nexports.types = {pragma: true};\n\n/*\nInstantiate parse rule\n*/\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\\\parsermode[^\\S\\n]/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Move past the pragma invocation\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Parse whitespace delimited tokens terminated by a line break\n\tvar reMatch = /[^\\S\\n]*(\\S+)|(\\r?\\n)/mg,\n\t\tparserMode = undefined;\n\treMatch.lastIndex = this.parser.pos;\n\tvar match = reMatch.exec(this.parser.source);\n\twhile(match && match.index === this.parser.pos) {\n\t\tthis.parser.pos = reMatch.lastIndex;\n\t\t// Exit if we've got the line break\n\t\tif(match[2]) {\n\t\t\tbreak;\n\t\t}\n\t\t// Process the token\n\t\tif(match[1]) {\n\t\t\tparserMode = match[1];\n\t\t}\n\t\t// Match the next token\n\t\tmatch = reMatch.exec(this.parser.source);\n\t}\n\t// Process the tokens\n\tif(parserMode !== undefined) {\n\t\tif(parserMode === \"block\") {\n\t\t\tthis.parser.parseAsInline = false;\n\t\t} else if(parserMode === \"inline\") {\n\t\t\tthis.parser.parseAsInline = true;\n\t\t}\n\t}\n\t// No parse tree nodes to return\n\treturn [];\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/prettyextlink.js":{"title":"$:/core/modules/parsers/wikiparser/rules/prettyextlink.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/prettyextlink.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for external links. For example:\n\n```\n[ext[https://tiddlywiki.com/fractalveg.jpg]]\n[ext[Tooltip|https://tiddlywiki.com/fractalveg.jpg]]\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"prettyextlink\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n};\n\nexports.findNextMatch = function(startPos) {\n\t// Find the next tag\n\tthis.nextLink = this.findNextLink(this.parser.source,startPos);\n\treturn this.nextLink ? this.nextLink.start : undefined;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.nextLink.end;\n\treturn [this.nextLink];\n};\n\n/*\nFind the next link from the current position\n*/\nexports.findNextLink = function(source,pos) {\n\t// A regexp for finding candidate links\n\tvar reLookahead = /(\\[ext\\[)/g;\n\t// Find the next candidate\n\treLookahead.lastIndex = pos;\n\tvar match = reLookahead.exec(source);\n\twhile(match) {\n\t\t// Try to parse the candidate as a link\n\t\tvar link = this.parseLink(source,match.index);\n\t\t// Return success\n\t\tif(link) {\n\t\t\treturn link;\n\t\t}\n\t\t// Look for the next match\n\t\treLookahead.lastIndex = match.index + 1;\n\t\tmatch = reLookahead.exec(source);\n\t}\n\t// Failed\n\treturn null;\n};\n\n/*\nLook for an link at the specified position. Returns null if not found, otherwise returns {type: \"element\", tag: \"a\", attributes: [], isSelfClosing:, start:, end:,}\n*/\nexports.parseLink = function(source,pos) {\n\tvar token,\n\t\ttextNode = {\n\t\t\ttype: \"text\"\n\t\t},\n\t\tnode = {\n\t\t\ttype: \"element\",\n\t\t\ttag: \"a\",\n\t\t\tstart: pos,\n\t\t\tattributes: {\n\t\t\t\t\"class\": {type: \"string\", value: \"tc-tiddlylink-external\"},\n\t\t\t},\n\t\t\tchildren: [textNode]\n\t\t};\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for the `[ext[`\n\ttoken = $tw.utils.parseTokenString(source,pos,\"[ext[\");\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Look ahead for the terminating `]]`\n\tvar closePos = source.indexOf(\"]]\",pos);\n\tif(closePos === -1) {\n\t\treturn null;\n\t}\n\t// Look for a `|` separating the tooltip\n\tvar splitPos = source.indexOf(\"|\",pos);\n\tif(splitPos === -1 || splitPos > closePos) {\n\t\tsplitPos = null;\n\t}\n\t// Pull out the tooltip and URL\n\tvar tooltip, URL, urlStart;\n\ttextNode.start = pos;\n\tif(splitPos) {\n\t\turlStart = splitPos + 1;\n\t\tURL = source.substring(splitPos + 1,closePos).trim();\n\t\ttextNode.text = source.substring(pos,splitPos).trim();\n\t\ttextNode.end = splitPos;\n\t} else {\n\t\turlStart = pos;\n\t\tURL = source.substring(pos,closePos).trim();\n\t\ttextNode.text = URL;\n\t\ttextNode.end = closePos;\n\t}\n\tnode.attributes.href = {type: \"string\", value: URL, start: urlStart, end: closePos};\n\tnode.attributes.target = {type: \"string\", value: \"_blank\"};\n\tnode.attributes.rel = {type: \"string\", value: \"noopener noreferrer\"};\n\t// Update the end position\n\tnode.end = closePos + 2;\n\treturn node;\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/prettylink.js":{"title":"$:/core/modules/parsers/wikiparser/rules/prettylink.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/prettylink.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for pretty links. For example:\n\n```\n[[Introduction]]\n\n[[Link description|TiddlerTitle]]\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"prettylink\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\[\\[(.*?)(?:\\|(.*?))?\\]\\]/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tvar start = this.parser.pos + 2;\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Process the link\n\tvar text = this.match[1],\n\t\tlink = this.match[2] || text,\n\t\ttextEndPos = this.parser.source.indexOf(\"|\", start);\n\tif (textEndPos < 0 || textEndPos > this.matchRegExp.lastIndex) {\n\t\ttextEndPos = this.matchRegExp.lastIndex - 2;\n\t}\n\tvar linkStart = this.match[2] ? (start + this.match[1].length + 1) : start;\n\tvar linkEnd = linkStart + link.length;\n\tif($tw.utils.isLinkExternal(link)) {\n\t\treturn [{\n\t\t\ttype: \"element\",\n\t\t\ttag: \"a\",\n\t\t\tattributes: {\n\t\t\t\thref: {type: \"string\", value: link, start: linkStart, end: linkEnd},\n\t\t\t\t\"class\": {type: \"string\", value: \"tc-tiddlylink-external\"},\n\t\t\t\ttarget: {type: \"string\", value: \"_blank\"},\n\t\t\t\trel: {type: \"string\", value: \"noopener noreferrer\"}\n\t\t\t},\n\t\t\tchildren: [{\n\t\t\t\ttype: \"text\", text: text, start: start, end: textEndPos\n\t\t\t}]\n\t\t}];\n\t} else {\n\t\treturn [{\n\t\t\ttype: \"link\",\n\t\t\tattributes: {\n\t\t\t\tto: {type: \"string\", value: link, start: linkStart, end: linkEnd}\n\t\t\t},\n\t\t\tchildren: [{\n\t\t\t\ttype: \"text\", text: text, start: start, end: textEndPos\n\t\t\t}]\n\t\t}];\n\t}\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/quoteblock.js":{"title":"$:/core/modules/parsers/wikiparser/rules/quoteblock.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/quoteblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text rule for quote blocks.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"quoteblock\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /(<<<+)/mg;\n};\n\nexports.parse = function() {\n\tvar classes = [\"tc-quote\"];\n\t// Get all the details of the match\n\tvar reEndString = \"^\\\\s*\" + this.match[1] + \"(?!<)\";\n\t// Move past the <s\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Parse any classes, whitespace and then the optional cite itself\n\tvar classStart = this.parser.pos;\n\tclasses.push.apply(classes, this.parser.parseClasses());\n\tvar classEnd = this.parser.pos;\n\tthis.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});\n\tvar citeStart = this.parser.pos;\n\tvar cite = this.parser.parseInlineRun(/(\\r?\\n)/mg);\n\tvar citeEnd = this.parser.pos;\n\t// before handling the cite, parse the body of the quote\n\tvar tree = this.parser.parseBlocks(reEndString);\n\t// If we got a cite, put it before the text\n\tif(cite.length > 0) {\n\t\ttree.unshift({\n\t\t\ttype: \"element\",\n\t\t\ttag: \"cite\",\n\t\t\tchildren: cite,\n\t\t\tstart: citeStart,\n\t\t\tend: citeEnd\n\t\t});\n\t}\n\t// Parse any optional cite\n\tthis.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});\n\tciteStart = this.parser.pos;\n\tcite = this.parser.parseInlineRun(/(\\r?\\n)/mg);\n\tciteEnd = this.parser.pos;\n\t// If we got a cite, push it\n\tif(cite.length > 0) {\n\t\ttree.push({\n\t\t\ttype: \"element\",\n\t\t\ttag: \"cite\",\n\t\t\tchildren: cite,\n\t\t\tstart: citeStart,\n\t\t\tend: citeEnd\n\t\t});\n\t}\n\t// Return the blockquote element\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"blockquote\",\n\t\tattributes: {\n\t\t\tclass: { type: \"string\", value: classes.join(\" \"), start: classStart, end: classEnd },\n\t\t},\n\t\tchildren: tree\n\t}];\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/rules.js":{"title":"$:/core/modules/parsers/wikiparser/rules/rules.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/rules.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki pragma rule for rules specifications\n\n```\n\\rules except ruleone ruletwo rulethree\n\\rules only ruleone ruletwo rulethree\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"rules\";\nexports.types = {pragma: true};\n\n/*\nInstantiate parse rule\n*/\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\\\rules[^\\S\\n]/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Move past the pragma invocation\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Parse whitespace delimited tokens terminated by a line break\n\tvar reMatch = /[^\\S\\n]*(\\S+)|(\\r?\\n)/mg,\n\t\ttokens = [];\n\treMatch.lastIndex = this.parser.pos;\n\tvar match = reMatch.exec(this.parser.source);\n\twhile(match && match.index === this.parser.pos) {\n\t\tthis.parser.pos = reMatch.lastIndex;\n\t\t// Exit if we've got the line break\n\t\tif(match[2]) {\n\t\t\tbreak;\n\t\t}\n\t\t// Process the token\n\t\tif(match[1]) {\n\t\t\ttokens.push(match[1]);\n\t\t}\n\t\t// Match the next token\n\t\tmatch = reMatch.exec(this.parser.source);\n\t}\n\t// Process the tokens\n\tif(tokens.length > 0) {\n\t\tthis.parser.amendRules(tokens[0],tokens.slice(1));\n\t}\n\t// No parse tree nodes to return\n\treturn [];\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/styleblock.js":{"title":"$:/core/modules/parsers/wikiparser/rules/styleblock.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/styleblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text block rule for assigning styles and classes to paragraphs and other blocks. For example:\n\n```\n@@.myClass\n@@background-color:red;\nThis paragraph will have the CSS class `myClass`.\n\n* The `<ul>` around this list will also have the class `myClass`\n* List item 2\n\n@@\n```\n\nNote that classes and styles can be mixed subject to the rule that styles must precede classes. For example\n\n```\n@@.myFirstClass.mySecondClass\n@@width:100px;.myThirdClass\nThis is a paragraph\n@@\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"styleblock\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /@@((?:[^\\.\\r\\n\\s:]+:[^\\r\\n;]+;)+)?(?:\\.([^\\r\\n\\s]+))?\\r?\\n/mg;\n};\n\nexports.parse = function() {\n\tvar reEndString = \"^@@(?:\\\\r?\\\\n)?\";\n\tvar classes = [], styles = [];\n\tdo {\n\t\t// Get the class and style\n\t\tif(this.match[1]) {\n\t\t\tstyles.push(this.match[1]);\n\t\t}\n\t\tif(this.match[2]) {\n\t\t\tclasses.push(this.match[2].split(\".\").join(\" \"));\n\t\t}\n\t\t// Move past the match\n\t\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t\t// Look for another line of classes and styles\n\t\tthis.match = this.matchRegExp.exec(this.parser.source);\n\t} while(this.match && this.match.index === this.parser.pos);\n\t// Parse the body\n\tvar tree = this.parser.parseBlocks(reEndString);\n\tfor(var t=0; t<tree.length; t++) {\n\t\tif(classes.length > 0) {\n\t\t\t$tw.utils.addClassToParseTreeNode(tree[t],classes.join(\" \"));\n\t\t}\n\t\tif(styles.length > 0) {\n\t\t\t$tw.utils.addAttributeToParseTreeNode(tree[t],\"style\",styles.join(\"\"));\n\t\t}\n\t}\n\treturn tree;\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/styleinline.js":{"title":"$:/core/modules/parsers/wikiparser/rules/styleinline.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/styleinline.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for assigning styles and classes to inline runs. For example:\n\n```\n@@.myClass This is some text with a class@@\n@@background-color:red;This is some text with a background colour@@\n@@width:100px;.myClass This is some text with a class and a width@@\n```\n\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"styleinline\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /@@((?:[^\\.\\r\\n\\s:]+:[^\\r\\n;]+;)+)?(\\.(?:[^\\r\\n\\s]+)\\s+)?/mg;\n};\n\nexports.parse = function() {\n\tvar reEnd = /@@/g;\n\t// Get the styles and class\n\tvar stylesString = this.match[1],\n\t\tclassString = this.match[2] ? this.match[2].split(\".\").join(\" \") : undefined;\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Parse the run up to the terminator\n\tvar tree = this.parser.parseInlineRun(reEnd,{eatTerminator: true});\n\t// Return the classed span\n\tvar node = {\n\t\ttype: \"element\",\n\t\ttag: \"span\",\n\t\tchildren: tree\n\t};\n\tif(classString) {\n\t\t$tw.utils.addClassToParseTreeNode(node,classString);\n\t}\n\tif(stylesString) {\n\t\t$tw.utils.addAttributeToParseTreeNode(node,\"style\",stylesString);\n\t}\n\tif(!classString && !stylesString) {\n\t\t$tw.utils.addClassToParseTreeNode(node,\"tc-inline-style\");\n\t}\n\treturn [node];\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/syslink.js":{"title":"$:/core/modules/parsers/wikiparser/rules/syslink.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/syslink.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for system tiddler links.\nCan be suppressed preceding them with `~`.\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"syslink\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = new RegExp(\n\t\t\"~?\\\\$:\\\\/[\" +\n\t\t$tw.config.textPrimitives.anyLetter.substr(1,$tw.config.textPrimitives.anyLetter.length - 2) +\n\t\t\"\\/._-]+\",\n\t\t\"mg\"\n\t);\n};\n\nexports.parse = function() {\n\tvar match = this.match[0];\n\t// Move past the match\n\tvar start = this.parser.pos;\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Create the link unless it is suppressed\n\tif(match.substr(0,1) === \"~\") {\n\t\treturn [{type: \"text\", text: match.substr(1), start: start+1, end: this.parser.pos}];\n\t} else {\n\t\treturn [{\n\t\t\ttype: \"link\",\n\t\t\tattributes: {\n\t\t\t\tto: {type: \"string\", value: match}\n\t\t\t},\n\t\t\tchildren: [{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: match,\n\t\t\t\tstart: start,\n\t\t\t\tend: this.parser.pos\n\t\t\t}]\n\t\t}];\n\t}\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/table.js":{"title":"$:/core/modules/parsers/wikiparser/rules/table.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/table.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text block rule for tables.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"table\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /^\\|(?:[^\\n]*)\\|(?:[fhck]?)\\r?(?:\\n|$)/mg;\n};\n\nvar processRow = function(prevColumns) {\n\tvar cellRegExp = /(?:\\|([^\\n\\|]*)\\|)|(\\|[fhck]?\\r?(?:\\n|$))/mg,\n\t\tcellTermRegExp = /((?:\\x20*)\\|)/mg,\n\t\ttree = [],\n\t\tcol = 0,\n\t\tcolSpanCount = 1,\n\t\tprevCell,\n\t\tvAlign;\n\t// Match a single cell\n\tcellRegExp.lastIndex = this.parser.pos;\n\tvar cellMatch = cellRegExp.exec(this.parser.source);\n\twhile(cellMatch && cellMatch.index === this.parser.pos) {\n\t\tif(cellMatch[1] === \"~\") {\n\t\t\t// Rowspan\n\t\t\tvar last = prevColumns[col];\n\t\t\tif(last) {\n\t\t\t\tlast.rowSpanCount++;\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(last.element,\"rowspan\",last.rowSpanCount);\n\t\t\t\tvAlign = $tw.utils.getAttributeValueFromParseTreeNode(last.element,\"valign\",\"center\");\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(last.element,\"valign\",vAlign);\n\t\t\t\tif(colSpanCount > 1) {\n\t\t\t\t\t$tw.utils.addAttributeToParseTreeNode(last.element,\"colspan\",colSpanCount);\n\t\t\t\t\tcolSpanCount = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Move to just before the `|` terminating the cell\n\t\t\tthis.parser.pos = cellRegExp.lastIndex - 1;\n\t\t} else if(cellMatch[1] === \">\") {\n\t\t\t// Colspan\n\t\t\tcolSpanCount++;\n\t\t\t// Move to just before the `|` terminating the cell\n\t\t\tthis.parser.pos = cellRegExp.lastIndex - 1;\n\t\t} else if(cellMatch[1] === \"<\" && prevCell) {\n\t\t\tcolSpanCount = 1 + $tw.utils.getAttributeValueFromParseTreeNode(prevCell,\"colspan\",1);\n\t\t\t$tw.utils.addAttributeToParseTreeNode(prevCell,\"colspan\",colSpanCount);\n\t\t\tcolSpanCount = 1;\n\t\t\t// Move to just before the `|` terminating the cell\n\t\t\tthis.parser.pos = cellRegExp.lastIndex - 1;\n\t\t} else if(cellMatch[2]) {\n\t\t\t// End of row\n\t\t\tif(prevCell && colSpanCount > 1) {\n\t\t\t\tif(prevCell.attributes && prevCell.attributes && prevCell.attributes.colspan) {\n\t\t\t\t\t\tcolSpanCount += prevCell.attributes.colspan.value;\n\t\t\t\t} else {\n\t\t\t\t\tcolSpanCount -= 1;\n\t\t\t\t}\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(prevCell,\"colspan\",colSpanCount);\n\t\t\t}\n\t\t\tthis.parser.pos = cellRegExp.lastIndex - 1;\n\t\t\tbreak;\n\t\t} else {\n\t\t\t// For ordinary cells, step beyond the opening `|`\n\t\t\tthis.parser.pos++;\n\t\t\t// Look for a space at the start of the cell\n\t\t\tvar spaceLeft = false;\n\t\t\tvAlign = null;\n\t\t\tif(this.parser.source.substr(this.parser.pos).search(/^\\^([^\\^]|\\^\\^)/) === 0) {\n\t\t\t\tvAlign = \"top\";\n\t\t\t} else if(this.parser.source.substr(this.parser.pos).search(/^,([^,]|,,)/) === 0) {\n\t\t\t\tvAlign = \"bottom\";\n\t\t\t}\n\t\t\tif(vAlign) {\n\t\t\t\tthis.parser.pos++;\n\t\t\t}\n\t\t\tvar chr = this.parser.source.substr(this.parser.pos,1);\n\t\t\twhile(chr === \" \") {\n\t\t\t\tspaceLeft = true;\n\t\t\t\tthis.parser.pos++;\n\t\t\t\tchr = this.parser.source.substr(this.parser.pos,1);\n\t\t\t}\n\t\t\t// Check whether this is a heading cell\n\t\t\tvar cell;\n\t\t\tvar start = this.parser.pos;\n\t\t\tif(chr === \"!\") {\n\t\t\t\tthis.parser.pos++;\n\t\t\t\tcell = {type: \"element\", tag: \"th\", start: start, children: []};\n\t\t\t} else {\n\t\t\t\tcell = {type: \"element\", tag: \"td\", start: start, children: []};\n\t\t\t}\n\t\t\ttree.push(cell);\n\t\t\t// Record information about this cell\n\t\t\tprevCell = cell;\n\t\t\tprevColumns[col] = {rowSpanCount:1,element:cell};\n\t\t\t// Check for a colspan\n\t\t\tif(colSpanCount > 1) {\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(cell,\"colspan\",colSpanCount);\n\t\t\t\tcolSpanCount = 1;\n\t\t\t}\n\t\t\t// Parse the cell\n\t\t\tcell.children = this.parser.parseInlineRun(cellTermRegExp,{eatTerminator: true});\n\t\t\t// Set the alignment for the cell\n\t\t\tif(vAlign) {\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(cell,\"valign\",vAlign);\n\t\t\t}\n\t\t\tif(this.parser.source.substr(this.parser.pos - 2,1) === \" \") { // spaceRight\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(cell,\"align\",spaceLeft ? \"center\" : \"left\");\n\t\t\t} else if(spaceLeft) {\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(cell,\"align\",\"right\");\n\t\t\t}\n\t\t\t// Move back to the closing `|`\n\t\t\tthis.parser.pos--;\n\t\t\tcell.end = this.parser.pos;\n\t\t}\n\t\tcol++;\n\t\tcellRegExp.lastIndex = this.parser.pos;\n\t\tcellMatch = cellRegExp.exec(this.parser.source);\n\t}\n\treturn tree;\n};\n\nexports.parse = function() {\n\tvar rowContainerTypes = {\"c\":\"caption\", \"h\":\"thead\", \"\":\"tbody\", \"f\":\"tfoot\"},\n\t\ttable = {type: \"element\", tag: \"table\", children: []},\n\t\trowRegExp = /^\\|([^\\n]*)\\|([fhck]?)\\r?(?:\\n|$)/mg,\n\t\trowTermRegExp = /(\\|(?:[fhck]?)\\r?(?:\\n|$))/mg,\n\t\tprevColumns = [],\n\t\tcurrRowType,\n\t\trowContainer,\n\t\trowCount = 0;\n\t// Match the row\n\trowRegExp.lastIndex = this.parser.pos;\n\tvar rowMatch = rowRegExp.exec(this.parser.source);\n\twhile(rowMatch && rowMatch.index === this.parser.pos) {\n\t\tvar rowType = rowMatch[2];\n\t\t// Check if it is a class assignment\n\t\tif(rowType === \"k\") {\n\t\t\t$tw.utils.addClassToParseTreeNode(table,rowMatch[1]);\n\t\t\tthis.parser.pos = rowMatch.index + rowMatch[0].length;\n\t\t} else {\n\t\t\t// Otherwise, create a new row if this one is of a different type\n\t\t\tif(rowType !== currRowType) {\n\t\t\t\trowContainer = {type: \"element\", tag: rowContainerTypes[rowType], children: [], start: this.parser.pos, end: this.parser.pos};\n\t\t\t\ttable.children.push(rowContainer);\n\t\t\t\tcurrRowType = rowType;\n\t\t\t}\n\t\t\t// Is this a caption row?\n\t\t\tif(currRowType === \"c\") {\n\t\t\t\t// If so, move past the opening `|` of the row\n\t\t\t\tthis.parser.pos++;\n\t\t\t\t// Move the caption to the first row if it isn't already\n\t\t\t\tif(table.children.length !== 1) {\n\t\t\t\t\ttable.children.pop(); // Take rowContainer out of the children array\n\t\t\t\t\ttable.children.splice(0,0,rowContainer); // Insert it at the bottom\n\t\t\t\t}\n\t\t\t\t// Set the alignment - TODO: figure out why TW did this\n//\t\t\t\trowContainer.attributes.align = rowCount === 0 ? \"top\" : \"bottom\";\n\t\t\t\t// Parse the caption\n\t\t\t\trowContainer.children = this.parser.parseInlineRun(rowTermRegExp,{eatTerminator: true});\n\t\t\t} else {\n\t\t\t\t// Create the row\n\t\t\t\tvar theRow = {type: \"element\", tag: \"tr\", children: [], start: rowMatch.index};\n\t\t\t\t$tw.utils.addClassToParseTreeNode(theRow,rowCount%2 ? \"oddRow\" : \"evenRow\");\n\t\t\t\trowContainer.children.push(theRow);\n\t\t\t\t// Process the row\n\t\t\t\ttheRow.children = processRow.call(this,prevColumns);\n\t\t\t\tthis.parser.pos = rowMatch.index + rowMatch[0].length;\n\t\t\t\ttheRow.end = this.parser.pos;\n\t\t\t\t// Increment the row count\n\t\t\t\trowCount++;\n\t\t\t}\n\t\t\trowContainer.end = this.parser.pos;\n\t\t}\n\t\trowMatch = rowRegExp.exec(this.parser.source);\n\t}\n\treturn [table];\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/transcludeblock.js":{"title":"$:/core/modules/parsers/wikiparser/rules/transcludeblock.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/transcludeblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text rule for block-level transclusion. For example:\n\n```\n{{MyTiddler}}\n{{MyTiddler||TemplateTitle}}\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"transcludeblock\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\{\\{([^\\{\\}\\|]*)(?:\\|\\|([^\\|\\{\\}]+))?(?:\\|([^\\{\\}]+))?\\}\\}(?:\\r?\\n|$)/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Get the match details\n\tvar template = $tw.utils.trim(this.match[2]),\n\t\ttextRef = $tw.utils.trim(this.match[1]),\n\t\tparams = this.match[3] ? this.match[3].split(\"|\") : [];\n\t// Prepare the transclude widget\n\tvar transcludeNode = {\n\t\t\ttype: \"transclude\",\n\t\t\tattributes: {},\n\t\t\tisBlock: true\n\t\t};\n\t$tw.utils.each(params,function(paramValue,index) {\n\t\tvar name = \"\" + index;\n\t\ttranscludeNode.attributes[name] = {\n\t\t\tname: name,\n\t\t\ttype: \"string\",\n\t\t\tvalue: paramValue\n\t\t}\n\t});\n\t// Prepare the tiddler widget\n\tvar tr, targetTitle, targetField, targetIndex, tiddlerNode;\n\tif(textRef) {\n\t\ttr = $tw.utils.parseTextReference(textRef);\n\t\ttargetTitle = tr.title;\n\t\ttargetField = tr.field;\n\t\ttargetIndex = tr.index;\n\t\ttiddlerNode = {\n\t\t\ttype: \"tiddler\",\n\t\t\tattributes: {\n\t\t\t\ttiddler: {name: \"tiddler\", type: \"string\", value: targetTitle}\n\t\t\t},\n\t\t\tisBlock: true,\n\t\t\tchildren: [transcludeNode]\n\t\t};\n\t}\n\tif(template) {\n\t\ttranscludeNode.attributes[\"$tiddler\"] = {name: \"$tiddler\", type: \"string\", value: template};\n\t\tif(textRef) {\n\t\t\treturn [tiddlerNode];\n\t\t} else {\n\t\t\treturn [transcludeNode];\n\t\t}\n\t} else {\n\t\tif(textRef) {\n\t\t\ttranscludeNode.attributes[\"$tiddler\"] = {name: \"$tiddler\", type: \"string\", value: targetTitle};\n\t\t\tif(targetField) {\n\t\t\t\ttranscludeNode.attributes[\"$field\"] = {name: \"$field\", type: \"string\", value: targetField};\n\t\t\t}\n\t\t\tif(targetIndex) {\n\t\t\t\ttranscludeNode.attributes[\"$index\"] = {name: \"$index\", type: \"string\", value: targetIndex};\n\t\t\t}\n\t\t\treturn [tiddlerNode];\n\t\t} else {\n\t\t\treturn [transcludeNode];\n\t\t}\n\t}\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/transcludeinline.js":{"title":"$:/core/modules/parsers/wikiparser/rules/transcludeinline.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/transcludeinline.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text rule for inline-level transclusion. For example:\n\n```\n{{MyTiddler}}\n{{MyTiddler||TemplateTitle}}\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"transcludeinline\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\{\\{([^\\{\\}\\|]*)(?:\\|\\|([^\\|\\{\\}]+))?(?:\\|([^\\{\\}]+))?\\}\\}/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Get the match details\n\tvar template = $tw.utils.trim(this.match[2]),\n\t\ttextRef = $tw.utils.trim(this.match[1]),\n\t\tparams = this.match[3] ? this.match[3].split(\"|\") : [];\n\t// Prepare the transclude widget\n\tvar transcludeNode = {\n\t\t\ttype: \"transclude\",\n\t\t\tattributes: {}\n\t\t};\n\t$tw.utils.each(params,function(paramValue,index) {\n\t\tvar name = \"\" + index;\n\t\ttranscludeNode.attributes[name] = {\n\t\t\tname: name,\n\t\t\ttype: \"string\",\n\t\t\tvalue: paramValue\n\t\t}\n\t});\n\t// Prepare the tiddler widget\n\tvar tr, targetTitle, targetField, targetIndex, tiddlerNode;\n\tif(textRef) {\n\t\ttr = $tw.utils.parseTextReference(textRef);\n\t\ttargetTitle = tr.title;\n\t\ttargetField = tr.field;\n\t\ttargetIndex = tr.index;\n\t\ttiddlerNode = {\n\t\t\ttype: \"tiddler\",\n\t\t\tattributes: {\n\t\t\t\ttiddler: {name: \"tiddler\", type: \"string\", value: targetTitle}\n\t\t\t},\n\t\t\tchildren: [transcludeNode]\n\t\t};\n\t}\n\tif(template) {\n\t\ttranscludeNode.attributes[\"$tiddler\"] = {name: \"$tiddler\", type: \"string\", value: template};\n\t\tif(textRef) {\n\t\t\treturn [tiddlerNode];\n\t\t} else {\n\t\t\treturn [transcludeNode];\n\t\t}\n\t} else {\n\t\tif(textRef) {\n\t\t\ttranscludeNode.attributes[\"$tiddler\"] = {name: \"$tiddler\", type: \"string\", value: targetTitle};\n\t\t\tif(targetField) {\n\t\t\t\ttranscludeNode.attributes[\"$field\"] = {name: \"$field\", type: \"string\", value: targetField};\n\t\t\t}\n\t\t\tif(targetIndex) {\n\t\t\t\ttranscludeNode.attributes[\"$index\"] = {name: \"$index\", type: \"string\", value: targetIndex};\n\t\t\t}\n\t\t\treturn [tiddlerNode];\n\t\t} else {\n\t\t\treturn [transcludeNode];\n\t\t}\n\t}\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/typedblock.js":{"title":"$:/core/modules/parsers/wikiparser/rules/typedblock.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/typedblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text rule for typed blocks. For example:\n\n```\n$$$.js\nThis will be rendered as JavaScript\n$$$\n\n$$$.svg\n<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"150\" height=\"100\">\n  <circle cx=\"100\" cy=\"50\" r=\"40\" stroke=\"black\" stroke-width=\"2\" fill=\"red\" />\n</svg>\n$$$\n\n$$$text/vnd.tiddlywiki>text/html\nThis will be rendered as an //HTML representation// of WikiText\n$$$\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nexports.name = \"typedblock\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\$\\$\\$([^ >\\r\\n]*)(?: *> *([^ \\r\\n]+))?\\r?\\n/mg;\n};\n\nexports.parse = function() {\n\tvar reEnd = /\\r?\\n\\$\\$\\$\\r?(?:\\n|$)/mg;\n\t// Save the type\n\tvar parseType = this.match[1],\n\t\trenderType = this.match[2];\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\tvar start = this.parser.pos;\n\t// Look for the end of the block\n\treEnd.lastIndex = this.parser.pos;\n\tvar match = reEnd.exec(this.parser.source),\n\t\ttext;\n\t// Process the block\n\tif(match) {\n\t\ttext = this.parser.source.substring(this.parser.pos,match.index);\n\t\tthis.parser.pos = match.index + match[0].length;\n\t} else {\n\t\ttext = this.parser.source.substr(this.parser.pos);\n\t\tthis.parser.pos = this.parser.sourceLength;\n\t}\n\t// Parse the block according to the specified type\n\tvar parser = this.parser.wiki.parseText(parseType,text,{defaultType: \"text/plain\"});\n\t// If there's no render type, just return the parse tree\n\tif(!renderType) {\n\t\treturn parser.tree;\n\t} else {\n\t\t// Otherwise, render to the rendertype and return in a <PRE> tag\n\t\tvar widgetNode = this.parser.wiki.makeWidget(parser),\n\t\t\tcontainer = $tw.fakeDocument.createElement(\"div\");\n\t\twidgetNode.render(container,null);\n\t\ttext = renderType === \"text/html\" ? container.innerHTML : container.textContent;\n\t\treturn [{\n\t\t\ttype: \"element\",\n\t\t\ttag: \"pre\",\n\t\t\tchildren: [{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: text,\n\t\t\t\tstart: start,\n\t\t\t\tend: this.parser.pos\n\t\t\t}]\n\t\t}];\n\t}\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/whitespace.js":{"title":"$:/core/modules/parsers/wikiparser/rules/whitespace.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/whitespace.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki pragma rule for whitespace specifications\n\n```\n\\whitespace trim\n\\whitespace notrim\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"whitespace\";\nexports.types = {pragma: true};\n\n/*\nInstantiate parse rule\n*/\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\\\whitespace[^\\S\\n]/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\tvar self = this;\n\t// Move past the pragma invocation\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Parse whitespace delimited tokens terminated by a line break\n\tvar reMatch = /[^\\S\\n]*(\\S+)|(\\r?\\n)/mg,\n\t\ttokens = [];\n\treMatch.lastIndex = this.parser.pos;\n\tvar match = reMatch.exec(this.parser.source);\n\twhile(match && match.index === this.parser.pos) {\n\t\tthis.parser.pos = reMatch.lastIndex;\n\t\t// Exit if we've got the line break\n\t\tif(match[2]) {\n\t\t\tbreak;\n\t\t}\n\t\t// Process the token\n\t\tif(match[1]) {\n\t\t\ttokens.push(match[1]);\n\t\t}\n\t\t// Match the next token\n\t\tmatch = reMatch.exec(this.parser.source);\n\t}\n\t// Process the tokens\n\t$tw.utils.each(tokens,function(token) {\n\t\tswitch(token) {\n\t\t\tcase \"trim\":\n\t\t\t\tself.parser.configTrimWhiteSpace = true;\n\t\t\t\tbreak;\n\t\t\tcase \"notrim\":\n\t\t\t\tself.parser.configTrimWhiteSpace = false;\n\t\t\t\tbreak;\n\t\t}\n\t});\n\t// No parse tree nodes to return\n\treturn [];\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/wikilink.js":{"title":"$:/core/modules/parsers/wikiparser/rules/wikilink.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/wikilink.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for wiki links. For example:\n\n```\nAWikiLink\nAnotherLink\n~SuppressedLink\n```\n\nPrecede a camel case word with `~` to prevent it from being recognised as a link.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"wikilink\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = new RegExp($tw.config.textPrimitives.unWikiLink + \"?\" + $tw.config.textPrimitives.wikiLink,\"mg\");\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Get the details of the match\n\tvar linkText = this.match[0];\n\t// Move past the macro call\n\tvar start = this.parser.pos;\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// If the link starts with the unwikilink character then just output it as plain text\n\tif(linkText.substr(0,1) === $tw.config.textPrimitives.unWikiLink) {\n\t\treturn [{type: \"text\", text: linkText.substr(1)}];\n\t}\n\t// If the link has been preceded with a blocked letter then don't treat it as a link\n\tif(this.match.index > 0) {\n\t\tvar preRegExp = new RegExp($tw.config.textPrimitives.blockPrefixLetters,\"mg\");\n\t\tpreRegExp.lastIndex = this.match.index-1;\n\t\tvar preMatch = preRegExp.exec(this.parser.source);\n\t\tif(preMatch && preMatch.index === this.match.index-1) {\n\t\t\treturn [{type: \"text\", text: linkText}];\n\t\t}\n\t}\n\treturn [{\n\t\ttype: \"link\",\n\t\tattributes: {\n\t\t\tto: {type: \"string\", value: linkText}\n\t\t},\n\t\tchildren: [{\n\t\t\ttype: \"text\",\n\t\t\ttext: linkText,\n\t\t\tstart: start,\n\t\t\tend: this.parser.pos\n\t\t}]\n\t}];\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/rules/wikilinkprefix.js":{"title":"$:/core/modules/parsers/wikiparser/rules/wikilinkprefix.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/wikilinkprefix.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for suppressed wiki links. For example:\n\n```\n~SuppressedLink\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"wikilinkprefix\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = new RegExp($tw.config.textPrimitives.unWikiLink + $tw.config.textPrimitives.wikiLink,\"mg\");\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Get the details of the match\n\tvar linkText = this.match[0];\n\t// Move past the wikilink\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Return the link without unwikilink character as plain text\n\treturn [{type: \"text\", text: linkText.substr(1)}];\n};\n\n})();\n","type":"application/javascript","module-type":"wikirule"},"$:/core/modules/parsers/wikiparser/wikiparser.js":{"title":"$:/core/modules/parsers/wikiparser/wikiparser.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/wikiparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe wiki text parser processes blocks of source text into a parse tree.\n\nThe parse tree is made up of nested arrays of these JavaScript objects:\n\n\t{type: \"element\", tag: <string>, attributes: {}, children: []} - an HTML element\n\t{type: \"text\", text: <string>} - a text node\n\t{type: \"entity\", value: <string>} - an entity\n\t{type: \"raw\", html: <string>} - raw HTML\n\nAttributes are stored as hashmaps of the following objects:\n\n\t{type: \"string\", value: <string>} - literal string\n\t{type: \"indirect\", textReference: <textReference>} - indirect through a text reference\n\t{type: \"macro\", macro: <TBD>} - indirect through a macro invocation\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\ntype: content type of text\ntext: text to be parsed\noptions: see below:\n\tparseAsInline: true to parse text as inline instead of block\n\twiki: reference to wiki to use\n\t_canonical_uri: optional URI of content if text is missing or empty\n\tconfigTrimWhiteSpace: true to trim whitespace\n*/\nvar WikiParser = function(type,text,options) {\n\tthis.wiki = options.wiki;\n\tvar self = this;\n\t// Check for an externally linked tiddler\n\tif($tw.browser && (text || \"\") === \"\" && options._canonical_uri) {\n\t\tthis.loadRemoteTiddler(options._canonical_uri);\n\t\ttext = $tw.language.getRawString(\"LazyLoadingWarning\");\n\t}\n\t// Save the parse text\n\tthis.type = type || \"text/vnd.tiddlywiki\";\n\tthis.source = text || \"\";\n\tthis.sourceLength = this.source.length;\n\t// Flag for ignoring whitespace\n\tthis.configTrimWhiteSpace = options.configTrimWhiteSpace !== undefined ? options.configTrimWhiteSpace : false;\n\t// Parser mode\n\tthis.parseAsInline = options.parseAsInline;\n\t// Set current parse position\n\tthis.pos = 0;\n\t// Start with empty output\n\tthis.tree = [];\n\t// Assemble the rule classes we're going to use\n\tvar pragmaRuleClasses, blockRuleClasses, inlineRuleClasses;\n\tif(options.rules) {\n\t\tpragmaRuleClasses = options.rules.pragma;\n\t\tblockRuleClasses = options.rules.block;\n\t\tinlineRuleClasses = options.rules.inline;\n\t} else {\n\t\t// Setup the rule classes if we don't have them already\n\t\tif(!this.pragmaRuleClasses) {\n\t\t\tWikiParser.prototype.pragmaRuleClasses = $tw.modules.createClassesFromModules(\"wikirule\",\"pragma\",$tw.WikiRuleBase);\n\t\t\tthis.setupRules(WikiParser.prototype.pragmaRuleClasses,\"$:/config/WikiParserRules/Pragmas/\");\n\t\t}\n\t\tpragmaRuleClasses = this.pragmaRuleClasses;\n\t\tif(!this.blockRuleClasses) {\n\t\t\tWikiParser.prototype.blockRuleClasses = $tw.modules.createClassesFromModules(\"wikirule\",\"block\",$tw.WikiRuleBase);\n\t\t\tthis.setupRules(WikiParser.prototype.blockRuleClasses,\"$:/config/WikiParserRules/Block/\");\n\t\t}\n\t\tblockRuleClasses = this.blockRuleClasses;\n\t\tif(!this.inlineRuleClasses) {\n\t\t\tWikiParser.prototype.inlineRuleClasses = $tw.modules.createClassesFromModules(\"wikirule\",\"inline\",$tw.WikiRuleBase);\n\t\t\tthis.setupRules(WikiParser.prototype.inlineRuleClasses,\"$:/config/WikiParserRules/Inline/\");\n\t\t}\n\t\tinlineRuleClasses = this.inlineRuleClasses;\n\t}\n\t// Instantiate the pragma parse rules\n\tthis.pragmaRules = this.instantiateRules(pragmaRuleClasses,\"pragma\",0);\n\t// Instantiate the parser block and inline rules\n\tthis.blockRules = this.instantiateRules(blockRuleClasses,\"block\",0);\n\tthis.inlineRules = this.instantiateRules(inlineRuleClasses,\"inline\",0);\n\t// Parse any pragmas\n\tvar topBranch = this.parsePragmas();\n\t// Parse the text into inline runs or blocks\n\tif(this.parseAsInline) {\n\t\ttopBranch.push.apply(topBranch,this.parseInlineRun());\n\t} else {\n\t\ttopBranch.push.apply(topBranch,this.parseBlocks());\n\t}\n\t// Build rules' name map\n\tthis.usingRuleMap = {};\n\t$tw.utils.each(this.pragmaRules, function (ruleInfo) { self.usingRuleMap[ruleInfo.rule.name] = Object.getPrototypeOf(ruleInfo.rule); });\n\t$tw.utils.each(this.blockRules, function (ruleInfo) { self.usingRuleMap[ruleInfo.rule.name] = Object.getPrototypeOf(ruleInfo.rule); });\n\t$tw.utils.each(this.inlineRules, function (ruleInfo) { self.usingRuleMap[ruleInfo.rule.name] = Object.getPrototypeOf(ruleInfo.rule); });\n\t// Return the parse tree\n};\n\n/*\n*/\nWikiParser.prototype.loadRemoteTiddler = function(url) {\n\tvar self = this;\n\t$tw.utils.httpRequest({\n\t\turl: url,\n\t\ttype: \"GET\",\n\t\tcallback: function(err,data) {\n\t\t\tif(!err) {\n\t\t\t\tvar tiddlers = self.wiki.deserializeTiddlers(\".tid\",data,self.wiki.getCreationFields());\n\t\t\t\t$tw.utils.each(tiddlers,function(tiddler) {\n\t\t\t\t\ttiddler[\"_canonical_uri\"] = url;\n\t\t\t\t});\n\t\t\t\tif(tiddlers) {\n\t\t\t\t\tself.wiki.addTiddlers(tiddlers);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n};\n\n/*\n*/\nWikiParser.prototype.setupRules = function(proto,configPrefix) {\n\tvar self = this;\n\tif(!$tw.safeMode) {\n\t\t$tw.utils.each(proto,function(object,name) {\n\t\t\tif(self.wiki.getTiddlerText(configPrefix + name,\"enable\") !== \"enable\") {\n\t\t\t\tdelete proto[name];\n\t\t\t}\n\t\t});\n\t}\n};\n\n/*\nInstantiate an array of parse rules\n*/\nWikiParser.prototype.instantiateRules = function(classes,type,startPos) {\n\tvar rulesInfo = [],\n\t\tself = this;\n\t$tw.utils.each(classes,function(RuleClass) {\n\t\t// Instantiate the rule\n\t\tvar rule = new RuleClass(self);\n\t\trule.is = {};\n\t\trule.is[type] = true;\n\t\trule.init(self);\n\t\tvar matchIndex = rule.findNextMatch(startPos);\n\t\tif(matchIndex !== undefined) {\n\t\t\trulesInfo.push({\n\t\t\t\trule: rule,\n\t\t\t\tmatchIndex: matchIndex\n\t\t\t});\n\t\t}\n\t});\n\treturn rulesInfo;\n};\n\n/*\nSkip any whitespace at the current position. Options are:\n\ttreatNewlinesAsNonWhitespace: true if newlines are NOT to be treated as whitespace\n*/\nWikiParser.prototype.skipWhitespace = function(options) {\n\toptions = options || {};\n\tvar whitespaceRegExp = options.treatNewlinesAsNonWhitespace ? /([^\\S\\n]+)/mg : /(\\s+)/mg;\n\twhitespaceRegExp.lastIndex = this.pos;\n\tvar whitespaceMatch = whitespaceRegExp.exec(this.source);\n\tif(whitespaceMatch && whitespaceMatch.index === this.pos) {\n\t\tthis.pos = whitespaceRegExp.lastIndex;\n\t}\n};\n\n/*\nGet the next match out of an array of parse rule instances\n*/\nWikiParser.prototype.findNextMatch = function(rules,startPos) {\n\t// Find the best matching rule by finding the closest match position\n\tvar matchingRule,\n\t\tmatchingRulePos = this.sourceLength;\n\t// Step through each rule\n\tfor(var t=0; t<rules.length; t++) {\n\t\tvar ruleInfo = rules[t];\n\t\t// Ask the rule to get the next match if we've moved past the current one\n\t\tif(ruleInfo.matchIndex !== undefined  && ruleInfo.matchIndex < startPos) {\n\t\t\truleInfo.matchIndex = ruleInfo.rule.findNextMatch(startPos);\n\t\t}\n\t\t// Adopt this match if it's closer than the current best match\n\t\tif(ruleInfo.matchIndex !== undefined && ruleInfo.matchIndex <= matchingRulePos) {\n\t\t\tmatchingRule = ruleInfo;\n\t\t\tmatchingRulePos = ruleInfo.matchIndex;\n\t\t}\n\t}\n\treturn matchingRule;\n};\n\n/*\nParse any pragmas at the beginning of a block of parse text\n*/\nWikiParser.prototype.parsePragmas = function() {\n\tvar currentTreeBranch = this.tree;\n\twhile(true) {\n\t\tvar savedPos = this.pos;\n\t\t// Skip whitespace\n\t\tthis.skipWhitespace();\n\t\t// Check for the end of the text\n\t\tif(this.pos >= this.sourceLength) {\n\t\t\tbreak;\n\t\t}\n\t\t// Check if we've arrived at a pragma rule match\n\t\tvar nextMatch = this.findNextMatch(this.pragmaRules,this.pos);\n\t\t// If not, just exit\n\t\tif(!nextMatch || nextMatch.matchIndex !== this.pos) {\n\t\t\tthis.pos = savedPos;\n\t\t\tbreak;\n\t\t}\n\t\t// Process the pragma rule\n\t\tvar start = this.pos;\n\t\tvar subTree = nextMatch.rule.parse();\n\t\tif(subTree.length > 0) {\n\t\t\t// Set the start and end positions of the pragma rule if\n\t\t\tif (subTree[0].start === undefined) subTree[0].start = start;\n\t\t\tif (subTree[subTree.length - 1].end === undefined) subTree[subTree.length - 1].end = this.pos;\n\t\t\t$tw.utils.each(subTree, function (node) { node.rule = nextMatch.rule.name; });\n\t\t\t// Quick hack; we only cope with a single parse tree node being returned, which is true at the moment\n\t\t\tcurrentTreeBranch.push.apply(currentTreeBranch,subTree);\n\t\t\tsubTree[0].children = [];\n\t\t\tcurrentTreeBranch = subTree[0].children;\n\t\t}\n\t\t// Skip whitespace after the pragma\n\t\tthis.skipWhitespace();\n\t}\n\treturn currentTreeBranch;\n};\n\n/*\nParse a block from the current position\n\tterminatorRegExpString: optional regular expression string that identifies the end of plain paragraphs. Must not include capturing parenthesis\n*/\nWikiParser.prototype.parseBlock = function(terminatorRegExpString) {\n\tvar terminatorRegExp = terminatorRegExpString ? new RegExp(terminatorRegExpString + \"|\\\\r?\\\\n\\\\r?\\\\n\",\"mg\") : /(\\r?\\n\\r?\\n)/mg;\n\tthis.skipWhitespace();\n\tif(this.pos >= this.sourceLength) {\n\t\treturn [];\n\t}\n\t// Look for a block rule that applies at the current position\n\tvar nextMatch = this.findNextMatch(this.blockRules,this.pos);\n\tif(nextMatch && nextMatch.matchIndex === this.pos) {\n\t\tvar start = this.pos;\n\t\tvar subTree = nextMatch.rule.parse();\n\t\t// Set the start and end positions of the first and last blocks if they're not already set\n\t\tif (subTree.length > 0) {\n\t\t\tif (subTree[0].start === undefined) subTree[0].start = start;\n\t\t\tif (subTree[subTree.length - 1].end === undefined) subTree[subTree.length - 1].end = this.pos;\n\t\t}\n\t\t$tw.utils.each(subTree, function (node) { node.rule = nextMatch.rule.name; });\n\t\treturn subTree;\n\t}\n\t// Treat it as a paragraph if we didn't find a block rule\n\tvar start = this.pos;\n\tvar children = this.parseInlineRun(terminatorRegExp);\n\tvar end = this.pos;\n\treturn [{type: \"element\", tag: \"p\", children: children, start: start, end: end }];\n};\n\n/*\nParse a series of blocks of text until a terminating regexp is encountered or the end of the text\n\tterminatorRegExpString: terminating regular expression\n*/\nWikiParser.prototype.parseBlocks = function(terminatorRegExpString) {\n\tif(terminatorRegExpString) {\n\t\treturn this.parseBlocksTerminated(terminatorRegExpString);\n\t} else {\n\t\treturn this.parseBlocksUnterminated();\n\t}\n};\n\n/*\nParse a block from the current position to the end of the text\n*/\nWikiParser.prototype.parseBlocksUnterminated = function() {\n\tvar tree = [];\n\twhile(this.pos < this.sourceLength) {\n\t\ttree.push.apply(tree,this.parseBlock());\n\t}\n\treturn tree;\n};\n\n/*\nParse blocks of text until a terminating regexp is encountered. Wrapper for parseBlocksTerminatedExtended that just returns the parse tree\n*/\nWikiParser.prototype.parseBlocksTerminated = function(terminatorRegExpString) {\n\tvar ex = this.parseBlocksTerminatedExtended(terminatorRegExpString);\n\treturn ex.tree;\n};\n\n/*\nParse blocks of text until a terminating regexp is encountered\n*/\nWikiParser.prototype.parseBlocksTerminatedExtended = function(terminatorRegExpString) {\n\tvar terminatorRegExp = new RegExp(terminatorRegExpString,\"mg\"),\n\t\tresult = {\n\t\t\ttree: []\n\t\t};\n\t// Skip any whitespace\n\tthis.skipWhitespace();\n\t//  Check if we've got the end marker\n\tterminatorRegExp.lastIndex = this.pos;\n\tvar match = terminatorRegExp.exec(this.source);\n\t// Parse the text into blocks\n\twhile(this.pos < this.sourceLength && !(match && match.index === this.pos)) {\n\t\tvar blocks = this.parseBlock(terminatorRegExpString);\n\t\tresult.tree.push.apply(result.tree,blocks);\n\t\t// Skip any whitespace\n\t\tthis.skipWhitespace();\n\t\t//  Check if we've got the end marker\n\t\tterminatorRegExp.lastIndex = this.pos;\n\t\tmatch = terminatorRegExp.exec(this.source);\n\t}\n\tif(match && match.index === this.pos) {\n\t\tthis.pos = match.index + match[0].length;\n\t\tresult.match = match;\n\t}\n\treturn result;\n};\n\n/*\nParse a run of text at the current position\n\tterminatorRegExp: a regexp at which to stop the run\n\toptions: see below\nOptions available:\n\teatTerminator: move the parse position past any encountered terminator (default false)\n*/\nWikiParser.prototype.parseInlineRun = function(terminatorRegExp,options) {\n\tif(terminatorRegExp) {\n\t\treturn this.parseInlineRunTerminated(terminatorRegExp,options);\n\t} else {\n\t\treturn this.parseInlineRunUnterminated(options);\n\t}\n};\n\nWikiParser.prototype.parseInlineRunUnterminated = function(options) {\n\tvar tree = [];\n\t// Find the next occurrence of an inline rule\n\tvar nextMatch = this.findNextMatch(this.inlineRules,this.pos);\n\t// Loop around the matches until we've reached the end of the text\n\twhile(this.pos < this.sourceLength && nextMatch) {\n\t\t// Process the text preceding the run rule\n\t\tif(nextMatch.matchIndex > this.pos) {\n\t\t\tthis.pushTextWidget(tree,this.source.substring(this.pos,nextMatch.matchIndex),this.pos,nextMatch.matchIndex);\n\t\t\tthis.pos = nextMatch.matchIndex;\n\t\t}\n\t\t// Process the run rule\n\t\tvar start = this.pos;\n\t\tvar subTree = nextMatch.rule.parse();\n\t\t// Set the start and end positions of the first and last child if they're not already set\n\t\tif (subTree.length > 0) {\n\t\t\t// Set the start and end positions of the first and last child if they're not already set\n\t\t\tif (subTree[0].start === undefined) subTree[0].start = start;\n\t\t\tif (subTree[subTree.length - 1].end === undefined) subTree[subTree.length - 1].end = this.pos;\n\t\t}\n\t\t$tw.utils.each(subTree, function (node) { node.rule = nextMatch.rule.name; });\n\t\ttree.push.apply(tree,subTree);\n\t\t// Look for the next run rule\n\t\tnextMatch = this.findNextMatch(this.inlineRules,this.pos);\n\t}\n\t// Process the remaining text\n\tif(this.pos < this.sourceLength) {\n\t\tthis.pushTextWidget(tree,this.source.substr(this.pos),this.pos,this.sourceLength);\n\t}\n\tthis.pos = this.sourceLength;\n\treturn tree;\n};\n\nWikiParser.prototype.parseInlineRunTerminated = function(terminatorRegExp,options) {\n\tvar ex = this.parseInlineRunTerminatedExtended(terminatorRegExp,options);\n\treturn ex.tree;\n};\n\nWikiParser.prototype.parseInlineRunTerminatedExtended = function(terminatorRegExp,options) {\n\toptions = options || {};\n\tvar tree = [];\n\t// Find the next occurrence of the terminator\n\tterminatorRegExp.lastIndex = this.pos;\n\tvar terminatorMatch = terminatorRegExp.exec(this.source);\n\t// Find the next occurrence of a inlinerule\n\tvar inlineRuleMatch = this.findNextMatch(this.inlineRules,this.pos);\n\t// Loop around until we've reached the end of the text\n\twhile(this.pos < this.sourceLength && (terminatorMatch || inlineRuleMatch)) {\n\t\t// Return if we've found the terminator, and it precedes any inline rule match\n\t\tif(terminatorMatch) {\n\t\t\tif(!inlineRuleMatch || inlineRuleMatch.matchIndex >= terminatorMatch.index) {\n\t\t\t\tif(terminatorMatch.index > this.pos) {\n\t\t\t\t\tthis.pushTextWidget(tree,this.source.substring(this.pos,terminatorMatch.index),this.pos,terminatorMatch.index);\n\t\t\t\t}\n\t\t\t\tthis.pos = terminatorMatch.index;\n\t\t\t\tif(options.eatTerminator) {\n\t\t\t\t\tthis.pos += terminatorMatch[0].length;\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tmatch: terminatorMatch,\n\t\t\t\t\ttree: tree\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\t// Process any inline rule, along with the text preceding it\n\t\tif(inlineRuleMatch) {\n\t\t\t// Preceding text\n\t\t\tif(inlineRuleMatch.matchIndex > this.pos) {\n\t\t\t\tthis.pushTextWidget(tree,this.source.substring(this.pos,inlineRuleMatch.matchIndex),this.pos,inlineRuleMatch.matchIndex);\n\t\t\t\tthis.pos = inlineRuleMatch.matchIndex;\n\t\t\t}\n\t\t\t// Process the inline rule\n\t\t\tvar start = this.pos;\n\t\t\tvar subTree = inlineRuleMatch.rule.parse();\n\t\t\t// Set the start and end positions of the first and last child if they're not already set\n\t\t\tif (subTree.length > 0) {\n\t\t\t\tif (subTree[0].start === undefined) subTree[0].start = start;\n\t\t\t\tif (subTree[subTree.length - 1].end === undefined) subTree[subTree.length - 1].end = this.pos;\n\t\t\t}\n\t\t\t$tw.utils.each(subTree, function (node) { node.rule = inlineRuleMatch.rule.name; });\n\t\t\ttree.push.apply(tree,subTree);\n\t\t\t// Look for the next inline rule\n\t\t\tinlineRuleMatch = this.findNextMatch(this.inlineRules,this.pos);\n\t\t\t// Look for the next terminator match\n\t\t\tterminatorRegExp.lastIndex = this.pos;\n\t\t\tterminatorMatch = terminatorRegExp.exec(this.source);\n\t\t}\n\t}\n\t// Process the remaining text\n\tif(this.pos < this.sourceLength) {\n\t\tthis.pushTextWidget(tree,this.source.substr(this.pos),this.pos,this.sourceLength);\n\t}\n\tthis.pos = this.sourceLength;\n\treturn {\n\t\ttree: tree\n\t};\n};\n\n/*\nPush a text widget onto an array, respecting the configTrimWhiteSpace setting\n*/\nWikiParser.prototype.pushTextWidget = function(array,text,start,end) {\n\tif(this.configTrimWhiteSpace) {\n\t\ttext = $tw.utils.trim(text);\n\t}\n\tif(text) {\n\t\tarray.push({type: \"text\", text: text, start: start, end: end});\n\t}\n};\n\n/*\nParse zero or more class specifiers `.classname`\n*/\nWikiParser.prototype.parseClasses = function() {\n\tvar classRegExp = /\\.([^\\s\\.]+)/mg,\n\t\tclassNames = [];\n\tclassRegExp.lastIndex = this.pos;\n\tvar match = classRegExp.exec(this.source);\n\twhile(match && match.index === this.pos) {\n\t\tthis.pos = match.index + match[0].length;\n\t\tclassNames.push(match[1]);\n\t\tmatch = classRegExp.exec(this.source);\n\t}\n\treturn classNames;\n};\n\n/*\nAmend the rules used by this instance of the parser\n\ttype: `only` keeps just the named rules, `except` keeps all but the named rules\n\tnames: array of rule names\n*/\nWikiParser.prototype.amendRules = function(type,names) {\n\tnames = names || [];\n\t// Define the filter function\n\tvar target;\n\tif(type === \"only\") {\n\t\ttarget = true;\n\t} else if(type === \"except\") {\n\t\ttarget = false;\n\t} else {\n\t\treturn;\n\t}\n\t// Define a function to process each of our rule arrays\n\tvar processRuleArray = function(ruleArray) {\n\t\tfor(var t=ruleArray.length-1; t>=0; t--) {\n\t\t\tif((names.indexOf(ruleArray[t].rule.name) === -1) === target) {\n\t\t\t\truleArray.splice(t,1);\n\t\t\t}\n\t\t}\n\t};\n\t// Process each rule array\n\tprocessRuleArray(this.pragmaRules);\n\tprocessRuleArray(this.blockRules);\n\tprocessRuleArray(this.inlineRules);\n};\n\nexports[\"text/vnd.tiddlywiki\"] = WikiParser;\n\n})();\n","type":"application/javascript","module-type":"parser"},"$:/core/modules/parsers/wikiparser/rules/wikirulebase.js":{"title":"$:/core/modules/parsers/wikiparser/rules/wikirulebase.js","text":"/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/wikirulebase.js\ntype: application/javascript\nmodule-type: global\n\nBase class for wiki parser rules\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nThis constructor is always overridden with a blank constructor, and so shouldn't be used\n*/\nvar WikiRuleBase = function() {\n};\n\n/*\nTo be overridden by individual rules\n*/\nWikiRuleBase.prototype.init = function(parser) {\n\tthis.parser = parser;\n};\n\n/*\nDefault implementation of findNextMatch uses RegExp matching\n*/\nWikiRuleBase.prototype.findNextMatch = function(startPos) {\n\tthis.matchRegExp.lastIndex = startPos;\n\tthis.match = this.matchRegExp.exec(this.parser.source);\n\treturn this.match ? this.match.index : undefined;\n};\n\nexports.WikiRuleBase = WikiRuleBase;\n\n})();\n","type":"application/javascript","module-type":"global"},"$:/core/modules/pluginswitcher.js":{"title":"$:/core/modules/pluginswitcher.js","text":"/*\\\ntitle: $:/core/modules/pluginswitcher.js\ntype: application/javascript\nmodule-type: global\n\nManages switching plugins for themes and languages.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\noptions:\nwiki: wiki store to be used\npluginType: type of plugin to be switched\ncontrollerTitle: title of tiddler used to control switching of this resource\ndefaultPlugins: array of default plugins to be used if nominated plugin isn't found\nonSwitch: callback when plugin is switched (single parameter is array of plugin titles)\n*/\nfunction PluginSwitcher(options) {\n\tthis.wiki = options.wiki;\n\tthis.pluginType = options.pluginType;\n\tthis.controllerTitle = options.controllerTitle;\n\tthis.defaultPlugins = options.defaultPlugins || [];\n\tthis.onSwitch = options.onSwitch;\n\t// Switch to the current plugin\n\tthis.switchPlugins();\n\t// Listen for changes to the selected plugin\n\tvar self = this;\n\tthis.wiki.addEventListener(\"change\",function(changes) {\n\t\tif($tw.utils.hop(changes,self.controllerTitle)) {\n\t\t\tself.switchPlugins();\n\t\t}\n\t});\n}\n\nPluginSwitcher.prototype.switchPlugins = function() {\n\t// Get the name of the current theme\n\tvar selectedPluginTitle = this.wiki.getTiddlerText(this.controllerTitle);\n\t// If it doesn't exist, then fallback to one of the default themes\n\tvar index = 0;\n\twhile(!this.wiki.getTiddler(selectedPluginTitle) && index < this.defaultPlugins.length) {\n\t\tselectedPluginTitle = this.defaultPlugins[index++];\n\t}\n\t// Accumulate the titles of the plugins that we need to load\n\tvar plugins = [],\n\t\tself = this,\n\t\taccumulatePlugin = function(title) {\n\t\t\tvar tiddler = self.wiki.getTiddler(title);\n\t\t\tif(tiddler && tiddler.isPlugin() && plugins.indexOf(title) === -1) {\n\t\t\t\tplugins.push(title);\n\t\t\t\tvar pluginInfo = $tw.utils.parseJSONSafe(self.wiki.getTiddlerText(title)),\n\t\t\t\t\tdependents = $tw.utils.parseStringArray(tiddler.fields.dependents || \"\");\n\t\t\t\t$tw.utils.each(dependents,function(title) {\n\t\t\t\t\taccumulatePlugin(title);\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\taccumulatePlugin(selectedPluginTitle);\n\t// Read the plugin info for the incoming plugins\n\tvar changes = $tw.wiki.readPluginInfo(plugins);\n\t// Unregister any existing theme tiddlers\n\tvar unregisteredTiddlers = $tw.wiki.unregisterPluginTiddlers(this.pluginType);\n\t// Register any new theme tiddlers\n\tvar registeredTiddlers = $tw.wiki.registerPluginTiddlers(this.pluginType,plugins);\n\t// Unpack the current theme tiddlers\n\t$tw.wiki.unpackPluginTiddlers();\n\t// Call the switch handler\n\tif(this.onSwitch) {\n\t\tthis.onSwitch(plugins);\n\t}\n};\n\nexports.PluginSwitcher = PluginSwitcher;\n\n})();\n","type":"application/javascript","module-type":"global"},"$:/core/modules/saver-handler.js":{"title":"$:/core/modules/saver-handler.js","text":"/*\\\ntitle: $:/core/modules/saver-handler.js\ntype: application/javascript\nmodule-type: global\n\nThe saver handler tracks changes to the store and handles saving the entire wiki via saver modules.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInstantiate the saver handler with the following options:\nwiki: wiki to be synced\ndirtyTracking: true if dirty tracking should be performed\n*/\nfunction SaverHandler(options) {\n\tvar self = this;\n\tthis.wiki = options.wiki;\n\tthis.dirtyTracking = options.dirtyTracking;\n\tthis.preloadDirty = options.preloadDirty || [];\n\tthis.pendingAutoSave = false;\n\t// Make a logger\n\tthis.logger = new $tw.utils.Logger(\"saver-handler\");\n\t// Initialise our savers\n\tif($tw.browser) {\n\t\tthis.initSavers();\n\t}\n\t// Only do dirty tracking if required\n\tif($tw.browser && this.dirtyTracking) {\n\t\t// Compile the dirty tiddler filter\n\t\tthis.filterFn = this.wiki.compileFilter(this.wiki.getTiddlerText(this.titleSyncFilter));\n\t\t// Count of changes that have not yet been saved\n\t\tvar filteredChanges = self.filterFn.call(self.wiki,function(iterator) {\n\t\t\t\t$tw.utils.each(self.preloadDirty,function(title) {\n\t\t\t\t\tvar tiddler = self.wiki.getTiddler(title);\n\t\t\t\t\titerator(tiddler,title);\n\t\t\t\t});\n\t\t});\n\t\tthis.numChanges = filteredChanges.length;\n\t\t// Listen out for changes to tiddlers\n\t\tthis.wiki.addEventListener(\"change\",function(changes) {\n\t\t\t// Filter the changes so that we only count changes to tiddlers that we care about\n\t\t\tvar filteredChanges = self.filterFn.call(self.wiki,function(iterator) {\n\t\t\t\t$tw.utils.each(changes,function(change,title) {\n\t\t\t\t\tvar tiddler = self.wiki.getTiddler(title);\n\t\t\t\t\titerator(tiddler,title);\n\t\t\t\t});\n\t\t\t});\n\t\t\t// Adjust the number of changes\n\t\t\tself.numChanges += filteredChanges.length;\n\t\t\tself.updateDirtyStatus();\n\t\t\t// Do any autosave if one is pending and there's no more change events\n\t\t\tif(self.pendingAutoSave && self.wiki.getSizeOfTiddlerEventQueue() === 0) {\n\t\t\t\t// Check if we're dirty\n\t\t\t\tif(self.numChanges > 0) {\n\t\t\t\t\tself.saveWiki({\n\t\t\t\t\t\tmethod: \"autosave\",\n\t\t\t\t\t\tdownloadType: \"text/plain\"\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tself.pendingAutoSave = false;\n\t\t\t}\n\t\t});\n\t\t// Listen for the autosave event\n\t\t$tw.rootWidget.addEventListener(\"tm-auto-save-wiki\",function(event) {\n\t\t\t// Do the autosave unless there are outstanding tiddler change events\n\t\t\tif(self.wiki.getSizeOfTiddlerEventQueue() === 0) {\n\t\t\t\t// Check if we're dirty\n\t\t\t\tif(self.numChanges > 0) {\n\t\t\t\t\tself.saveWiki({\n\t\t\t\t\t\tmethod: \"autosave\",\n\t\t\t\t\t\tdownloadType: \"text/plain\"\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Otherwise put ourselves in the \"pending autosave\" state and wait for the change event before we do the autosave\n\t\t\t\tself.pendingAutoSave = true;\n\t\t\t}\n\t\t});\n\t\t// Set up our beforeunload handler\n\t\t$tw.addUnloadTask(function(event) {\n\t\t\tvar confirmationMessage;\n\t\t\tif(self.isDirty()) {\n\t\t\t\tconfirmationMessage = $tw.language.getString(\"UnsavedChangesWarning\");\n\t\t\t\tevent.returnValue = confirmationMessage; // Gecko\n\t\t\t}\n\t\t\treturn confirmationMessage;\n\t\t});\n\t}\n\t// Install the save action handlers\n\tif($tw.browser) {\n\t\t$tw.rootWidget.addEventListener(\"tm-save-wiki\",function(event) {\n\t\t\tself.saveWiki({\n\t\t\t\twiki: event.widget.wiki,\n\t\t\t\ttemplate: event.param,\n\t\t\t\tdownloadType: \"text/plain\",\n\t\t\t\tvariables: event.paramObject\n\t\t\t});\n\t\t});\n\t\t$tw.rootWidget.addEventListener(\"tm-download-file\",function(event) {\n\t\t\tself.saveWiki({\n\t\t\t\twiki: event.widget.wiki,\n\t\t\t\tmethod: \"download\",\n\t\t\t\ttemplate: event.param,\n\t\t\t\tdownloadType: \"text/plain\",\n\t\t\t\tvariables: event.paramObject\n\t\t\t});\n\t\t});\n\t}\n}\n\nSaverHandler.prototype.titleSyncFilter = \"$:/config/SaverFilter\";\nSaverHandler.prototype.titleAutoSave = \"$:/config/AutoSave\";\nSaverHandler.prototype.titleSavedNotification = \"$:/language/Notifications/Save/Done\";\n\n/*\nSelect the appropriate saver modules and set them up\n*/\nSaverHandler.prototype.initSavers = function(moduleType) {\n\tmoduleType = moduleType || \"saver\";\n\t// Instantiate the available savers\n\tthis.savers = [];\n\tvar self = this;\n\t$tw.modules.forEachModuleOfType(moduleType,function(title,module) {\n\t\tif(module.canSave(self)) {\n\t\t\tself.savers.push(module.create(self.wiki));\n\t\t}\n\t});\n\t// Sort the savers into priority order\n\tthis.savers.sort(function(a,b) {\n\t\tif(a.info.priority < b.info.priority) {\n\t\t\treturn -1;\n\t\t} else {\n\t\t\tif(a.info.priority > b.info.priority) {\n\t\t\t\treturn +1;\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n};\n\n/*\nSave the wiki contents. Options are:\n\tmethod: \"save\", \"autosave\" or \"download\"\n\ttemplate: the tiddler containing the template to save\n\tdownloadType: the content type for the saved file\n\twiki: optional wiki, overriding the default wiki specified in the constructor\n*/\nSaverHandler.prototype.saveWiki = function(options) {\n\toptions = options || {};\n\tvar self = this,\n\t\twiki = options.wiki || this.wiki,\n\t\tmethod = options.method || \"save\";\n\t// Ignore autosave if disabled\n\tif(method === \"autosave\" && ($tw.config.disableAutoSave || wiki.getTiddlerText(this.titleAutoSave,\"yes\") !== \"yes\")) {\n\t\treturn false;\n\t}\n\tvar\tvariables = options.variables || {},\n\t\ttemplate = (options.template || \n\t\t           wiki.getTiddlerText(\"$:/config/SaveWikiButton/Template\",\"$:/core/save/all\")).trim(),\n\t\tdownloadType = options.downloadType || \"text/plain\",\n\t\ttext = wiki.renderTiddler(downloadType,template,options),\n\t\tcallback = function(err) {\n\t\t\tif(err) {\n\t\t\t\talert($tw.language.getString(\"Error/WhileSaving\") + \":\\n\\n\" + err);\n\t\t\t} else {\n\t\t\t\t// Clear the task queue if we're saving (rather than downloading)\n\t\t\t\tif(method !== \"download\") {\n\t\t\t\t\tself.numChanges = 0;\n\t\t\t\t\tself.updateDirtyStatus();\n\t\t\t\t}\n\t\t\t\t$tw.notifier.display(self.titleSavedNotification);\n\t\t\t\tif(options.callback) {\n\t\t\t\t\toptions.callback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t// Call the highest priority saver that supports this method\n\tfor(var t=this.savers.length-1; t>=0; t--) {\n\t\tvar saver = this.savers[t];\n\t\tif(saver.info.capabilities.indexOf(method) !== -1 && saver.save(text,method,callback,{variables: {filename: variables.filename}})) {\n\t\t\tthis.logger.log(\"Saving wiki with method\",method,\"through saver\",saver.info.name);\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n};\n\n/*\nChecks whether the wiki is dirty (ie the window shouldn't be closed)\n*/\nSaverHandler.prototype.isDirty = function() {\n\treturn this.numChanges > 0;\n};\n\n/*\nUpdate the document body with the class \"tc-dirty\" if the wiki has unsaved/unsynced changes\n*/\nSaverHandler.prototype.updateDirtyStatus = function() {\n\tvar self = this;\n\tif($tw.browser) {\n\t\t$tw.utils.toggleClass(document.body,\"tc-dirty\",this.isDirty());\n\t\t$tw.utils.each($tw.windows,function(win) {\n\t\t\t$tw.utils.toggleClass(win.document.body,\"tc-dirty\",self.isDirty());\n\t\t});\n\t}\n};\n\nexports.SaverHandler = SaverHandler;\n\n})();\n","type":"application/javascript","module-type":"global"},"$:/core/modules/savers/andtidwiki.js":{"title":"$:/core/modules/savers/andtidwiki.js","text":"/*\\\ntitle: $:/core/modules/savers/andtidwiki.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via the AndTidWiki Android app\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false, netscape: false, Components: false */\n\"use strict\";\n\nvar AndTidWiki = function(wiki) {\n};\n\nAndTidWiki.prototype.save = function(text,method,callback,options) {\n\tvar filename = options && options.variables ? options.variables.filename : null;\n\tif (method === \"download\") {\n\t\t// Support download\n\t\tif (window.twi.saveDownload) {\n\t\t\ttry {\n\t\t\t\twindow.twi.saveDownload(text,filename);\n\t\t\t} catch(err) {\n\t\t\t\tif (err.message === \"Method not found\") {\n\t\t\t\t\twindow.twi.saveDownload(text);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tvar link = document.createElement(\"a\");\n\t\t\tlink.setAttribute(\"href\",\"data:text/plain,\" + encodeURIComponent(text));\n\t\t\tif (filename) {\n\t\t\t    link.setAttribute(\"download\",filename);\n\t\t\t}\n\t\t\tdocument.body.appendChild(link);\n\t\t\tlink.click();\n\t\t\tdocument.body.removeChild(link);\n\t\t}\n\t} else if (window.twi.saveWiki) {\n\t\t// Direct save in Tiddloid\n\t\twindow.twi.saveWiki(text);\n\t} else {\n\t\t// Get the pathname of this document\n\t\tvar pathname = $tw.utils.decodeURIComponentSafe(document.location.toString().split(\"#\")[0]);\n\t\t// Strip the file://\n\t\tif(pathname.indexOf(\"file://\") === 0) {\n\t\t\tpathname = pathname.substr(7);\n\t\t}\n\t\t// Strip any query or location part\n\t\tvar p = pathname.indexOf(\"?\");\n\t\tif(p !== -1) {\n\t\t\tpathname = pathname.substr(0,p);\n\t\t}\n\t\tp = pathname.indexOf(\"#\");\n\t\tif(p !== -1) {\n\t\t\tpathname = pathname.substr(0,p);\n\t\t}\n\t\t// Save the file\n\t\twindow.twi.saveFile(pathname,text);\n\t}\n\t// Call the callback\n\tcallback(null);\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nAndTidWiki.prototype.info = {\n\tname: \"andtidwiki\",\n\tpriority: 1600,\n\tcapabilities: [\"save\", \"autosave\", \"download\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn !!window.twi && !!window.twi.saveFile;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new AndTidWiki(wiki);\n};\n\n})();\n","type":"application/javascript","module-type":"saver"},"$:/core/modules/savers/custom.js":{"title":"$:/core/modules/savers/custom.js","text":"/*\\\ntitle: $:/core/modules/savers/custom.js\ntype: application/javascript\nmodule-type: saver\n\nLooks for `window.$tw.customSaver` first on the current window, then\non the parent window (of an iframe). If present, the saver must define\n\tsave: function(text,method,callback) { ... }\nand the saver may define\n\tpriority: number\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar findSaver = function(window) {\n\ttry {\n\t\treturn window && window.$tw && window.$tw.customSaver;\n\t} catch (err) {\n\t\t// Catching the exception is the most reliable way to detect cross-origin iframe errors.\n\t\t// For example, instead of saying that `window.parent.$tw` is undefined, Firefox will throw\n\t\t//   Uncaught DOMException: Permission denied to access property \"$tw\" on cross-origin object\n\t\tconsole.log({ msg: \"custom saver is disabled\", reason: err });\n\t\treturn null;\n\t}\n}\nvar saver = findSaver(window) || findSaver(window.parent) || {};\n\nvar CustomSaver = function(wiki) {\n};\n\nCustomSaver.prototype.save = function(text,method,callback) {\n\treturn saver.save(text, method, callback);\n};\n\n/*\nInformation about this saver\n*/\nCustomSaver.prototype.info = {\n\tname: \"custom\",\n\tpriority: saver.priority || 4000,\n\tcapabilities: [\"save\",\"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn !!(saver.save);\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new CustomSaver(wiki);\n};\n})();\n","type":"application/javascript","module-type":"saver"},"$:/core/modules/savers/download.js":{"title":"$:/core/modules/savers/download.js","text":"/*\\\ntitle: $:/core/modules/savers/download.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via HTML5's download APIs\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar DownloadSaver = function(wiki) {\n};\n\nDownloadSaver.prototype.save = function(text,method,callback,options) {\n\toptions = options || {};\n\t// Get the current filename\n\tvar filename = options.variables.filename;\n\tif(!filename) {\n\t\tvar p = document.location.pathname.lastIndexOf(\"/\");\n\t\tif(p !== -1) {\n\t\t\t// We decode the pathname because document.location is URL encoded by the browser\n\t\t\tfilename = $tw.utils.decodeURIComponentSafe(document.location.pathname.substr(p+1));\n\t\t}\n\t}\n\tif(!filename) {\n\t\tfilename = \"tiddlywiki.html\";\n\t}\n\t// Set up the link\n\tvar link = document.createElement(\"a\");\n\tif(Blob !== undefined) {\n\t\tvar blob = new Blob([text], {type: \"text/html\"});\n\t\tlink.setAttribute(\"href\", URL.createObjectURL(blob));\n\t} else {\n\t\tlink.setAttribute(\"href\",\"data:text/html,\" + encodeURIComponent(text));\n\t}\n\tlink.setAttribute(\"download\",filename);\n\tdocument.body.appendChild(link);\n\tlink.click();\n\tdocument.body.removeChild(link);\n\t// Callback that we succeeded\n\tcallback(null);\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nDownloadSaver.prototype.info = {\n\tname: \"download\",\n\tpriority: 100\n};\n\nObject.defineProperty(DownloadSaver.prototype.info, \"capabilities\", {\n\tget: function() {\n\t\tvar capabilities = [\"save\", \"download\"];\n\t\tif(($tw.wiki.getTextReference(\"$:/config/DownloadSaver/AutoSave\") || \"\").toLowerCase() === \"yes\") {\n\t\t\tcapabilities.push(\"autosave\");\n\t\t}\n\t\treturn capabilities;\n\t}\n});\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn document.createElement(\"a\").download !== undefined;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new DownloadSaver(wiki);\n};\n\n})();\n","type":"application/javascript","module-type":"saver"},"$:/core/modules/savers/fsosaver.js":{"title":"$:/core/modules/savers/fsosaver.js","text":"/*\\\ntitle: $:/core/modules/savers/fsosaver.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via MS FileSystemObject ActiveXObject\n\nNote: Since TiddlyWiki's markup contains the MOTW, the FileSystemObject normally won't be available. \nHowever, if the wiki is loaded as an .HTA file (Windows HTML Applications) then the FSO can be used.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar FSOSaver = function(wiki) {\n};\n\nFSOSaver.prototype.save = function(text,method,callback) {\n\t// Get the pathname of this document\n\tvar pathname = unescape(document.location.pathname);\n\t// Test for a Windows path of the form /x:\\blah...\n\tif(/^\\/[A-Z]\\:\\\\[^\\\\]+/i.test(pathname)) {\t// ie: ^/[a-z]:/[^/]+\n\t\t// Remove the leading slash\n\t\tpathname = pathname.substr(1);\n\t} else if(document.location.hostname !== \"\" && /^\\/\\\\[^\\\\]+\\\\[^\\\\]+/i.test(pathname)) {\t// test for \\\\server\\share\\blah... - ^/[^/]+/[^/]+\n\t\t// Remove the leading slash\n\t\tpathname = pathname.substr(1);\n\t\t// reconstruct UNC path\n\t\tpathname = \"\\\\\\\\\" + document.location.hostname + pathname;\n\t} else {\n\t\treturn false;\n\t}\n\t// Save the file (as UTF-16)\n\tvar fso = new ActiveXObject(\"Scripting.FileSystemObject\");\n\tvar file = fso.OpenTextFile(pathname,2,-1,-1);\n\tfile.Write(text);\n\tfile.Close();\n\t// Callback that we succeeded\n\tcallback(null);\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nFSOSaver.prototype.info = {\n\tname: \"FSOSaver\",\n\tpriority: 120,\n\tcapabilities: [\"save\", \"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\ttry {\n\t\treturn (window.location.protocol === \"file:\") && !!(new ActiveXObject(\"Scripting.FileSystemObject\"));\n\t} catch(e) { return false; }\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new FSOSaver(wiki);\n};\n\n})();\n","type":"application/javascript","module-type":"saver"},"$:/core/modules/savers/gitea.js":{"title":"$:/core/modules/savers/gitea.js","text":"/*\\\ntitle: $:/core/modules/savers/gitea.js\ntype: application/javascript\nmodule-type: saver\n\nSaves wiki by pushing a commit to the gitea\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar GiteaSaver = function(wiki) {\n\tthis.wiki = wiki;\n};\n\nGiteaSaver.prototype.save = function(text,method,callback) {\n\tvar self = this,\n\t\tusername = this.wiki.getTiddlerText(\"$:/Gitea/Username\"),\n\t\tpassword = $tw.utils.getPassword(\"Gitea\"),\n\t\trepo = this.wiki.getTiddlerText(\"$:/Gitea/Repo\"),\n\t\tpath = this.wiki.getTiddlerText(\"$:/Gitea/Path\",\"\"),\n\t\tfilename = this.wiki.getTiddlerText(\"$:/Gitea/Filename\"),\n\t\tbranch = this.wiki.getTiddlerText(\"$:/Gitea/Branch\") || \"master\",\n\t\tendpoint = this.wiki.getTiddlerText(\"$:/Gitea/ServerURL\") || \"https://gitea\",\n\t\theaders = {\n\t\t\t\"Accept\": \"application/json\",\n\t\t\t\"Content-Type\": \"application/json;charset=UTF-8\",\n\t\t\t\"Authorization\": \"token \" + password\n\t\t};\n\t// Bail if we don't have everything we need\n\tif(!username || !password || !repo || !filename) {\n\t\treturn false;\n\t}\n\t// Make sure the path start and ends with a slash\n\tif(path.substring(0,1) !== \"/\") {\n\t\tpath = \"/\" + path;\n\t}\n\tif(path.substring(path.length - 1) !== \"/\") {\n\t\tpath = path + \"/\";\n\t}\n\t// Compose the base URI\n\tvar uri = endpoint + \"/repos/\" + repo + \"/contents\" + path;\n\t// Perform a get request to get the details (inc shas) of files in the same path as our file\n\t$tw.utils.httpRequest({\n\t\turl: uri,\n\t\ttype: \"GET\",\n\t\theaders: headers,\n\t\tdata: {\n\t\t\tref: branch\n\t\t},\n\t\tcallback: function(err,getResponseDataJson,xhr) {\n\t\t\tvar getResponseData,sha = \"\";\n\t\t\tif(err && xhr.status !== 404) {\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\tvar use_put = true;\n\t\t\tif(xhr.status !== 404) {\n\t\t\t\tgetResponseData = $tw.utils.parseJSONSafe(getResponseDataJson);\n\t\t\t\t$tw.utils.each(getResponseData,function(details) {\n\t\t\t\t\tif(details.name === filename) {\n\t\t\t\t\t\tsha = details.sha;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tif(sha === \"\"){\n\t\t\t\t\tuse_put = false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar data = {\n\t\t\t\tmessage: $tw.language.getString(\"ControlPanel/Saving/GitService/CommitMessage\"),\n\t\t\t\tcontent: $tw.utils.base64Encode(text),\n\t\t\t\tsha: sha\n\t\t\t};\n\t\t\t$tw.utils.httpRequest({\n\t\t\t\turl: endpoint + \"/repos/\" + repo + \"/branches/\" + branch,\n\t\t\t\ttype: \"GET\",\n\t\t\t\theaders: headers,\n\t\t\t\tcallback: function(err,getResponseDataJson,xhr) {\n\t\t\t\t\tif(xhr.status === 404) {\n\t\t\t\t\t\tcallback(\"Please ensure the branch in the Gitea repo exists\");\n\t\t\t\t\t}else{\n\t\t\t\t\t\tdata[\"branch\"] = branch;\n\t\t\t\t\t\tself.upload(uri + filename, use_put?\"PUT\":\"POST\", headers, data, callback);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t});\n\treturn true;\n};\n\nGiteaSaver.prototype.upload = function(uri,method,headers,data,callback) {\n\t$tw.utils.httpRequest({\n\t\turl: uri,\n\t\ttype: method,\n\t\theaders: headers,\n\t\tdata: JSON.stringify(data),\n\t\tcallback: function(err,putResponseDataJson,xhr) {\n\t\t\tif(err) {\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\tvar putResponseData = $tw.utils.parseJSONSafe(putResponseDataJson);\n\t\t\tcallback(null);\n\t\t}\n\t});\n};\n\n/*\nInformation about this saver\n*/\nGiteaSaver.prototype.info = {\n\tname: \"Gitea\",\n\tpriority: 2000,\n\tcapabilities: [\"save\", \"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn true;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new GiteaSaver(wiki);\n};\n\n})();\n","type":"application/javascript","module-type":"saver"},"$:/core/modules/savers/github.js":{"title":"$:/core/modules/savers/github.js","text":"/*\\\ntitle: $:/core/modules/savers/github.js\ntype: application/javascript\nmodule-type: saver\n\nSaves wiki by pushing a commit to the GitHub v3 REST API\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar GitHubSaver = function(wiki) {\n\tthis.wiki = wiki;\n};\n\nGitHubSaver.prototype.save = function(text,method,callback) {\n\tvar self = this,\n\t\tusername = this.wiki.getTiddlerText(\"$:/GitHub/Username\"),\n\t\tpassword = $tw.utils.getPassword(\"github\"),\n\t\trepo = this.wiki.getTiddlerText(\"$:/GitHub/Repo\"),\n\t\tpath = this.wiki.getTiddlerText(\"$:/GitHub/Path\",\"\"),\n\t\tfilename = this.wiki.getTiddlerText(\"$:/GitHub/Filename\"),\n\t\tbranch = this.wiki.getTiddlerText(\"$:/GitHub/Branch\") || \"main\",\n\t\tendpoint = this.wiki.getTiddlerText(\"$:/GitHub/ServerURL\") || \"https://api.github.com\",\n\t\theaders = {\n\t\t\t\"Accept\": \"application/vnd.github.v3+json\",\n\t\t\t\"Content-Type\": \"application/json;charset=UTF-8\",\n\t\t\t\"Authorization\": \"Basic \" + $tw.utils.base64Encode(username + \":\" + password),\n\t\t\t\"If-None-Match\": \"\"\n\t\t};\n\t// Bail if we don't have everything we need\n\tif(!username || !password || !repo || !filename) {\n\t\treturn false;\n\t}\n\t// Make sure the path start and ends with a slash\n\tif(path.substring(0,1) !== \"/\") {\n\t\tpath = \"/\" + path;\n\t}\n\tif(path.substring(path.length - 1) !== \"/\") {\n\t\tpath = path + \"/\";\n\t}\n\t// Compose the base URI\n\tvar uri = endpoint + \"/repos/\" + repo + \"/contents\" + path;\n\t// Perform a get request to get the details (inc shas) of files in the same path as our file\n\t$tw.utils.httpRequest({\n\t\turl: uri,\n\t\ttype: \"GET\",\n\t\theaders: headers,\n\t\tdata: {\n\t\t\tref: branch\n\t\t},\n\t\tcallback: function(err,getResponseDataJson,xhr) {\n\t\t\tvar getResponseData,sha = \"\";\n\t\t\tif(err && xhr.status !== 404) {\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\tif(xhr.status !== 404) {\n\t\t\t\tgetResponseData = $tw.utils.parseJSONSafe(getResponseDataJson);\n\t\t\t\t$tw.utils.each(getResponseData,function(details) {\n\t\t\t\t\tif(details.name === filename) {\n\t\t\t\t\t\tsha = details.sha;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\tvar data = {\n\t\t\t\tmessage: $tw.language.getString(\"ControlPanel/Saving/GitService/CommitMessage\"),\n\t\t\t\tcontent: $tw.utils.base64Encode(text),\n\t\t\t\tbranch: branch,\n\t\t\t\tsha: sha\n\t\t\t};\n\t\t\t// Perform a PUT request to save the file\n\t\t\t$tw.utils.httpRequest({\n\t\t\t\turl: uri + filename,\n\t\t\t\ttype: \"PUT\",\n\t\t\t\theaders: headers,\n\t\t\t\tdata: JSON.stringify(data),\n\t\t\t\tcallback: function(err,putResponseDataJson,xhr) {\n\t\t\t\t\tif(err) {\n\t\t\t\t\t\treturn callback(err);\n\t\t\t\t\t}\n\t\t\t\t\tvar putResponseData = $tw.utils.parseJSONSafe(putResponseDataJson);\n\t\t\t\t\tcallback(null);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t});\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nGitHubSaver.prototype.info = {\n\tname: \"github\",\n\tpriority: 2000,\n\tcapabilities: [\"save\", \"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn true;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new GitHubSaver(wiki);\n};\n\n})();\n","type":"application/javascript","module-type":"saver"},"$:/core/modules/savers/gitlab.js":{"title":"$:/core/modules/savers/gitlab.js","text":"/*\\\ntitle: $:/core/modules/savers/gitlab.js\ntype: application/javascript\nmodule-type: saver\n\nSaves wiki by pushing a commit to the GitLab REST API\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: true */\n\"use strict\";\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar GitLabSaver = function(wiki) {\n\tthis.wiki = wiki;\n};\n\nGitLabSaver.prototype.save = function(text,method,callback) {\n\t/* See https://docs.gitlab.com/ee/api/repository_files.html */\n\tvar self = this,\n\t\tusername = this.wiki.getTiddlerText(\"$:/GitLab/Username\"),\n\t\tpassword = $tw.utils.getPassword(\"gitlab\"),\n\t\trepo = this.wiki.getTiddlerText(\"$:/GitLab/Repo\"),\n\t\tpath = this.wiki.getTiddlerText(\"$:/GitLab/Path\",\"\"),\n\t\tfilename = this.wiki.getTiddlerText(\"$:/GitLab/Filename\"),\n\t\tbranch = this.wiki.getTiddlerText(\"$:/GitLab/Branch\") || \"master\",\n\t\tendpoint = this.wiki.getTiddlerText(\"$:/GitLab/ServerURL\") || \"https://gitlab.com/api/v4\",\n\t\theaders = {\n\t\t\t\"Content-Type\": \"application/json;charset=UTF-8\",\n\t\t\t\"Private-Token\": password\n\t\t};\n\t// Bail if we don't have everything we need\n\tif(!username || !password || !repo || !filename) {\n\t\treturn false;\n\t}\n\t// Make sure the path start and ends with a slash\n\tif(path.substring(0,1) !== \"/\") {\n\t\tpath = \"/\" + path;\n\t}\n\tif(path.substring(path.length - 1) !== \"/\") {\n\t\tpath = path + \"/\";\n\t}\n\t// Compose the base URI\n\tvar uri = endpoint + \"/projects/\" + encodeURIComponent(repo) + \"/repository/\";\n\t// Perform a get request to get the details (inc shas) of files in the same path as our file\n\t$tw.utils.httpRequest({\n\t\turl: uri + \"tree/?path=\" + encodeURIComponent(path.replace(/^\\/+|\\/$/g, '')) + \"&branch=\" + encodeURIComponent(branch.replace(/^\\/+|\\/$/g, '')),\n\t\ttype: \"GET\",\n\t\theaders: headers,\n\t\tcallback: function(err,getResponseDataJson,xhr) {\n\t\t\tvar getResponseData,sha = \"\";\n\t\t\tif(err && xhr.status !== 404) {\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\tvar requestType = \"POST\";\n\t\t\tif(xhr.status !== 404) {\n\t\t\t\tgetResponseData = $tw.utils.parseJSONSafe(getResponseDataJson);\n\t\t\t\t$tw.utils.each(getResponseData,function(details) {\n\t\t\t\t\tif(details.name === filename) {\n\t\t\t\t\t\trequestType = \"PUT\";\n\t\t\t\t\t\tsha = details.sha;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\tvar data = {\n\t\t\t\tcommit_message: $tw.language.getString(\"ControlPanel/Saving/GitService/CommitMessage\"),\n\t\t\t\tcontent: text,\n\t\t\t\tbranch: branch,\n\t\t\t\tsha: sha\n\t\t\t};\n\t\t\t// Perform a request to save the file\n\t\t\t$tw.utils.httpRequest({\n\t\t\t\turl: uri + \"files/\" + encodeURIComponent(path.replace(/^\\/+/, '') + filename),\n\t\t\t\ttype: requestType,\n\t\t\t\theaders: headers,\n\t\t\t\tdata: JSON.stringify(data),\n\t\t\t\tcallback: function(err,putResponseDataJson,xhr) {\n\t\t\t\t\tif(err) {\n\t\t\t\t\t\treturn callback(err);\n\t\t\t\t\t}\n\t\t\t\t\tvar putResponseData = $tw.utils.parseJSONSafe(putResponseDataJson);\n\t\t\t\t\tcallback(null);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t});\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nGitLabSaver.prototype.info = {\n\tname: \"gitlab\",\n\tpriority: 2000,\n\tcapabilities: [\"save\", \"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn true;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new GitLabSaver(wiki);\n};\n\n})();\n","type":"application/javascript","module-type":"saver"},"$:/core/modules/savers/manualdownload.js":{"title":"$:/core/modules/savers/manualdownload.js","text":"/*\\\ntitle: $:/core/modules/savers/manualdownload.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via HTML5's download APIs\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Title of the tiddler containing the download message\nvar downloadInstructionsTitle = \"$:/language/Modals/Download\";\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar ManualDownloadSaver = function(wiki) {\n};\n\nManualDownloadSaver.prototype.save = function(text,method,callback) {\n\t$tw.modal.display(downloadInstructionsTitle,{\n\t\tdownloadLink: \"data:text/html,\" + encodeURIComponent(text)\n\t});\n\t// Callback that we succeeded\n\tcallback(null);\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nManualDownloadSaver.prototype.info = {\n\tname: \"manualdownload\",\n\tpriority: 0,\n\tcapabilities: [\"save\", \"download\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn true;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new ManualDownloadSaver(wiki);\n};\n\n})();\n","type":"application/javascript","module-type":"saver"},"$:/core/modules/savers/msdownload.js":{"title":"$:/core/modules/savers/msdownload.js","text":"/*\\\ntitle: $:/core/modules/savers/msdownload.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via window.navigator.msSaveBlob()\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar MsDownloadSaver = function(wiki) {\n};\n\nMsDownloadSaver.prototype.save = function(text,method,callback) {\n\t// Get the current filename\n\tvar filename = \"tiddlywiki.html\",\n\t\tp = document.location.pathname.lastIndexOf(\"/\");\n\tif(p !== -1) {\n\t\tfilename = document.location.pathname.substr(p+1);\n\t}\n\t// Set up the link\n\tvar blob = new Blob([text], {type: \"text/html\"});\n\twindow.navigator.msSaveBlob(blob,filename);\n\t// Callback that we succeeded\n\tcallback(null);\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nMsDownloadSaver.prototype.info = {\n\tname: \"msdownload\",\n\tpriority: 110,\n\tcapabilities: [\"save\", \"download\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn !!window.navigator.msSaveBlob;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new MsDownloadSaver(wiki);\n};\n\n})();\n","type":"application/javascript","module-type":"saver"},"$:/core/modules/savers/put.js":{"title":"$:/core/modules/savers/put.js","text":"/*\\\ntitle: $:/core/modules/savers/put.js\ntype: application/javascript\nmodule-type: saver\n\nSaves wiki by performing a PUT request to the server\n\nWorks with any server which accepts a PUT request\nto the current URL, such as a WebDAV server.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nRetrieve ETag if available\n*/\nvar retrieveETag = function(self) {\n\tvar headers = {\n\t\tAccept: \"*/*\"\n\t};\n\t$tw.utils.httpRequest({\n\t\turl: self.uri(),\n\t\ttype: \"HEAD\",\n\t\theaders: headers,\n\t\tcallback: function(err,data,xhr) {\n\t\t\tif(err) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvar etag = xhr.getResponseHeader(\"ETag\");\n\t\t\tif(!etag) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tself.etag = etag.replace(/^W\\//,\"\");\n\t\t}\n\t});\n};\n\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar PutSaver = function(wiki) {\n\tthis.wiki = wiki;\n\tvar self = this;\n\tvar uri = this.uri();\n\t// Async server probe. Until probe finishes, save will fail fast\n\t// See also https://github.com/TiddlyWiki/TiddlyWiki5/issues/2276\n\t$tw.utils.httpRequest({\n\t\turl: uri,\n\t\ttype: \"OPTIONS\",\n\t\tcallback: function(err,data,xhr) {\n\t\t\t// Check DAV header http://www.webdav.org/specs/rfc2518.html#rfc.section.9.1\n\t\t\tif(!err) {\n\t\t\t\tself.serverAcceptsPuts = xhr.status >= 200 && xhr.status < 300 && !!xhr.getResponseHeader(\"dav\");\n\t\t\t}\n\t\t}\n\t});\n\tretrieveETag(this);\n};\n\nPutSaver.prototype.uri = function() {\n\treturn document.location.toString().split(\"#\")[0];\n};\n\n// TODO: in case of edit conflict\n// Prompt: Do you want to save over this? Y/N\n// Merging would be ideal, and may be possible using future generic merge flow\nPutSaver.prototype.save = function(text,method,callback) {\n\tif(!this.serverAcceptsPuts) {\n\t\treturn false;\n\t}\n\tvar self = this;\n\tvar headers = {\n\t\t\"Content-Type\": \"text/html;charset=UTF-8\"\n\t};\n\tif(this.etag) {\n\t\theaders[\"If-Match\"] = this.etag;\n\t}\n\t$tw.notifier.display(\"$:/language/Notifications/Save/Starting\");\n\t$tw.utils.httpRequest({\n\t\turl: this.uri(),\n\t\ttype: \"PUT\",\n\t\theaders: headers,\n\t\tdata: text,\n\t\tcallback: function(err,data,xhr) {\n\t\t\tif(err) {\n\t\t\t\tvar status = xhr.status,\n\t\t\t\t\terrorMsg = err;\n\t\t\t\tif(status === 412) { // file changed on server\n\t\t\t\t\terrorMsg = $tw.language.getString(\"Error/PutEditConflict\");\n\t\t\t\t} else if(status === 401) { // authentication required\n\t\t\t\t\terrorMsg = $tw.language.getString(\"Error/PutUnauthorized\");\n\t\t\t\t} else if(status === 403) { // permission denied\n\t\t\t\t\terrorMsg = $tw.language.getString(\"Error/PutForbidden\");\n\t\t\t\t}\n\t\t\t\tif (xhr.responseText) {\n\t\t\t\t\t// treat any server response like a plain text error explanation\n\t\t\t\t\terrorMsg = errorMsg + \"\\n\\n\" + xhr.responseText;\n\t\t\t\t}\n\t\t\t\tcallback(errorMsg); // fail\n\t\t\t} else {\n\t\t\t\tself.etag = xhr.getResponseHeader(\"ETag\");\n\t\t\t\tif(self.etag == null) {\n\t\t\t\t\tretrieveETag(self);\n\t\t\t\t}\n\t\t\t\tcallback(null); // success\n\t\t\t}\n\t\t}\n\t});\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nPutSaver.prototype.info = {\n\tname: \"put\",\n\tpriority: 2000,\n\tcapabilities: [\"save\",\"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn /^https?:/.test(location.protocol);\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new PutSaver(wiki);\n};\n\n})();\n","type":"application/javascript","module-type":"saver"},"$:/core/modules/savers/tiddlyfox.js":{"title":"$:/core/modules/savers/tiddlyfox.js","text":"/*\\\ntitle: $:/core/modules/savers/tiddlyfox.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via the TiddlyFox file extension\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false, netscape: false, Components: false */\n\"use strict\";\n\nvar TiddlyFoxSaver = function(wiki) {\n};\n\nTiddlyFoxSaver.prototype.save = function(text,method,callback) {\n\tvar messageBox = document.getElementById(\"tiddlyfox-message-box\");\n\tif(messageBox) {\n\t\t// Get the pathname of this document\n\t\tvar pathname = document.location.toString().split(\"#\")[0];\n\t\t// Replace file://localhost/ with file:///\n\t\tif(pathname.indexOf(\"file://localhost/\") === 0) {\n\t\t\tpathname = \"file://\" + pathname.substr(16);\n\t\t}\n\t\t// Windows path file:///x:/blah/blah --> x:\\blah\\blah\n\t\tif(/^file\\:\\/\\/\\/[A-Z]\\:\\//i.test(pathname)) {\n\t\t\t// Remove the leading slash and convert slashes to backslashes\n\t\t\tpathname = pathname.substr(8).replace(/\\//g,\"\\\\\");\n\t\t// Firefox Windows network path file://///server/share/blah/blah --> //server/share/blah/blah\n\t\t} else if(pathname.indexOf(\"file://///\") === 0) {\n\t\t\tpathname = \"\\\\\\\\\" + unescape(pathname.substr(10)).replace(/\\//g,\"\\\\\");\n\t\t// Mac/Unix local path file:///path/path --> /path/path\n\t\t} else if(pathname.indexOf(\"file:///\") === 0) {\n\t\t\tpathname = unescape(pathname.substr(7));\n\t\t// Mac/Unix local path file:/path/path --> /path/path\n\t\t} else if(pathname.indexOf(\"file:/\") === 0) {\n\t\t\tpathname = unescape(pathname.substr(5));\n\t\t// Otherwise Windows networth path file://server/share/path/path --> \\\\server\\share\\path\\path\n\t\t} else {\n\t\t\tpathname = \"\\\\\\\\\" + unescape(pathname.substr(7)).replace(new RegExp(\"/\",\"g\"),\"\\\\\");\n\t\t}\n\t\t// Create the message element and put it in the message box\n\t\tvar message = document.createElement(\"div\");\n\t\tmessage.setAttribute(\"data-tiddlyfox-path\",$tw.utils.decodeURIComponentSafe(pathname));\n\t\tmessage.setAttribute(\"data-tiddlyfox-content\",text);\n\t\tmessageBox.appendChild(message);\n\t\t// Add an event handler for when the file has been saved\n\t\tmessage.addEventListener(\"tiddlyfox-have-saved-file\",function(event) {\n\t\t\tcallback(null);\n\t\t}, false);\n\t\t// Create and dispatch the custom event to the extension\n\t\tvar event = document.createEvent(\"Events\");\n\t\tevent.initEvent(\"tiddlyfox-save-file\",true,false);\n\t\tmessage.dispatchEvent(event);\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n};\n\n/*\nInformation about this saver\n*/\nTiddlyFoxSaver.prototype.info = {\n\tname: \"tiddlyfox\",\n\tpriority: 1500,\n\tcapabilities: [\"save\", \"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn true;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new TiddlyFoxSaver(wiki);\n};\n\n})();\n","type":"application/javascript","module-type":"saver"},"$:/core/modules/savers/tiddlyie.js":{"title":"$:/core/modules/savers/tiddlyie.js","text":"/*\\\ntitle: $:/core/modules/savers/tiddlyie.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via Internet Explorer BHO extenion (TiddlyIE)\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar TiddlyIESaver = function(wiki) {\n};\n\nTiddlyIESaver.prototype.save = function(text,method,callback) {\n\t// Check existence of TiddlyIE BHO extension (note: only works after document is complete)\n\tif(typeof(window.TiddlyIE) != \"undefined\") {\n\t\t// Get the pathname of this document\n\t\tvar pathname = unescape(document.location.pathname);\n\t\t// Test for a Windows path of the form /x:/blah...\n\t\tif(/^\\/[A-Z]\\:\\/[^\\/]+/i.test(pathname)) {\t// ie: ^/[a-z]:/[^/]+ (is this better?: ^/[a-z]:/[^/]+(/[^/]+)*\\.[^/]+ )\n\t\t\t// Remove the leading slash\n\t\t\tpathname = pathname.substr(1);\n\t\t\t// Convert slashes to backslashes\n\t\t\tpathname = pathname.replace(/\\//g,\"\\\\\");\n\t\t} else if(document.hostname !== \"\" && /^\\/[^\\/]+\\/[^\\/]+/i.test(pathname)) {\t// test for \\\\server\\share\\blah... - ^/[^/]+/[^/]+\n\t\t\t// Convert slashes to backslashes\n\t\t\tpathname = pathname.replace(/\\//g,\"\\\\\");\n\t\t\t// reconstruct UNC path\n\t\t\tpathname = \"\\\\\\\\\" + document.location.hostname + pathname;\n\t\t} else return false;\n\t\t// Prompt the user to save the file\n\t\twindow.TiddlyIE.save(pathname, text);\n\t\t// Callback that we succeeded\n\t\tcallback(null);\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n};\n\n/*\nInformation about this saver\n*/\nTiddlyIESaver.prototype.info = {\n\tname: \"tiddlyiesaver\",\n\tpriority: 1500,\n\tcapabilities: [\"save\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn (window.location.protocol === \"file:\");\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new TiddlyIESaver(wiki);\n};\n\n})();\n","type":"application/javascript","module-type":"saver"},"$:/core/modules/savers/twedit.js":{"title":"$:/core/modules/savers/twedit.js","text":"/*\\\ntitle: $:/core/modules/savers/twedit.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via the TWEdit iOS app\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false, netscape: false, Components: false */\n\"use strict\";\n\nvar TWEditSaver = function(wiki) {\n};\n\nTWEditSaver.prototype.save = function(text,method,callback) {\n\t// Bail if we're not running under TWEdit\n\tif(typeof DeviceInfo !== \"object\") {\n\t\treturn false;\n\t}\n\t// Get the pathname of this document\n\tvar pathname = $tw.utils.decodeURIComponentSafe(document.location.pathname);\n\t// Strip any query or location part\n\tvar p = pathname.indexOf(\"?\");\n\tif(p !== -1) {\n\t\tpathname = pathname.substr(0,p);\n\t}\n\tp = pathname.indexOf(\"#\");\n\tif(p !== -1) {\n\t\tpathname = pathname.substr(0,p);\n\t}\n\t// Remove the leading \"/Documents\" from path\n\tvar prefix = \"/Documents\";\n\tif(pathname.indexOf(prefix) === 0) {\n\t\tpathname = pathname.substr(prefix.length);\n\t}\n\t// Error handler\n\tvar errorHandler = function(event) {\n\t\t// Error\n\t\tcallback($tw.language.getString(\"Error/SavingToTWEdit\") + \": \" + event.target.error.code);\n\t};\n\t// Get the file system\n\twindow.requestFileSystem(LocalFileSystem.PERSISTENT,0,function(fileSystem) {\n\t\t// Now we've got the filesystem, get the fileEntry\n\t\tfileSystem.root.getFile(pathname, {create: true}, function(fileEntry) {\n\t\t\t// Now we've got the fileEntry, create the writer\n\t\t\tfileEntry.createWriter(function(writer) {\n\t\t\t\twriter.onerror = errorHandler;\n\t\t\t\twriter.onwrite = function() {\n\t\t\t\t\tcallback(null);\n\t\t\t\t};\n\t\t\t\twriter.position = 0;\n\t\t\t\twriter.write(text);\n\t\t\t},errorHandler);\n\t\t}, errorHandler);\n\t}, errorHandler);\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nTWEditSaver.prototype.info = {\n\tname: \"twedit\",\n\tpriority: 1600,\n\tcapabilities: [\"save\", \"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn true;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new TWEditSaver(wiki);\n};\n\n/////////////////////////// Hack\n// HACK: This ensures that TWEdit recognises us as a TiddlyWiki document\nif($tw.browser) {\n\twindow.version = {title: \"TiddlyWiki\"};\n}\n\n})();\n","type":"application/javascript","module-type":"saver"},"$:/core/modules/savers/upload.js":{"title":"$:/core/modules/savers/upload.js","text":"/*\\\ntitle: $:/core/modules/savers/upload.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via upload to a server.\n\nDesigned to be compatible with BidiX's UploadPlugin at http://tiddlywiki.bidix.info/#UploadPlugin\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar UploadSaver = function(wiki) {\n\tthis.wiki = wiki;\n};\n\nUploadSaver.prototype.save = function(text,method,callback) {\n\t// Get the various parameters we need\n\tvar backupDir = this.wiki.getTextReference(\"$:/UploadBackupDir\") || \".\",\n\t\tusername = this.wiki.getTextReference(\"$:/UploadName\"),\n\t\tpassword = $tw.utils.getPassword(\"upload\"),\n\t\tuploadDir = this.wiki.getTextReference(\"$:/UploadDir\") || \".\",\n\t\tuploadFilename = this.wiki.getTextReference(\"$:/UploadFilename\") || \"index.html\",\n\t\tuploadWithUrlOnly = this.wiki.getTextReference(\"$:/UploadWithUrlOnly\") || \"no\",\n\t\turl = this.wiki.getTextReference(\"$:/UploadURL\");\n\t// Bail out if we don't have the bits we need\n\tif (uploadWithUrlOnly === \"yes\") {\n\t\t// The url is good enough. No need for a username and password.\n\t\t// Assume the server uses some other kind of auth mechanism.\n\t\tif(!url || url.toString().trim() === \"\") {\n\t\t\treturn false;\n\t\t}\n\t}\n\telse {\n\t\t// Require username and password to be present.\n\t\t// Assume the server uses the standard UploadPlugin username/password.\n\t\tif(!username || username.toString().trim() === \"\" || !password || password.toString().trim() === \"\") {\n\t\t\treturn false;\n\t\t}\n\t}\n\t// Construct the url if not provided\n\tif(!url) {\n\t\turl = \"http://\" + username + \".tiddlyspot.com/store.cgi\";\n\t}\n\t// Assemble the header\n\tvar boundary = \"---------------------------\" + \"AaB03x\";\n\tvar uploadFormName = \"UploadPlugin\";\n\tvar head = [];\n\thead.push(\"--\" + boundary + \"\\r\\nContent-disposition: form-data; name=\\\"UploadPlugin\\\"\\r\\n\");\n\thead.push(\"backupDir=\" + backupDir + \";user=\" + username + \";password=\" + password + \";uploaddir=\" + uploadDir + \";;\"); \n\thead.push(\"\\r\\n\" + \"--\" + boundary);\n\thead.push(\"Content-disposition: form-data; name=\\\"userfile\\\"; filename=\\\"\" + uploadFilename + \"\\\"\");\n\thead.push(\"Content-Type: text/html;charset=UTF-8\");\n\thead.push(\"Content-Length: \" + text.length + \"\\r\\n\");\n\thead.push(\"\");\n\t// Assemble the tail and the data itself\n\tvar tail = \"\\r\\n--\" + boundary + \"--\\r\\n\",\n\t\tdata = head.join(\"\\r\\n\") + text + tail;\n\t// Do the HTTP post\n\t$tw.notifier.display(\"$:/language/Notifications/Save/Starting\");\n\tvar http = new XMLHttpRequest();\n\thttp.open(\"POST\",url,true,username,password);\n\thttp.setRequestHeader(\"Content-Type\",\"multipart/form-data; charset=UTF-8; boundary=\" + boundary);\n\thttp.onreadystatechange = function() {\n\t\tif(http.readyState == 4 && http.status == 200) {\n\t\t\tif(http.responseText.substr(0,4) === \"0 - \") {\n\t\t\t\tcallback(null);\n\t\t\t} else {\n\t\t\t\tcallback(http.responseText);\n\t\t\t}\n\t\t}\n\t};\n\ttry {\n\t\thttp.send(data);\n\t} catch(ex) {\n\t\treturn callback($tw.language.getString(\"Error/Caption\") + \":\" + ex);\n\t}\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nUploadSaver.prototype.info = {\n\tname: \"upload\",\n\tpriority: 2000,\n\tcapabilities: [\"save\", \"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn true;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new UploadSaver(wiki);\n};\n\n})();\n","type":"application/javascript","module-type":"saver"},"$:/core/modules/server/authenticators/basic.js":{"title":"$:/core/modules/server/authenticators/basic.js","text":"/*\\\ntitle: $:/core/modules/server/authenticators/basic.js\ntype: application/javascript\nmodule-type: authenticator\n\nAuthenticator for WWW basic authentication\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nif($tw.node) {\n\tvar util = require(\"util\"),\n\t\tfs = require(\"fs\"),\n\t\turl = require(\"url\"),\n\t\tpath = require(\"path\");\n}\n\nfunction BasicAuthenticator(server) {\n\tthis.server = server;\n\tthis.credentialsData = [];\n}\n\n/*\nReturns true if the authenticator is active, false if it is inactive, or a string if there is an error\n*/\nBasicAuthenticator.prototype.init = function() {\n\t// Read the credentials data\n\tthis.credentialsFilepath = this.server.get(\"credentials\");\n\tif(this.credentialsFilepath) {\n\t\tvar resolveCredentialsFilepath = path.resolve(this.server.boot.wikiPath,this.credentialsFilepath);\n\t\tif(fs.existsSync(resolveCredentialsFilepath) && !fs.statSync(resolveCredentialsFilepath).isDirectory()) {\n\t\t\tvar credentialsText = fs.readFileSync(resolveCredentialsFilepath,\"utf8\"),\n\t\t\t\tcredentialsData = $tw.utils.parseCsvStringWithHeader(credentialsText);\n\t\t\tif(typeof credentialsData === \"string\") {\n\t\t\t\treturn \"Error: \" + credentialsData + \" reading credentials from '\" + resolveCredentialsFilepath + \"'\";\n\t\t\t} else {\n\t\t\t\tthis.credentialsData = credentialsData;\n\t\t\t}\n\t\t} else {\n\t\t\treturn \"Error: Unable to load user credentials from '\" + resolveCredentialsFilepath + \"'\";\n\t\t}\n\t}\n\t// Add the hardcoded username and password if specified\n\tif(this.server.get(\"username\") && this.server.get(\"password\")) {\n\t\tthis.credentialsData = this.credentialsData || [];\n\t\tthis.credentialsData.push({\n\t\t\tusername: this.server.get(\"username\"),\n\t\t\tpassword: this.server.get(\"password\")\n\t\t});\n\t}\n\treturn this.credentialsData.length > 0;\n};\n\n/*\nReturns true if the request is authenticated and assigns the \"authenticatedUsername\" state variable.\nReturns false if the request couldn't be authenticated having sent an appropriate response to the browser\n*/\nBasicAuthenticator.prototype.authenticateRequest = function(request,response,state) {\n\t// Extract the incoming username and password from the request\n\tvar header = request.headers.authorization || \"\";\n\tif(!header && state.allowAnon) {\n\t\t// If there's no header and anonymous access is allowed then we don't set authenticatedUsername\n\t\treturn true;\n\t}\n\tvar token = header.split(/\\s+/).pop() || \"\",\n\t\tauth = $tw.utils.base64Decode(token),\n\t\tparts = auth.split(/:/),\n\t\tincomingUsername = parts[0],\n\t\tincomingPassword = parts[1];\n\t// Check that at least one of the credentials matches\n\tvar matchingCredentials = this.credentialsData.find(function(credential) {\n\t\treturn credential.username === incomingUsername && credential.password === incomingPassword;\n\t});\n\tif(matchingCredentials) {\n\t\t// If so, add the authenticated username to the request state\n\t\tstate.authenticatedUsername = incomingUsername;\n\t\treturn true;\n\t} else {\n\t\t// If not, return an authentication challenge\n\t\tresponse.writeHead(401,\"Authentication required\",{\n\t\t\t\"WWW-Authenticate\": 'Basic realm=\"Please provide your username and password to login to ' + state.server.servername + '\"'\n\t\t});\n\t\tresponse.end();\n\t\treturn false;\n\t}\n};\n\nexports.AuthenticatorClass = BasicAuthenticator;\n\n})();\n","type":"application/javascript","module-type":"authenticator"},"$:/core/modules/server/authenticators/header.js":{"title":"$:/core/modules/server/authenticators/header.js","text":"/*\\\ntitle: $:/core/modules/server/authenticators/header.js\ntype: application/javascript\nmodule-type: authenticator\n\nAuthenticator for trusted header authentication\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nfunction HeaderAuthenticator(server) {\n\tthis.server = server;\n\tthis.header = server.get(\"authenticated-user-header\") ? server.get(\"authenticated-user-header\").toLowerCase() : undefined;\n}\n\n/*\nReturns true if the authenticator is active, false if it is inactive, or a string if there is an error\n*/\nHeaderAuthenticator.prototype.init = function() {\n\treturn !!this.header;\n};\n\n/*\nReturns true if the request is authenticated and assigns the \"authenticatedUsername\" state variable.\nReturns false if the request couldn't be authenticated having sent an appropriate response to the browser\n*/\nHeaderAuthenticator.prototype.authenticateRequest = function(request,response,state) {\n\t// Otherwise, authenticate as the username in the specified header\n\tvar username = request.headers[this.header];\n\tif(!username && !state.allowAnon) {\n\t\tresponse.writeHead(401,\"Authorization header required to login to '\" + state.server.servername + \"'\");\n\t\tresponse.end();\n\t\treturn false;\n\t} else {\n\t\t// authenticatedUsername will be undefined for anonymous users\n\t\tif(username) {\n\t\t\tstate.authenticatedUsername = $tw.utils.decodeURIComponentSafe(username);\n\t\t}\n\t\treturn true;\n\t}\n};\n\nexports.AuthenticatorClass = HeaderAuthenticator;\n\n})();\n","type":"application/javascript","module-type":"authenticator"},"$:/core/modules/server/routes/delete-tiddler.js":{"title":"$:/core/modules/server/routes/delete-tiddler.js","text":"/*\\\ntitle: $:/core/modules/server/routes/delete-tiddler.js\ntype: application/javascript\nmodule-type: route\n\nDELETE /recipes/default/tiddlers/:title\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"DELETE\";\n\nexports.path = /^\\/bags\\/default\\/tiddlers\\/(.+)$/;\n\nexports.handler = function(request,response,state) {\n\tvar title = $tw.utils.decodeURIComponentSafe(state.params[0]);\n\tstate.wiki.deleteTiddler(title);\n\tresponse.writeHead(204, \"OK\", {\n\t\t\"Content-Type\": \"text/plain\"\n\t});\n\tresponse.end();\n};\n\n}());\n","type":"application/javascript","module-type":"route"},"$:/core/modules/server/routes/get-favicon.js":{"title":"$:/core/modules/server/routes/get-favicon.js","text":"/*\\\ntitle: $:/core/modules/server/routes/get-favicon.js\ntype: application/javascript\nmodule-type: route\n\nGET /favicon.ico\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"GET\";\n\nexports.path = /^\\/favicon.ico$/;\n\nexports.handler = function(request,response,state) {\n\tvar buffer = state.wiki.getTiddlerText(\"$:/favicon.ico\",\"\");\n\tstate.sendResponse(200,{\"Content-Type\": \"image/x-icon\"},buffer,\"base64\");\n};\n\n}());\n","type":"application/javascript","module-type":"route"},"$:/core/modules/server/routes/get-file.js":{"title":"$:/core/modules/server/routes/get-file.js","text":"/*\\\ntitle: $:/core/modules/server/routes/get-file.js\ntype: application/javascript\nmodule-type: route\n\nGET /files/:filepath\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"GET\";\n\nexports.path = /^\\/files\\/(.+)$/;\n\nexports.handler = function(request,response,state) {\n\tvar path = require(\"path\"),\n\t\tfs = require(\"fs\"),\n\t\tutil = require(\"util\"),\n\t\tsuppliedFilename = $tw.utils.decodeURIComponentSafe(state.params[0]),\n\t\tbaseFilename = path.resolve(state.boot.wikiPath,\"files\"),\n\t\tfilename = path.resolve(baseFilename,suppliedFilename),\n\t\textension = path.extname(filename);\n\t// Check that the filename is inside the wiki files folder\n\tif(path.relative(baseFilename,filename).indexOf(\"..\") !== 0) {\n\t\t// Send the file\n\t\tfs.readFile(filename,function(err,content) {\n\t\t\tvar status,content,type = \"text/plain\";\n\t\t\tif(err) {\n\t\t\t\tconsole.log(\"Error accessing file \" + filename + \": \" + err.toString());\n\t\t\t\tstatus = 404;\n\t\t\t\tcontent = \"File '\" + suppliedFilename + \"' not found\";\n\t\t\t} else {\n\t\t\t\tstatus = 200;\n\t\t\t\tcontent = content;\n\t\t\t\ttype = ($tw.config.fileExtensionInfo[extension] ? $tw.config.fileExtensionInfo[extension].type : \"application/octet-stream\");\n\t\t\t}\n\t\t\tstate.sendResponse(status,{\"Content-Type\": type},content);\n\t\t});\n\t} else {\n\t\tstate.sendResponse(404,{\"Content-Type\": \"text/plain\"},\"File '\" + suppliedFilename + \"' not found\");\n\t}\n};\n\n}());\n","type":"application/javascript","module-type":"route"},"$:/core/modules/server/routes/get-index.js":{"title":"$:/core/modules/server/routes/get-index.js","text":"/*\\\ntitle: $:/core/modules/server/routes/get-index.js\ntype: application/javascript\nmodule-type: route\n\nGET /\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"GET\";\n\nexports.path = /^\\/$/;\n\nexports.handler = function(request,response,state) {\n\tvar text = state.wiki.renderTiddler(state.server.get(\"root-render-type\"),state.server.get(\"root-tiddler\")),\n\t\tresponseHeaders = {\n\t\t\"Content-Type\": state.server.get(\"root-serve-type\")\n\t};\n\tstate.sendResponse(200,responseHeaders,text);\n};\n\n}());\n","type":"application/javascript","module-type":"route"},"$:/core/modules/server/routes/get-login-basic.js":{"title":"$:/core/modules/server/routes/get-login-basic.js","text":"/*\\\ntitle: $:/core/modules/server/routes/get-login-basic.js\ntype: application/javascript\nmodule-type: route\n\nGET /login-basic -- force a Basic Authentication challenge\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"GET\";\n\nexports.path = /^\\/login-basic$/;\n\nexports.handler = function(request,response,state) {\n\tif(!state.authenticatedUsername) {\n\t\t// Challenge if there's no username\n\t\tresponse.writeHead(401,{\n\t\t\t\"WWW-Authenticate\": 'Basic realm=\"Please provide your username and password to login to ' + state.server.servername + '\"'\n\t\t});\n\t\tresponse.end();\n\t} else {\n\t\t// Redirect to the root wiki if login worked\n\t\tvar location = ($tw.syncadaptor && $tw.syncadaptor.host)? $tw.syncadaptor.host: \"/\";\n\t\tresponse.writeHead(302,{\n\t\t\tLocation: location\n\t\t});\n\t\tresponse.end();\n\t}\n};\n\n}());\n","type":"application/javascript","module-type":"route"},"$:/core/modules/server/routes/get-status.js":{"title":"$:/core/modules/server/routes/get-status.js","text":"/*\\\ntitle: $:/core/modules/server/routes/get-status.js\ntype: application/javascript\nmodule-type: route\n\nGET /status\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"GET\";\n\nexports.path = /^\\/status$/;\n\nexports.handler = function(request,response,state) {\n\tvar text = JSON.stringify({\n\t\tusername: state.authenticatedUsername || state.server.get(\"anon-username\") || \"\",\n\t\tanonymous: !state.authenticatedUsername,\n\t\tread_only: !state.server.isAuthorized(\"writers\",state.authenticatedUsername),\n\t\tlogout_is_available: false,\n\t\tspace: {\n\t\t\trecipe: \"default\"\n\t\t},\n\t\ttiddlywiki_version: $tw.version\n\t});\n\tstate.sendResponse(200,{\"Content-Type\": \"application/json\"},text,\"utf8\");\n};\n\n}());\n","type":"application/javascript","module-type":"route"},"$:/core/modules/server/routes/get-tiddler-html.js":{"title":"$:/core/modules/server/routes/get-tiddler-html.js","text":"/*\\\ntitle: $:/core/modules/server/routes/get-tiddler-html.js\ntype: application/javascript\nmodule-type: route\n\nGET /:title\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"GET\";\n\nexports.path = /^\\/([^\\/]+)$/;\n\nexports.handler = function(request,response,state) {\n\tvar title = $tw.utils.decodeURIComponentSafe(state.params[0]),\n\t\ttiddler = state.wiki.getTiddler(title);\n\tif(tiddler) {\n\t\tvar renderType = tiddler.getFieldString(\"_render_type\"),\n\t\t\trenderTemplate = tiddler.getFieldString(\"_render_template\");\n\t\t// Tiddler fields '_render_type' and '_render_template' overwrite\n\t\t// system wide settings for render type and template\n\t\tif(state.wiki.isSystemTiddler(title)) {\n\t\t\trenderType = renderType || state.server.get(\"system-tiddler-render-type\");\n\t\t\trenderTemplate = renderTemplate || state.server.get(\"system-tiddler-render-template\");\n\t\t} else {\n\t\t\trenderType = renderType || state.server.get(\"tiddler-render-type\");\n\t\t\trenderTemplate = renderTemplate || state.server.get(\"tiddler-render-template\");\n\t\t}\n\t\tvar text = state.wiki.renderTiddler(renderType,renderTemplate,{parseAsInline: true, variables: {currentTiddler: title}});\n\n\t\t// Naughty not to set a content-type, but it's the easiest way to ensure the browser will see HTML pages as HTML, and accept plain text tiddlers as CSS or JS\n\t\tstate.sendResponse(200,{},text,\"utf8\");\n\t} else {\n\t\tresponse.writeHead(404);\n\t\tresponse.end();\n\t}\n};\n\n}());\n","type":"application/javascript","module-type":"route"},"$:/core/modules/server/routes/get-tiddler.js":{"title":"$:/core/modules/server/routes/get-tiddler.js","text":"/*\\\ntitle: $:/core/modules/server/routes/get-tiddler.js\ntype: application/javascript\nmodule-type: route\n\nGET /recipes/default/tiddlers/:title\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"GET\";\n\nexports.path = /^\\/recipes\\/default\\/tiddlers\\/(.+)$/;\n\nexports.handler = function(request,response,state) {\n\tvar title = $tw.utils.decodeURIComponentSafe(state.params[0]),\n\t\ttiddler = state.wiki.getTiddler(title),\n\t\ttiddlerFields = {},\n\t\tknownFields = [\n\t\t\t\"bag\", \"created\", \"creator\", \"modified\", \"modifier\", \"permissions\", \"recipe\", \"revision\", \"tags\", \"text\", \"title\", \"type\", \"uri\"\n\t\t];\n\tif(tiddler) {\n\t\t$tw.utils.each(tiddler.fields,function(field,name) {\n\t\t\tvar value = tiddler.getFieldString(name);\n\t\t\tif(knownFields.indexOf(name) !== -1) {\n\t\t\t\ttiddlerFields[name] = value;\n\t\t\t} else {\n\t\t\t\ttiddlerFields.fields = tiddlerFields.fields || {};\n\t\t\t\ttiddlerFields.fields[name] = value;\n\t\t\t}\n\t\t});\n\t\ttiddlerFields.revision = state.wiki.getChangeCount(title);\n\t\ttiddlerFields.bag = \"default\";\n\t\ttiddlerFields.type = tiddlerFields.type || \"text/vnd.tiddlywiki\";\n\t\tstate.sendResponse(200,{\"Content-Type\": \"application/json\"},JSON.stringify(tiddlerFields),\"utf8\");\n\t} else {\n\t\tresponse.writeHead(404);\n\t\tresponse.end();\n\t}\n};\n\n}());\n","type":"application/javascript","module-type":"route"},"$:/core/modules/server/routes/get-tiddlers-json.js":{"title":"$:/core/modules/server/routes/get-tiddlers-json.js","text":"/*\\\ntitle: $:/core/modules/server/routes/get-tiddlers-json.js\ntype: application/javascript\nmodule-type: route\n\nGET /recipes/default/tiddlers.json?filter=<filter>\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar DEFAULT_FILTER = \"[all[tiddlers]!is[system]sort[title]]\";\n\nexports.method = \"GET\";\n\nexports.path = /^\\/recipes\\/default\\/tiddlers.json$/;\n\nexports.handler = function(request,response,state) {\n\tvar filter = state.queryParameters.filter || DEFAULT_FILTER;\n\tif(state.wiki.getTiddlerText(\"$:/config/Server/AllowAllExternalFilters\") !== \"yes\") {\n\t\tif(state.wiki.getTiddlerText(\"$:/config/Server/ExternalFilters/\" + filter) !== \"yes\") {\n\t\t\tconsole.log(\"Blocked attempt to GET /recipes/default/tiddlers.json with filter: \" + filter);\n\t\t\tresponse.writeHead(403);\n\t\t\tresponse.end();\n\t\t\treturn;\n\t\t}\n\t}\n\tif(state.wiki.getTiddlerText(\"$:/config/SyncSystemTiddlersFromServer\") === \"no\") {\n\t\tfilter += \"+[!is[system]]\";\n\t}\n\tvar excludeFields = (state.queryParameters.exclude || \"text\").split(\",\"),\n\t\ttitles = state.wiki.filterTiddlers(filter);\n\tvar tiddlers = [];\n\t$tw.utils.each(titles,function(title) {\n\t\tvar tiddler = state.wiki.getTiddler(title);\n\t\tif(tiddler) {\n\t\t\tvar tiddlerFields = tiddler.getFieldStrings({exclude: excludeFields});\n\t\t\ttiddlerFields.revision = state.wiki.getChangeCount(title);\n\t\t\ttiddlerFields.type = tiddlerFields.type || \"text/vnd.tiddlywiki\";\n\t\t\ttiddlers.push(tiddlerFields);\n\t\t}\n\t});\n\tvar text = JSON.stringify(tiddlers);\n\tstate.sendResponse(200,{\"Content-Type\": \"application/json\"},text,\"utf8\");\n};\n\n}());\n","type":"application/javascript","module-type":"route"},"$:/core/modules/server/routes/put-tiddler.js":{"title":"$:/core/modules/server/routes/put-tiddler.js","text":"/*\\\ntitle: $:/core/modules/server/routes/put-tiddler.js\ntype: application/javascript\nmodule-type: route\n\nPUT /recipes/default/tiddlers/:title\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"PUT\";\n\nexports.path = /^\\/recipes\\/default\\/tiddlers\\/(.+)$/;\n\nexports.handler = function(request,response,state) {\n\tvar title = $tw.utils.decodeURIComponentSafe(state.params[0]),\n\tfields = $tw.utils.parseJSONSafe(state.data);\n\t// Pull up any subfields in the `fields` object\n\tif(fields.fields) {\n\t\t$tw.utils.each(fields.fields,function(field,name) {\n\t\t\tfields[name] = field;\n\t\t});\n\t\tdelete fields.fields;\n\t}\n\t// Remove any revision field\n\tif(fields.revision) {\n\t\tdelete fields.revision;\n\t}\n\t// If this is a skinny tiddler, it means the client never got the full\n\t// version of the tiddler to edit. So we must preserve whatever text\n\t// already exists on the server, or else we'll inadvertently delete it.\n\tif(fields._is_skinny !== undefined) {\n\t\tvar tiddler = state.wiki.getTiddler(title);\n\t\tif(tiddler) {\n\t\t\tfields.text = tiddler.fields.text;\n\t\t}\n\t\tdelete fields._is_skinny;\n\t}\n\tstate.wiki.addTiddler(new $tw.Tiddler(fields,{title: title}));\n\tvar changeCount = state.wiki.getChangeCount(title).toString();\n\tresponse.writeHead(204, \"OK\",{\n\t\tEtag: \"\\\"default/\" + encodeURIComponent(title) + \"/\" + changeCount + \":\\\"\",\n\t\t\"Content-Type\": \"text/plain\"\n\t});\n\tresponse.end();\n};\n\n}());\n","type":"application/javascript","module-type":"route"},"$:/core/modules/server/server.js":{"title":"$:/core/modules/server/server.js","text":"/*\\\ntitle: $:/core/modules/server/server.js\ntype: application/javascript\nmodule-type: library\n\nServe tiddlers over http\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nif($tw.node) {\n\tvar util = require(\"util\"),\n\t\tfs = require(\"fs\"),\n\t\turl = require(\"url\"),\n\t\tpath = require(\"path\"),\n\t\tquerystring = require(\"querystring\"),\n\t\tcrypto = require(\"crypto\"),\n\t\tzlib = require(\"zlib\");\n}\n\n/*\nA simple HTTP server with regexp-based routes\noptions: variables - optional hashmap of variables to set (a misnomer - they are really constant parameters)\n\t\t routes - optional array of routes to use\n\t\t wiki - reference to wiki object\n*/\nfunction Server(options) {\n\tvar self = this;\n\tthis.routes = options.routes || [];\n\tthis.authenticators = options.authenticators || [];\n\tthis.wiki = options.wiki;\n\tthis.boot = options.boot || $tw.boot;\n\t// Initialise the variables\n\tthis.variables = $tw.utils.extend({},this.defaultVariables);\n\tif(options.variables) {\n\t\tfor(var variable in options.variables) {\n\t\t\tif(options.variables[variable]) {\n\t\t\t\tthis.variables[variable] = options.variables[variable];\n\t\t\t}\n\t\t}\n\t}\n\t// Setup the default required plugins\n\tthis.requiredPlugins = this.get(\"required-plugins\").split(',');\n\t// Initialise CSRF\n\tthis.csrfDisable = this.get(\"csrf-disable\") === \"yes\";\n\t// Initialize Gzip compression\n\tthis.enableGzip = this.get(\"gzip\") === \"yes\";\n\t// Initialize browser-caching\n\tthis.enableBrowserCache = this.get(\"use-browser-cache\") === \"yes\";\n\t// Initialise authorization\n\tvar authorizedUserName;\n\tif(this.get(\"username\") && this.get(\"password\")) {\n\t\tauthorizedUserName = this.get(\"username\");\n\t} else if(this.get(\"credentials\")) {\n\t\tauthorizedUserName = \"(authenticated)\";\n\t} else {\n\t\tauthorizedUserName = \"(anon)\";\n\t}\n\tthis.authorizationPrincipals = {\n\t\treaders: (this.get(\"readers\") || authorizedUserName).split(\",\").map($tw.utils.trim),\n\t\twriters: (this.get(\"writers\") || authorizedUserName).split(\",\").map($tw.utils.trim)\n\t}\n\tif(this.get(\"admin\") || authorizedUserName !== \"(anon)\") {\n\t\tthis.authorizationPrincipals[\"admin\"] = (this.get(\"admin\") || authorizedUserName).split(',').map($tw.utils.trim)\n\t}\n\t// Load and initialise authenticators\n\t$tw.modules.forEachModuleOfType(\"authenticator\", function(title,authenticatorDefinition) {\n\t\t// console.log(\"Loading authenticator \" + title);\n\t\tself.addAuthenticator(authenticatorDefinition.AuthenticatorClass);\n\t});\n\t// Load route handlers\n\t$tw.modules.forEachModuleOfType(\"route\", function(title,routeDefinition) {\n\t\t// console.log(\"Loading server route \" + title);\n\t\tself.addRoute(routeDefinition);\n\t});\n\t// Initialise the http vs https\n\tthis.listenOptions = null;\n\tthis.protocol = \"http\";\n\tvar tlsKeyFilepath = this.get(\"tls-key\"),\n\t\ttlsCertFilepath = this.get(\"tls-cert\"),\n\t\ttlsPassphrase = this.get(\"tls-passphrase\");\n\tif(tlsCertFilepath && tlsKeyFilepath) {\n\t\tthis.listenOptions = {\n\t\t\tkey: fs.readFileSync(path.resolve(this.boot.wikiPath,tlsKeyFilepath),\"utf8\"),\n\t\t\tcert: fs.readFileSync(path.resolve(this.boot.wikiPath,tlsCertFilepath),\"utf8\"),\n\t\t\tpassphrase: tlsPassphrase || ''\n\t\t};\n\t\tthis.protocol = \"https\";\n\t}\n\tthis.transport = require(this.protocol);\n\t// Name the server and init the boot state\n\tthis.servername = $tw.utils.transliterateToSafeASCII(this.get(\"server-name\") || this.wiki.getTiddlerText(\"$:/SiteTitle\") || \"TiddlyWiki5\");\n\tthis.boot.origin = this.get(\"origin\")? this.get(\"origin\"): this.protocol+\"://\"+this.get(\"host\")+\":\"+this.get(\"port\");\n\tthis.boot.pathPrefix = this.get(\"path-prefix\") || \"\";\n}\n\n/*\nSend a response to the client. This method checks if the response must be sent\nor if the client alrady has the data cached. If that's the case only a 304\nresponse will be transmitted and the browser will use the cached data.\nOnly requests with status code 200 are considdered for caching.\nrequest: request instance passed to the handler\nresponse: response instance passed to the handler\nstatusCode: stauts code to send to the browser\nheaders: response headers (they will be augmented with an `Etag` header)\ndata: the data to send (passed to the end method of the response instance)\nencoding: the encoding of the data to send (passed to the end method of the response instance)\n*/\nfunction sendResponse(request,response,statusCode,headers,data,encoding) {\n\tif(this.enableBrowserCache && (statusCode == 200)) {\n\t\tvar hash = crypto.createHash('md5');\n\t\t// Put everything into the hash that could change and invalidate the data that\n\t\t// the browser already stored. The headers the data and the encoding.\n\t\thash.update(data);\n\t\thash.update(JSON.stringify(headers));\n\t\tif(encoding) {\n\t\t\thash.update(encoding);\n\t\t}\n\t\tvar contentDigest = hash.digest(\"hex\");\n\t\t// RFC 7232 section 2.3 mandates for the etag to be enclosed in quotes\n\t\theaders[\"Etag\"] = '\"' + contentDigest + '\"';\n\t\theaders[\"Cache-Control\"] = \"max-age=0, must-revalidate\";\n\t\t// Check if any of the hashes contained within the if-none-match header\n\t\t// matches the current hash.\n\t\t// If one matches, do not send the data but tell the browser to use the\n\t\t// cached data.\n\t\t// We do not implement \"*\" as it makes no sense here.\n\t\tvar ifNoneMatch = request.headers[\"if-none-match\"];\n\t\tif(ifNoneMatch) {\n\t\t\tvar matchParts = ifNoneMatch.split(\",\").map(function(etag) {\n\t\t\t\treturn etag.replace(/^[ \"]+|[ \"]+$/g, \"\");\n\t\t\t});\n\t\t\tif(matchParts.indexOf(contentDigest) != -1) {\n\t\t\t\tresponse.writeHead(304,headers);\n\t\t\t\tresponse.end();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// RFC 7231, 6.1. Overview of Status Codes:\n\t\t// Browser clients may cache 200, 203, 204, 206, 300, 301, \n\t\t// 404, 405, 410, 414, and 501 unless given explicit cache controls\n\t\theaders[\"Cache-Control\"] = headers[\"Cache-Control\"] || \"no-store\";\n\t}\n\t/*\n\tIf the gzip=yes is set, check if the user agent permits compression. If so,\n\tcompress our response if the raw data is bigger than 2k. Compressing less\n\tdata is inefficient. Note that we use the synchronous functions from zlib\n\tto stay in the imperative style. The current `Server` doesn't depend on\n\tthis, and we may just as well use the async versions.\n\t*/\n\tif(this.enableGzip && (data.length > 2048)) {\n\t\tvar acceptEncoding = request.headers[\"accept-encoding\"] || \"\";\n\t\tif(/\\bdeflate\\b/.test(acceptEncoding)) {\n\t\t\theaders[\"Content-Encoding\"] = \"deflate\";\n\t\t\tdata = zlib.deflateSync(data);\n\t\t} else if(/\\bgzip\\b/.test(acceptEncoding)) {\n\t\t\theaders[\"Content-Encoding\"] = \"gzip\";\n\t\t\tdata = zlib.gzipSync(data);\n\t\t}\n\t}\n\n\tresponse.writeHead(statusCode,headers);\n\tresponse.end(data,encoding);\n}\n\nServer.prototype.defaultVariables = {\n\tport: \"8080\",\n\thost: \"127.0.0.1\",\n\t\"required-plugins\": \"$:/plugins/tiddlywiki/filesystem,$:/plugins/tiddlywiki/tiddlyweb\",\n\t\"root-tiddler\": \"$:/core/save/all\",\n\t\"root-render-type\": \"text/plain\",\n\t\"root-serve-type\": \"text/html\",\n\t\"tiddler-render-type\": \"text/html\",\n\t\"tiddler-render-template\": \"$:/core/templates/server/static.tiddler.html\",\n\t\"system-tiddler-render-type\": \"text/plain\",\n\t\"system-tiddler-render-template\": \"$:/core/templates/wikified-tiddler\",\n\t\"debug-level\": \"none\",\n\t\"gzip\": \"no\",\n\t\"use-browser-cache\": \"no\"\n};\n\nServer.prototype.get = function(name) {\n\treturn this.variables[name];\n};\n\nServer.prototype.addRoute = function(route) {\n\tthis.routes.push(route);\n};\n\nServer.prototype.addAuthenticator = function(AuthenticatorClass) {\n\t// Instantiate and initialise the authenticator\n\tvar authenticator = new AuthenticatorClass(this),\n\t\tresult = authenticator.init();\n\tif(typeof result === \"string\") {\n\t\t$tw.utils.error(\"Error: \" + result);\n\t} else if(result) {\n\t\t// Only use the authenticator if it initialised successfully\n\t\tthis.authenticators.push(authenticator);\n\t}\n};\n\nServer.prototype.findMatchingRoute = function(request,state) {\n\tfor(var t=0; t<this.routes.length; t++) {\n\t\tvar potentialRoute = this.routes[t],\n\t\t\tpathRegExp = potentialRoute.path,\n\t\t\tpathname = state.urlInfo.pathname,\n\t\t\tmatch;\n\t\tif(state.pathPrefix) {\n\t\t\tif(pathname.substr(0,state.pathPrefix.length) === state.pathPrefix) {\n\t\t\t\tpathname = pathname.substr(state.pathPrefix.length) || \"/\";\n\t\t\t\tmatch = potentialRoute.path.exec(pathname);\n\t\t\t} else {\n\t\t\t\tmatch = false;\n\t\t\t}\n\t\t} else {\n\t\t\tmatch = potentialRoute.path.exec(pathname);\n\t\t}\n\t\tif(match && request.method === potentialRoute.method) {\n\t\t\tstate.params = [];\n\t\t\tfor(var p=1; p<match.length; p++) {\n\t\t\t\tstate.params.push(match[p]);\n\t\t\t}\n\t\t\treturn potentialRoute;\n\t\t}\n\t}\n\treturn null;\n};\n\nServer.prototype.methodMappings = {\n\t\"GET\": \"readers\",\n\t\"OPTIONS\": \"readers\",\n\t\"HEAD\": \"readers\",\n\t\"PUT\": \"writers\",\n\t\"POST\": \"writers\",\n\t\"DELETE\": \"writers\"\n};\n\n/*\nCheck whether a given user is authorized for the specified authorizationType (\"readers\" or \"writers\"). Pass null or undefined as the username to check for anonymous access\n*/\nServer.prototype.isAuthorized = function(authorizationType,username) {\n\tvar principals = this.authorizationPrincipals[authorizationType] || [];\n\treturn principals.indexOf(\"(anon)\") !== -1 || (username && (principals.indexOf(\"(authenticated)\") !== -1 || principals.indexOf(username) !== -1));\n}\n\nServer.prototype.requestHandler = function(request,response,options) {\n\toptions = options || {};\n\t// Compose the state object\n\tvar self = this;\n\tvar state = {};\n\tstate.wiki = options.wiki || self.wiki;\n\tstate.boot = options.boot || self.boot;\n\tstate.server = self;\n\tstate.urlInfo = url.parse(request.url);\n\tstate.queryParameters = querystring.parse(state.urlInfo.query);\n\tstate.pathPrefix = options.pathPrefix || this.get(\"path-prefix\") || \"\";\n\tstate.sendResponse = sendResponse.bind(self,request,response);\n\t// Get the principals authorized to access this resource\n\tstate.authorizationType = options.authorizationType || this.methodMappings[request.method] || \"readers\";\n\t// Check for the CSRF header if this is a write\n\tif(!this.csrfDisable && state.authorizationType === \"writers\" && request.headers[\"x-requested-with\"] !== \"TiddlyWiki\") {\n\t\tresponse.writeHead(403,\"'X-Requested-With' header required to login to '\" + this.servername + \"'\");\n\t\tresponse.end();\n\t\treturn;\n\t}\n\t// Check whether anonymous access is granted\n\tstate.allowAnon = this.isAuthorized(state.authorizationType,null);\n\t// Authenticate with the first active authenticator\n\tif(this.authenticators.length > 0) {\n\t\tif(!this.authenticators[0].authenticateRequest(request,response,state)) {\n\t\t\t// Bail if we failed (the authenticator will have sent the response)\n\t\t\treturn;\n\t\t}\n\t}\n\t// Authorize with the authenticated username\n\tif(!this.isAuthorized(state.authorizationType,state.authenticatedUsername)) {\n\t\tresponse.writeHead(401,\"'\" + state.authenticatedUsername + \"' is not authorized to access '\" + this.servername + \"'\");\n\t\tresponse.end();\n\t\treturn;\n\t}\n\t// Find the route that matches this path\n\tvar route = self.findMatchingRoute(request,state);\n\t// Optionally output debug info\n\tif(self.get(\"debug-level\") !== \"none\") {\n\t\tconsole.log(\"Request path:\",JSON.stringify(state.urlInfo));\n\t\tconsole.log(\"Request headers:\",JSON.stringify(request.headers));\n\t\tconsole.log(\"authenticatedUsername:\",state.authenticatedUsername);\n\t}\n\t// Return a 404 if we didn't find a route\n\tif(!route) {\n\t\tresponse.writeHead(404);\n\t\tresponse.end();\n\t\treturn;\n\t}\n\t// Receive the request body if necessary and hand off to the route handler\n\tif(route.bodyFormat === \"stream\" || request.method === \"GET\" || request.method === \"HEAD\") {\n\t\t// Let the route handle the request stream itself\n\t\troute.handler(request,response,state);\n\t} else if(route.bodyFormat === \"string\" || !route.bodyFormat) {\n\t\t// Set the encoding for the incoming request\n\t\trequest.setEncoding(\"utf8\");\n\t\tvar data = \"\";\n\t\trequest.on(\"data\",function(chunk) {\n\t\t\tdata += chunk.toString();\n\t\t});\n\t\trequest.on(\"end\",function() {\n\t\t\tstate.data = data;\n\t\t\troute.handler(request,response,state);\n\t\t});\n\t} else if(route.bodyFormat === \"buffer\") {\n\t\tvar data = [];\n\t\trequest.on(\"data\",function(chunk) {\n\t\t\tdata.push(chunk);\n\t\t});\n\t\trequest.on(\"end\",function() {\n\t\t\tstate.data = Buffer.concat(data);\n\t\t\troute.handler(request,response,state);\n\t\t})\n\t} else {\n\t\tresponse.writeHead(400,\"Invalid bodyFormat \" + route.bodyFormat + \" in route \" + route.method + \" \" + route.path.source);\n\t\tresponse.end();\n\t}\n};\n\n/*\nListen for requests\nport: optional port number (falls back to value of \"port\" variable)\nhost: optional host address (falls back to value of \"host\" variable)\nprefix: optional prefix (falls back to value of \"path-prefix\" variable)\n*/\nServer.prototype.listen = function(port,host,prefix) {\n\tvar self = this;\n\t// Handle defaults for port and host\n\tport = port || this.get(\"port\");\n\thost = host || this.get(\"host\");\n\tprefix = prefix || this.get(\"path-prefix\") || \"\";\n\t// Check for the port being a string and look it up as an environment variable\n\tif(parseInt(port,10).toString() !== port) {\n\t\tport = process.env[port] || 8080;\n\t}\n\t// Warn if required plugins are missing\n\tvar missing = [];\n\tfor (var index=0; index<this.requiredPlugins.length; index++) {\n\t\tif (!this.wiki.getTiddler(this.requiredPlugins[index])) {\n\t\t\tmissing.push(this.requiredPlugins[index]);\n\t\t}\n\t}\n\tif(missing.length > 0) {\n\t\tvar error = \"Warning: Plugin(s) required for client-server operation are missing.\\n\"+\n\t\t\t\"\\\"\"+ missing.join(\"\\\", \\\"\")+\"\\\"\";\n\t\t$tw.utils.warning(error);\n\t}\n\t// Create the server\n\tvar server;\n\tif(this.listenOptions) {\n\t\tserver = this.transport.createServer(this.listenOptions,this.requestHandler.bind(this));\n\t} else {\n\t\tserver = this.transport.createServer(this.requestHandler.bind(this));\n\t}\n\t// Display the port number after we've started listening (the port number might have been specified as zero, in which case we will get an assigned port)\n\tserver.on(\"listening\",function() {\n\t\tvar address = server.address(),\n\t\t\turl = self.protocol + \"://\" + (address.family === \"IPv6\" ? \"[\" + address.address + \"]\" : address.address) + \":\" + address.port + prefix;\n\t\t$tw.utils.log(\"Serving on \" + url,\"brown/orange\");\n\t\t$tw.utils.log(\"(press ctrl-C to exit)\",\"red\");\n\t});\n\t// Listen\n\treturn server.listen(port,host);\n};\n\nexports.Server = Server;\n\n})();\n","type":"application/javascript","module-type":"library"},"$:/core/modules/browser-messaging.js":{"title":"$:/core/modules/browser-messaging.js","text":"/*\\\ntitle: $:/core/modules/browser-messaging.js\ntype: application/javascript\nmodule-type: startup\n\nBrowser message handling\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"browser-messaging\";\nexports.platforms = [\"browser\"];\nexports.after = [\"startup\"];\nexports.synchronous = true;\n\n/*\nLoad a specified url as an iframe and call the callback when it is loaded. If the url is already loaded then the existing iframe instance is used\n*/\nfunction loadIFrame(url,callback) {\n\t// Check if iframe already exists\n\tvar iframeInfo = $tw.browserMessaging.iframeInfoMap[url];\n\tif(iframeInfo) {\n\t\t// We've already got the iframe\n\t\tcallback(null,iframeInfo);\n\t} else {\n\t\t// Create the iframe and save it in the list\n\t\tvar iframe = document.createElement(\"iframe\");\n\t\tiframeInfo = {\n\t\t\turl: url,\n\t\t\tstatus: \"loading\",\n\t\t\tdomNode: iframe\n\t\t};\n\t\t$tw.browserMessaging.iframeInfoMap[url] = iframeInfo;\n\t\tsaveIFrameInfoTiddler(iframeInfo);\n\t\t// Add the iframe to the DOM and hide it\n\t\tiframe.style.display = \"none\";\n\t\tiframe.setAttribute(\"library\",\"true\");\n\t\tdocument.body.appendChild(iframe);\n\t\t// Set up onload\n\t\tiframe.onload = function() {\n\t\t\tiframeInfo.status = \"loaded\";\n\t\t\tsaveIFrameInfoTiddler(iframeInfo);\n\t\t\tcallback(null,iframeInfo);\n\t\t};\n\t\tiframe.onerror = function() {\n\t\t\tcallback(\"Cannot load iframe\");\n\t\t};\n\t\ttry {\n\t\t\tiframe.src = url;\n\t\t} catch(ex) {\n\t\t\tcallback(ex);\n\t\t}\n\t}\n}\n\n/*\nUnload library iframe for given url\n*/\nfunction unloadIFrame(url){\n\tvar iframes = document.getElementsByTagName('iframe');\n\tfor(var t=iframes.length-1; t--; t>=0) {\n\t\tvar iframe = iframes[t];\n\t\tif(iframe.getAttribute(\"library\") === \"true\" &&\n\t\t  iframe.getAttribute(\"src\") === url) {\n\t\t\tiframe.parentNode.removeChild(iframe);\n\t\t}\n\t}\n}\n\nfunction saveIFrameInfoTiddler(iframeInfo) {\n\t$tw.wiki.addTiddler(new $tw.Tiddler($tw.wiki.getCreationFields(),{\n\t\ttitle: \"$:/temp/ServerConnection/\" + iframeInfo.url,\n\t\ttext: iframeInfo.status,\n\t\ttags: [\"$:/tags/ServerConnection\"],\n\t\turl: iframeInfo.url\n\t},$tw.wiki.getModificationFields()));\n}\n\nexports.startup = function() {\n\t// Initialise the store of iframes we've created\n\t$tw.browserMessaging = {\n\t\tiframeInfoMap: {} // Hashmap by URL of {url:,status:\"loading/loaded\",domNode:}\n\t};\n\t// Listen for widget messages to control loading the plugin library\n\t$tw.rootWidget.addEventListener(\"tm-load-plugin-library\",function(event) {\n\t\tvar paramObject = event.paramObject || {},\n\t\t\turl = paramObject.url;\n\t\tif(url) {\n\t\t\tloadIFrame(url,function(err,iframeInfo) {\n\t\t\t\tif(err) {\n\t\t\t\t\talert($tw.language.getString(\"Error/LoadingPluginLibrary\") + \": \" + url);\n\t\t\t\t} else {\n\t\t\t\t\tiframeInfo.domNode.contentWindow.postMessage({\n\t\t\t\t\t\tverb: \"GET\",\n\t\t\t\t\t\turl: \"recipes/library/tiddlers.json\",\n\t\t\t\t\t\tcookies: {\n\t\t\t\t\t\t\ttype: \"save-info\",\n\t\t\t\t\t\t\tinfoTitlePrefix: paramObject.infoTitlePrefix || \"$:/temp/RemoteAssetInfo/\",\n\t\t\t\t\t\t\turl: url\n\t\t\t\t\t\t}\n\t\t\t\t\t},\"*\");\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t});\n\t// Listen for widget messages to control unloading the plugin library\n\t$tw.rootWidget.addEventListener(\"tm-unload-plugin-library\",function(event) {\n\t\tvar paramObject = event.paramObject || {},\n\t\t\turl = paramObject.url;\n\t\t$tw.browserMessaging.iframeInfoMap[url] = undefined;\n\t\tif(url) {\n\t\t\tunloadIFrame(url);\n\t\t\t$tw.utils.each(\n\t\t\t\t$tw.wiki.filterTiddlers(\"[[$:/temp/ServerConnection/\" + url + \"]] [prefix[$:/temp/RemoteAssetInfo/\" + url + \"/]]\"),\n\t\t\t\tfunction(title) {\n\t\t\t\t\t$tw.wiki.deleteTiddler(title);\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\t});\n\t$tw.rootWidget.addEventListener(\"tm-load-plugin-from-library\",function(event) {\n\t\tvar paramObject = event.paramObject || {},\n\t\t\turl = paramObject.url,\n\t\t\ttitle = paramObject.title;\n\t\tif(url && title) {\n\t\t\tloadIFrame(url,function(err,iframeInfo) {\n\t\t\t\tif(err) {\n\t\t\t\t\talert($tw.language.getString(\"Error/LoadingPluginLibrary\") + \": \" + url);\n\t\t\t\t} else {\n\t\t\t\t\tiframeInfo.domNode.contentWindow.postMessage({\n\t\t\t\t\t\tverb: \"GET\",\n\t\t\t\t\t\turl: \"recipes/library/tiddlers/\" + encodeURIComponent(title) + \".json\",\n\t\t\t\t\t\tcookies: {\n\t\t\t\t\t\t\ttype: \"save-tiddler\",\n\t\t\t\t\t\t\turl: url\n\t\t\t\t\t\t}\n\t\t\t\t\t},\"*\");\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t});\n\t// Listen for window messages from other windows\n\twindow.addEventListener(\"message\",function listener(event){\n\t\t// console.log(\"browser-messaging: \",document.location.toString())\n\t\t// console.log(\"browser-messaging: Received message from\",event.origin);\n\t\t// console.log(\"browser-messaging: Message content\",event.data);\n\t\tswitch(event.data.verb) {\n\t\t\tcase \"GET-RESPONSE\":\n\t\t\t\tif(event.data.status.charAt(0) === \"2\") {\n\t\t\t\t\tif(event.data.cookies) {\n\t\t\t\t\t\tif(event.data.cookies.type === \"save-info\") {\n\t\t\t\t\t\t\tvar tiddlers = $tw.utils.parseJSONSafe(event.data.body);\n\t\t\t\t\t\t\t$tw.utils.each(tiddlers,function(tiddler) {\n\t\t\t\t\t\t\t\t$tw.wiki.addTiddler(new $tw.Tiddler($tw.wiki.getCreationFields(),tiddler,{\n\t\t\t\t\t\t\t\t\ttitle: event.data.cookies.infoTitlePrefix + event.data.cookies.url + \"/\" + tiddler.title,\n\t\t\t\t\t\t\t\t\t\"original-title\": tiddler.title,\n\t\t\t\t\t\t\t\t\ttext: \"\",\n\t\t\t\t\t\t\t\t\ttype: \"text/vnd.tiddlywiki\",\n\t\t\t\t\t\t\t\t\t\"original-type\": tiddler.type,\n\t\t\t\t\t\t\t\t\t\"plugin-type\": undefined,\n\t\t\t\t\t\t\t\t\t\"original-plugin-type\": tiddler[\"plugin-type\"],\n\t\t\t\t\t\t\t\t\t\"module-type\": undefined,\n\t\t\t\t\t\t\t\t\t\"original-module-type\": tiddler[\"module-type\"],\n\t\t\t\t\t\t\t\t\ttags: [\"$:/tags/RemoteAssetInfo\"],\n\t\t\t\t\t\t\t\t\t\"original-tags\": $tw.utils.stringifyList(tiddler.tags || []),\n\t\t\t\t\t\t\t\t\t\"server-url\": event.data.cookies.url\n\t\t\t\t\t\t\t\t},$tw.wiki.getModificationFields()));\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else if(event.data.cookies.type === \"save-tiddler\") {\n\t\t\t\t\t\t\tvar tiddler = $tw.utils.parseJSONSafe(event.data.body);\n\t\t\t\t\t\t\t$tw.wiki.addTiddler(new $tw.Tiddler(tiddler));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t},false);\n};\n\n})();\n","type":"application/javascript","module-type":"startup"},"$:/core/modules/startup/commands.js":{"title":"$:/core/modules/startup/commands.js","text":"/*\\\ntitle: $:/core/modules/startup/commands.js\ntype: application/javascript\nmodule-type: startup\n\nCommand processing\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"commands\";\nexports.platforms = [\"node\"];\nexports.after = [\"story\"];\nexports.synchronous = false;\n\nexports.startup = function(callback) {\n\t// On the server, start a commander with the command line arguments\n\tvar commander = new $tw.Commander(\n\t\t$tw.boot.argv,\n\t\tfunction(err) {\n\t\t\tif(err) {\n\t\t\t\treturn $tw.utils.error(\"Error: \" + err);\n\t\t\t}\n\t\t\tcallback();\n\t\t},\n\t\t$tw.wiki,\n\t\t{output: process.stdout, error: process.stderr}\n\t);\n\tcommander.execute();\n};\n\n})();\n","type":"application/javascript","module-type":"startup"},"$:/core/modules/startup/favicon.js":{"title":"$:/core/modules/startup/favicon.js","text":"/*\\\ntitle: $:/core/modules/startup/favicon.js\ntype: application/javascript\nmodule-type: startup\n\nFavicon handling\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"favicon\";\nexports.platforms = [\"browser\"];\nexports.after = [\"startup\"];\nexports.synchronous = true;\n\n// Favicon tiddler\nvar FAVICON_TITLE = \"$:/favicon.ico\";\n\nexports.startup = function() {\n\t// Set up the favicon\n\tsetFavicon();\n\t// Reset the favicon when the tiddler changes\n\t$tw.wiki.addEventListener(\"change\",function(changes) {\n\t\tif($tw.utils.hop(changes,FAVICON_TITLE)) {\n\t\t\tsetFavicon();\n\t\t}\n\t});\n};\n\nfunction setFavicon() {\n\tvar tiddler = $tw.wiki.getTiddler(FAVICON_TITLE);\n\tif(tiddler) {\n\t\tvar faviconLink = document.getElementById(\"faviconLink\");\n\t\tfaviconLink.setAttribute(\"href\",$tw.utils.makeDataUri(tiddler.fields.text,tiddler.fields.type,tiddler.fields._canonical_uri));\n\t}\n}\n\n})();\n","type":"application/javascript","module-type":"startup"},"$:/core/modules/startup/info.js":{"title":"$:/core/modules/startup/info.js","text":"/*\\\ntitle: $:/core/modules/startup/info.js\ntype: application/javascript\nmodule-type: startup\n\nInitialise $:/info tiddlers via $:/temp/info-plugin pseudo-plugin\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"info\";\nexports.before = [\"startup\"];\nexports.after = [\"load-modules\"];\nexports.synchronous = true;\n\nvar TITLE_INFO_PLUGIN = \"$:/temp/info-plugin\";\n\nexports.startup = function() {\n\t// Function to bake the info plugin with new tiddlers\n\tvar updateInfoPlugin = function(tiddlerFieldsArray) {\n\t\t// Get the existing tiddlers\n\t\tvar json = $tw.wiki.getTiddlerData(TITLE_INFO_PLUGIN,{tiddlers: {}});\n\t\t// Add the new ones\n\t\t$tw.utils.each(tiddlerFieldsArray,function(fields) {\n\t\t\tif(fields && fields.title) {\n\t\t\t\tjson.tiddlers[fields.title] = fields;\n\t\t\t}\n\t\t});\n\t\t// Bake the info tiddlers into a plugin. We use the non-standard plugin-type \"info\" because ordinary plugins are only registered asynchronously after being loaded dynamically\n\t\tvar fields = {\n\t\t\ttitle: TITLE_INFO_PLUGIN,\n\t\t\ttype: \"application/json\",\n\t\t\t\"plugin-type\": \"info\",\n\t\t\ttext: JSON.stringify(json,null,$tw.config.preferences.jsonSpaces)\n\t\t};\n\t\t$tw.wiki.addTiddler(new $tw.Tiddler(fields));\n\n\t};\n\t// Collect up the info tiddlers\n\tvar tiddlerFieldsArray = [];\n\t// Give each info module a chance to provide as many info tiddlers as they want as an array, and give them a callback for dynamically updating them\n\t$tw.modules.forEachModuleOfType(\"info\",function(title,moduleExports) {\n\t\tif(moduleExports && moduleExports.getInfoTiddlerFields) {\n\t\t\tArray.prototype.push.apply(tiddlerFieldsArray,moduleExports.getInfoTiddlerFields(updateInfoPlugin));\n\t\t}\n\t});\n\tupdateInfoPlugin(tiddlerFieldsArray);\n\tvar changes = $tw.wiki.readPluginInfo([TITLE_INFO_PLUGIN]);\n\t$tw.wiki.registerPluginTiddlers(\"info\",[TITLE_INFO_PLUGIN]);\n\t$tw.wiki.unpackPluginTiddlers();\n};\n\n})();\n","type":"application/javascript","module-type":"startup"},"$:/core/modules/startup/load-modules.js":{"title":"$:/core/modules/startup/load-modules.js","text":"/*\\\ntitle: $:/core/modules/startup/load-modules.js\ntype: application/javascript\nmodule-type: startup\n\nLoad core modules\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"load-modules\";\nexports.synchronous = true;\n\nexports.startup = function() {\n\t// Load modules\n\t$tw.modules.applyMethods(\"utils\",$tw.utils);\n\tif($tw.node) {\n\t\t$tw.modules.applyMethods(\"utils-node\",$tw.utils);\n\t}\n\tif($tw.browser) {\n\t\t$tw.modules.applyMethods(\"utils-browser\",$tw.utils);\n\t}\n\t$tw.modules.applyMethods(\"global\",$tw);\n\t$tw.modules.applyMethods(\"config\",$tw.config);\n\t$tw.Tiddler.fieldModules = $tw.modules.getModulesByTypeAsHashmap(\"tiddlerfield\");\n\t$tw.modules.applyMethods(\"tiddlermethod\",$tw.Tiddler.prototype);\n\t$tw.modules.applyMethods(\"wikimethod\",$tw.Wiki.prototype);\n\t$tw.wiki.addIndexersToWiki();\n\t$tw.modules.applyMethods(\"tiddlerdeserializer\",$tw.Wiki.tiddlerDeserializerModules);\n\t$tw.macros = $tw.modules.getModulesByTypeAsHashmap(\"macro\");\n\t$tw.wiki.initParsers();\n\t$tw.Commander.initCommands();\n};\n\n})();\n","type":"application/javascript","module-type":"startup"},"$:/core/modules/startup/password.js":{"title":"$:/core/modules/startup/password.js","text":"/*\\\ntitle: $:/core/modules/startup/password.js\ntype: application/javascript\nmodule-type: startup\n\nPassword handling\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"password\";\nexports.platforms = [\"browser\"];\nexports.after = [\"startup\"];\nexports.synchronous = true;\n\nexports.startup = function() {\n\t$tw.rootWidget.addEventListener(\"tm-set-password\",function(event) {\n\t\t$tw.passwordPrompt.createPrompt({\n\t\t\tserviceName: $tw.language.getString(\"Encryption/PromptSetPassword\"),\n\t\t\tnoUserName: true,\n\t\t\tsubmitText: $tw.language.getString(\"Encryption/SetPassword\"),\n\t\t\tcanCancel: true,\n\t\t\trepeatPassword: true,\n\t\t\tcallback: function(data) {\n\t\t\t\tif(data) {\n\t\t\t\t\t$tw.crypto.setPassword(data.password);\n\t\t\t\t}\n\t\t\t\treturn true; // Get rid of the password prompt\n\t\t\t}\n\t\t});\n\t});\n\t$tw.rootWidget.addEventListener(\"tm-clear-password\",function(event) {\n\t\tif($tw.browser) {\n\t\t\tif(!confirm($tw.language.getString(\"Encryption/ConfirmClearPassword\"))) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\t$tw.crypto.setPassword(null);\n\t});\n\t// Ensure that $:/isEncrypted is maintained properly\n\t$tw.wiki.addEventListener(\"change\",function(changes) {\n\t\tif($tw.utils.hop(changes,\"$:/isEncrypted\")) {\n\t\t\t$tw.crypto.updateCryptoStateTiddler();\n\t\t}\n\t});\n};\n\n})();\n","type":"application/javascript","module-type":"startup"},"$:/core/modules/startup/plugins.js":{"title":"$:/core/modules/startup/plugins.js","text":"/*\\\ntitle: $:/core/modules/startup/plugins.js\ntype: application/javascript\nmodule-type: startup\n\nStartup logic concerned with managing plugins\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"plugins\";\nexports.after = [\"load-modules\"];\nexports.before = [\"startup\"];\nexports.synchronous = true;\n\nvar TITLE_REQUIRE_RELOAD_DUE_TO_PLUGIN_CHANGE = \"$:/status/RequireReloadDueToPluginChange\";\n\nvar PREFIX_CONFIG_REGISTER_PLUGIN_TYPE = \"$:/config/RegisterPluginType/\";\n\nexports.startup = function() {\n\t$tw.wiki.addTiddler({title: TITLE_REQUIRE_RELOAD_DUE_TO_PLUGIN_CHANGE,text: \"no\"});\n\t$tw.wiki.addEventListener(\"change\",function(changes) {\n\t\t// Work out which of the changed tiddlers are plugins that we need to reregister\n\t\tvar changesToProcess = [],\n\t\t\trequireReloadDueToPluginChange = false;\n\t\t$tw.utils.each(Object.keys(changes),function(title) {\n\t\t\tvar tiddler = $tw.wiki.getTiddler(title),\n\t\t\t\trequiresReload = $tw.wiki.doesPluginRequireReload(title);\n\t\t\tif(requiresReload) {\n\t\t\t\trequireReloadDueToPluginChange = true;\n\t\t\t} else if(tiddler) {\n\t\t\t\tvar pluginType = tiddler.fields[\"plugin-type\"];\n\t\t\t\tif($tw.wiki.getTiddlerText(PREFIX_CONFIG_REGISTER_PLUGIN_TYPE + (tiddler.fields[\"plugin-type\"] || \"\"),\"no\") === \"yes\") {\n\t\t\t\t\tchangesToProcess.push(title);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\t// Issue warning if any of the tiddlers require a reload\n\t\tif(requireReloadDueToPluginChange) {\n\t\t\t$tw.wiki.addTiddler({title: TITLE_REQUIRE_RELOAD_DUE_TO_PLUGIN_CHANGE,text: \"yes\"});\n\t\t}\n\t\t// Read or delete the plugin info of the changed tiddlers\n\t\tif(changesToProcess.length > 0) {\n\t\t\tvar changes = $tw.wiki.readPluginInfo(changesToProcess);\n\t\t\tif(changes.modifiedPlugins.length > 0 || changes.deletedPlugins.length > 0) {\n\t\t\t\tvar changedShadowTiddlers = {};\n\t\t\t\t// Collect the shadow tiddlers of any deleted plugins\n\t\t\t\t$tw.utils.each(changes.deletedPlugins,function(pluginTitle) {\n\t\t\t\t\tvar pluginInfo = $tw.wiki.getPluginInfo(pluginTitle);\n\t\t\t\t\tif(pluginInfo) {\n\t\t\t\t\t\t$tw.utils.each(Object.keys(pluginInfo.tiddlers),function(title) {\n\t\t\t\t\t\t\tchangedShadowTiddlers[title] = true;\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\t// Collect the shadow tiddlers of any modified plugins\n\t\t\t\t$tw.utils.each(changes.modifiedPlugins,function(pluginTitle) {\n\t\t\t\t\tvar pluginInfo = $tw.wiki.getPluginInfo(pluginTitle);\n\t\t\t\t\tif(pluginInfo && pluginInfo.tiddlers) {\n\t\t\t\t\t\t$tw.utils.each(Object.keys(pluginInfo.tiddlers),function(title) {\n\t\t\t\t\t\t\tchangedShadowTiddlers[title] = false;\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\t// (Re-)register any modified plugins\n\t\t\t\t$tw.wiki.registerPluginTiddlers(null,changes.modifiedPlugins);\n\t\t\t\t// Unregister any deleted plugins\n\t\t\t\t$tw.wiki.unregisterPluginTiddlers(null,changes.deletedPlugins);\n\t\t\t\t// Unpack the shadow tiddlers\n\t\t\t\t$tw.wiki.unpackPluginTiddlers();\n\t\t\t\t// Queue change events for the changed shadow tiddlers\n\t\t\t\t$tw.utils.each(Object.keys(changedShadowTiddlers),function(title) {\n\t\t\t\t\t$tw.wiki.enqueueTiddlerEvent(title,changedShadowTiddlers[title]);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t});\n};\n\n})();\n","type":"application/javascript","module-type":"startup"},"$:/core/modules/startup/render.js":{"title":"$:/core/modules/startup/render.js","text":"/*\\\ntitle: $:/core/modules/startup/render.js\ntype: application/javascript\nmodule-type: startup\n\nTitle, stylesheet and page rendering\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"render\";\nexports.platforms = [\"browser\"];\nexports.after = [\"story\"];\nexports.synchronous = true;\n\n// Default story and history lists\nvar PAGE_TITLE_TITLE = \"$:/core/wiki/title\";\nvar PAGE_STYLESHEET_TITLE = \"$:/core/ui/PageStylesheet\";\nvar PAGE_TEMPLATE_TITLE = \"$:/core/ui/RootTemplate\";\n\n// Time (in ms) that we defer refreshing changes to draft tiddlers\nvar DRAFT_TIDDLER_TIMEOUT_TITLE = \"$:/config/Drafts/TypingTimeout\";\nvar THROTTLE_REFRESH_TIMEOUT = 400;\n\nexports.startup = function() {\n\t// Set up the title\n\t$tw.titleWidgetNode = $tw.wiki.makeTranscludeWidget(PAGE_TITLE_TITLE, {\n\t\tdocument: $tw.fakeDocument,\n\t\tparseAsInline: true,\n\t\timportPageMacros: true,\n\t});\n\t$tw.titleContainer = $tw.fakeDocument.createElement(\"div\");\n\t$tw.titleWidgetNode.render($tw.titleContainer,null);\n\tdocument.title = $tw.titleContainer.textContent;\n\t$tw.wiki.addEventListener(\"change\",function(changes) {\n\t\tif($tw.titleWidgetNode.refresh(changes,$tw.titleContainer,null)) {\n\t\t\tdocument.title = $tw.titleContainer.textContent;\n\t\t}\n\t});\n\t// Set up the styles\n\t$tw.styleWidgetNode = $tw.wiki.makeTranscludeWidget(PAGE_STYLESHEET_TITLE,{document: $tw.fakeDocument});\n\t$tw.styleContainer = $tw.fakeDocument.createElement(\"style\");\n\t$tw.styleWidgetNode.render($tw.styleContainer,null);\n\t$tw.styleWidgetNode.assignedStyles = $tw.styleContainer.textContent;\n\t$tw.styleElement = document.createElement(\"style\");\n\t$tw.styleElement.innerHTML = $tw.styleWidgetNode.assignedStyles;\n\tdocument.head.insertBefore($tw.styleElement,document.head.firstChild);\n\t$tw.wiki.addEventListener(\"change\",$tw.perf.report(\"styleRefresh\",function(changes) {\n\t\tif($tw.styleWidgetNode.refresh(changes,$tw.styleContainer,null)) {\n\t\t\tvar newStyles = $tw.styleContainer.textContent;\n\t\t\tif(newStyles !== $tw.styleWidgetNode.assignedStyles) {\n\t\t\t\t$tw.styleWidgetNode.assignedStyles = newStyles;\n\t\t\t\t$tw.styleElement.innerHTML = $tw.styleWidgetNode.assignedStyles;\n\t\t\t}\n\t\t}\n\t}));\n\t// Display the $:/core/ui/PageTemplate tiddler to kick off the display\n\t$tw.perf.report(\"mainRender\",function() {\n\t\t$tw.pageWidgetNode = $tw.wiki.makeTranscludeWidget(PAGE_TEMPLATE_TITLE,{document: document, parentWidget: $tw.rootWidget, recursionMarker: \"no\"});\n\t\t$tw.pageContainer = document.createElement(\"div\");\n\t\t$tw.utils.addClass($tw.pageContainer,\"tc-page-container-wrapper\");\n\t\tdocument.body.insertBefore($tw.pageContainer,document.body.firstChild);\n\t\t$tw.pageWidgetNode.render($tw.pageContainer,null);\n   \t\t$tw.hooks.invokeHook(\"th-page-refreshed\");\n\t})();\n\t// Remove any splash screen elements\n\tvar removeList = document.querySelectorAll(\".tc-remove-when-wiki-loaded\");\n\t$tw.utils.each(removeList,function(removeItem) {\n\t\tif(removeItem.parentNode) {\n\t\t\tremoveItem.parentNode.removeChild(removeItem);\n\t\t}\n\t});\n\t// Prepare refresh mechanism\n\tvar deferredChanges = Object.create(null),\n\t\ttimerId;\n\tfunction refresh() {\n\t\t// Process the refresh\n\t\t$tw.hooks.invokeHook(\"th-page-refreshing\");\n\t\t$tw.pageWidgetNode.refresh(deferredChanges);\n\t\tdeferredChanges = Object.create(null);\n\t\t$tw.hooks.invokeHook(\"th-page-refreshed\");\n\t}\n\tvar throttledRefresh = $tw.perf.report(\"throttledRefresh\",refresh);\n\n\t// Add the change event handler\n\t$tw.wiki.addEventListener(\"change\",$tw.perf.report(\"mainRefresh\",function(changes) {\n\t\t// Check if only tiddlers that are throttled have changed\n\t\tvar onlyThrottledTiddlersHaveChanged = true;\n\t\tfor(var title in changes) {\n\t\t\tvar tiddler = $tw.wiki.getTiddler(title);\n\t\t\tif(!$tw.wiki.isVolatileTiddler(title) && (!tiddler || !(tiddler.hasField(\"draft.of\") || tiddler.hasField(\"throttle.refresh\")))) {\n\t\t\t\tonlyThrottledTiddlersHaveChanged = false;\n\t\t\t}\n\t\t}\n\t\t// Defer the change if only drafts have changed\n\t\tif(timerId) {\n\t\t\tclearTimeout(timerId);\n\t\t}\n\t\ttimerId = null;\n\t\tif(onlyThrottledTiddlersHaveChanged) {\n\t\t\tvar timeout = parseInt($tw.wiki.getTiddlerText(DRAFT_TIDDLER_TIMEOUT_TITLE,\"\"),10);\n\t\t\tif(isNaN(timeout)) {\n\t\t\t\ttimeout = THROTTLE_REFRESH_TIMEOUT;\n\t\t\t}\n\t\t\ttimerId = setTimeout(throttledRefresh,timeout);\n\t\t\t$tw.utils.extend(deferredChanges,changes);\n\t\t} else {\n\t\t\t$tw.utils.extend(deferredChanges,changes);\n\t\t\trefresh();\n\t\t}\n\t}));\n\t// Fix up the link between the root widget and the page container\n\t$tw.rootWidget.domNodes = [$tw.pageContainer];\n\t$tw.rootWidget.children = [$tw.pageWidgetNode];\n\t// Run any post-render startup actions\n\t$tw.rootWidget.invokeActionsByTag(\"$:/tags/StartupAction/PostRender\");\n};\n\n})();\n","type":"application/javascript","module-type":"startup"},"$:/core/modules/startup/rootwidget.js":{"title":"$:/core/modules/startup/rootwidget.js","text":"/*\\\ntitle: $:/core/modules/startup/rootwidget.js\ntype: application/javascript\nmodule-type: startup\n\nSetup the root widget and the core root widget handlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"rootwidget\";\nexports.platforms = [\"browser\"];\nexports.after = [\"startup\"];\nexports.before = [\"story\"];\nexports.synchronous = true;\n\nexports.startup = function() {\n\t// Install the HTTP client event handler\n\t$tw.httpClient = new $tw.utils.HttpClient();\n\tvar getPropertiesWithPrefix = function(properties,prefix) {\n\t\tvar result = Object.create(null);\n\t\t$tw.utils.each(properties,function(value,name) {\n\t\t\tif(name.indexOf(prefix) === 0) {\n\t\t\t\tresult[name.substring(prefix.length)] = properties[name];\n\t\t\t}\n\t\t});\n\t\treturn result;\n\t};\n\t$tw.rootWidget.addEventListener(\"tm-http-request\",function(event) {\n\t\tvar params = event.paramObject || {};\n\t\t$tw.httpClient.initiateHttpRequest({\n\t\t\twiki: event.widget.wiki,\n\t\t\turl: params.url,\n\t\t\tmethod: params.method,\n\t\t\tbody: params.body,\n\t\t\tbinary: params.binary,\n\t\t\tuseDefaultHeaders: params.useDefaultHeaders,\n\t\t\toncompletion: params.oncompletion,\n\t\t\tonprogress: params.onprogress,\n\t\t\tbindStatus: params[\"bind-status\"],\n\t\t\tbindProgress: params[\"bind-progress\"],\n\t\t\tvariables: getPropertiesWithPrefix(params,\"var-\"),\n\t\t\theaders: getPropertiesWithPrefix(params,\"header-\"),\n\t\t\tpasswordHeaders: getPropertiesWithPrefix(params,\"password-header-\"),\n\t\t\tqueryStrings: getPropertiesWithPrefix(params,\"query-\"),\n\t\t\tpasswordQueryStrings: getPropertiesWithPrefix(params,\"password-query-\"),\n\t\t\tbasicAuthUsername: params[\"basic-auth-username\"],\n\t\t\tbasicAuthUsernameFromStore: params[\"basic-auth-username-from-store\"],\n\t\t\tbasicAuthPassword: params[\"basic-auth-password\"],\n\t\t\tbasicAuthPasswordFromStore: params[\"basic-auth-password-from-store\"],\n\t\t\tbearerAuthToken: params[\"bearer-auth-token\"],\n\t\t\tbearerAuthTokenFromStore: params[\"bearer-auth-token-from-store\"]\n\t\t});\n\t});\n\t$tw.rootWidget.addEventListener(\"tm-http-cancel-all-requests\",function(event) {\n\t\t$tw.httpClient.cancelAllHttpRequests();\n\t});\n\t// Install the modal message mechanism\n\t$tw.modal = new $tw.utils.Modal($tw.wiki);\n\t$tw.rootWidget.addEventListener(\"tm-modal\",function(event) {\n\t\t$tw.modal.display(event.param,{variables: event.paramObject, event: event});\n\t});\n\t$tw.rootWidget.addEventListener(\"tm-show-switcher\",function(event) {\n\t\t$tw.modal.display(\"$:/core/ui/SwitcherModal\",{variables: event.paramObject, event: event});\n\t});\n\t// Install the notification  mechanism\n\t$tw.notifier = new $tw.utils.Notifier($tw.wiki);\n\t$tw.rootWidget.addEventListener(\"tm-notify\",function(event) {\n\t\t$tw.notifier.display(event.param,{variables: event.paramObject});\n\t});\n\t// Install the copy-to-clipboard  mechanism\n\t$tw.rootWidget.addEventListener(\"tm-copy-to-clipboard\",function(event) {\n\t\t$tw.utils.copyToClipboard(event.param,{\n\t\t\tsuccessNotification: event.paramObject && event.paramObject.successNotification,\n\t\t\tfailureNotification: event.paramObject && event.paramObject.failureNotification\n\t\t});\n\t});\n\t// Install the tm-focus-selector message\n\t$tw.rootWidget.addEventListener(\"tm-focus-selector\",function(event) {\n\t\tvar selector = event.param || \"\",\n\t\t\telement,\n\t\t    \tbaseElement = event.event && event.event.target ? event.event.target.ownerDocument : document;\n\t\telement = $tw.utils.querySelectorSafe(selector,baseElement);\n\t\tif(element && element.focus) {\n\t\t\telement.focus(event.paramObject);\n\t\t}\n\t});\n\t// Install the tm-rename-tiddler and tm-relink-tiddler messages\n\tvar makeRenameHandler = function(method) {\n\t\treturn function(event) {\n\t\t\tvar options = {},\n\t\t\t\tparamObject = event.paramObject || {},\n\t\t\t\tfrom = paramObject.from || event.tiddlerTitle,\n\t\t\t\tto = paramObject.to;\n\t\t\toptions.dontRenameInTags = (paramObject.renameInTags === \"false\" || paramObject.renameInTags === \"no\") ? true : false;\n\t\t\toptions.dontRenameInLists = (paramObject.renameInLists === \"false\" || paramObject.renameInLists === \"no\") ? true : false;\n\t\t\t$tw.wiki[method](from,to,options);\n\t\t};\n\t};\n\t$tw.rootWidget.addEventListener(\"tm-rename-tiddler\",makeRenameHandler(\"renameTiddler\"));\n\t$tw.rootWidget.addEventListener(\"tm-relink-tiddler\",makeRenameHandler(\"relinkTiddler\"));\n\t// Install the scroller\n\t$tw.pageScroller = new $tw.utils.PageScroller();\n\t$tw.rootWidget.addEventListener(\"tm-scroll\",function(event) {\n\t\t$tw.pageScroller.handleEvent(event);\n\t});\n\tvar fullscreen = $tw.utils.getFullScreenApis();\n\tif(fullscreen) {\n\t\t$tw.rootWidget.addEventListener(\"tm-full-screen\",function(event) {\n\t\t\tvar fullScreenDocument = event.event ? event.event.target.ownerDocument : document;\n\t\t\tif(event.param === \"enter\") {\n\t\t\t\tfullScreenDocument.documentElement[fullscreen._requestFullscreen](Element.ALLOW_KEYBOARD_INPUT);\n\t\t\t} else if(event.param === \"exit\") {\n\t\t\t\tfullScreenDocument[fullscreen._exitFullscreen]();\n\t\t\t} else {\n\t\t\t\tif(fullScreenDocument[fullscreen._fullscreenElement]) {\n\t\t\t\t\tfullScreenDocument[fullscreen._exitFullscreen]();\n\t\t\t\t} else {\n\t\t\t\t\tfullScreenDocument.documentElement[fullscreen._requestFullscreen](Element.ALLOW_KEYBOARD_INPUT);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n};\n\n})();\n","type":"application/javascript","module-type":"startup"},"$:/core/modules/startup.js":{"title":"$:/core/modules/startup.js","text":"/*\\\ntitle: $:/core/modules/startup.js\ntype: application/javascript\nmodule-type: startup\n\nMiscellaneous startup logic for both the client and server.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"startup\";\nexports.after = [\"load-modules\"];\nexports.synchronous = true;\n\n// Set to `true` to enable performance instrumentation\nvar PERFORMANCE_INSTRUMENTATION_CONFIG_TITLE = \"$:/config/Performance/Instrumentation\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nexports.startup = function() {\n\t// Minimal browser detection\n\tif($tw.browser) {\n\t\t$tw.browser.isIE = (/msie|trident/i.test(navigator.userAgent));\n\t\t$tw.browser.isFirefox = !!document.mozFullScreenEnabled;\n\t\t// 2023-07-21 Edge returns UA below. So we use \"isChromeLike\"\n\t\t//'mozilla/5.0 (windows nt 10.0; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/114.0.0.0 safari/537.36 edg/114.0.1823.82'\n\t\t$tw.browser.isChromeLike = navigator.userAgent.toLowerCase().indexOf(\"chrome\") > -1;\n\t\t$tw.browser.hasTouch = !!window.matchMedia && window.matchMedia(\"(pointer: coarse)\").matches;\n\t\t$tw.browser.isMobileChrome = $tw.browser.isChromeLike && $tw.browser.hasTouch;\n\t}\n\t// Platform detection\n\t$tw.platform = {};\n\tif($tw.browser) {\n\t\t$tw.platform.isMac = /Mac/.test(navigator.platform);\n\t\t$tw.platform.isWindows = /win/i.test(navigator.platform);\n\t\t$tw.platform.isLinux = /Linux/i.test(navigator.platform);\n\t} else {\n\t\tswitch(require(\"os\").platform()) {\n\t\t\tcase \"darwin\":\n\t\t\t\t$tw.platform.isMac = true;\n\t\t\t\tbreak;\n\t\t\tcase \"win32\":\n\t\t\t\t$tw.platform.isWindows = true;\n\t\t\t\tbreak;\n\t\t\tcase \"freebsd\":\n\t\t\t\t$tw.platform.isLinux = true;\n\t\t\t\tbreak;\n\t\t\tcase \"linux\":\n\t\t\t\t$tw.platform.isLinux = true;\n\t\t\t\tbreak;\n\t\t}\n\t}\n\t// Initialise version\n\t$tw.version = $tw.utils.extractVersionInfo();\n\t// Set up the performance framework\n\t$tw.perf = new $tw.Performance($tw.wiki.getTiddlerText(PERFORMANCE_INSTRUMENTATION_CONFIG_TITLE,\"no\") === \"yes\");\n\t// Create a root widget for attaching event handlers. By using it as the parentWidget for another widget tree, one can reuse the event handlers\n\t$tw.rootWidget = new widget.widget({\n\t\ttype: \"widget\",\n\t\tchildren: []\n\t},{\n\t\twiki: $tw.wiki,\n\t\tdocument: $tw.browser ? document : $tw.fakeDocument\n\t});\n\t// Execute any startup actions\n\t$tw.rootWidget.invokeActionsByTag(\"$:/tags/StartupAction\");\n\tif($tw.browser) {\n\t\t$tw.rootWidget.invokeActionsByTag(\"$:/tags/StartupAction/Browser\");\n\t}\n\tif($tw.node) {\n\t\t$tw.rootWidget.invokeActionsByTag(\"$:/tags/StartupAction/Node\");\n\t}\n\t// Kick off the language manager and switcher\n\t$tw.language = new $tw.Language();\n\t$tw.languageSwitcher = new $tw.PluginSwitcher({\n\t\twiki: $tw.wiki,\n\t\tpluginType: \"language\",\n\t\tcontrollerTitle: \"$:/language\",\n\t\tdefaultPlugins: [\n\t\t\t\"$:/languages/en-GB\"\n\t\t],\n\t\tonSwitch: function(plugins) {\n\t\t\tif($tw.browser) {\n\t\t\t\tvar pluginTiddler = $tw.wiki.getTiddler(plugins[0]);\n\t\t\t\tif(pluginTiddler) {\n\t\t\t\t\tdocument.documentElement.setAttribute(\"dir\",pluginTiddler.getFieldString(\"text-direction\") || \"auto\");\n\t\t\t\t} else {\n\t\t\t\t\tdocument.documentElement.removeAttribute(\"dir\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\t// Kick off the theme manager\n\t$tw.themeManager = new $tw.PluginSwitcher({\n\t\twiki: $tw.wiki,\n\t\tpluginType: \"theme\",\n\t\tcontrollerTitle: \"$:/theme\",\n\t\tdefaultPlugins: [\n\t\t\t\"$:/themes/tiddlywiki/snowwhite\",\n\t\t\t\"$:/themes/tiddlywiki/vanilla\"\n\t\t]\n\t});\n\t// Kick off the keyboard manager\n\t$tw.keyboardManager = new $tw.KeyboardManager();\n\t// Listen for shortcuts\n\tif($tw.browser) {\n\t\t$tw.utils.addEventListeners(document,[{\n\t\t\tname: \"keydown\",\n\t\t\thandlerObject: $tw.keyboardManager,\n\t\t\thandlerMethod: \"handleKeydownEvent\"\n\t\t}]);\n\t}\n\t// Clear outstanding tiddler store change events to avoid an unnecessary refresh cycle at startup\n\t$tw.wiki.clearTiddlerEventQueue();\n\t// Find a working syncadaptor\n\t$tw.syncadaptor = undefined;\n\t$tw.modules.forEachModuleOfType(\"syncadaptor\",function(title,module) {\n\t\tif(!$tw.syncadaptor && module.adaptorClass) {\n\t\t\t$tw.syncadaptor = new module.adaptorClass({wiki: $tw.wiki});\n\t\t}\n\t});\n\t// Set up the syncer object if we've got a syncadaptor\n\tif($tw.syncadaptor) {\n\t\t$tw.syncer = new $tw.Syncer({\n\t\t\twiki: $tw.wiki,\n\t\t\tsyncadaptor: $tw.syncadaptor,\n\t\t\tlogging: $tw.wiki.getTiddlerText('$:/config/SyncLogging', \"yes\") === \"yes\"\n\t\t});\n\t}\n\t// Setup the saver handler\n\t$tw.saverHandler = new $tw.SaverHandler({\n\t\twiki: $tw.wiki,\n\t\tdirtyTracking: !$tw.syncadaptor,\n\t\tpreloadDirty: $tw.boot.preloadDirty || []\n\t});\n\t// Host-specific startup\n\tif($tw.browser) {\n\t\t// Install the popup manager\n\t\t$tw.popup = new $tw.utils.Popup();\n\t\t// Install the animator\n\t\t$tw.anim = new $tw.utils.Animator();\n\t}\n};\n\n})();\n","type":"application/javascript","module-type":"startup"},"$:/core/modules/startup/story.js":{"title":"$:/core/modules/startup/story.js","text":"/*\\\ntitle: $:/core/modules/startup/story.js\ntype: application/javascript\nmodule-type: startup\n\nLoad core modules\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"story\";\nexports.after = [\"startup\"];\nexports.synchronous = true;\n\n// Default story and history lists\nvar DEFAULT_STORY_TITLE = \"$:/StoryList\";\nvar DEFAULT_HISTORY_TITLE = \"$:/HistoryList\";\n\n// Default tiddlers\nvar DEFAULT_TIDDLERS_TITLE = \"$:/DefaultTiddlers\";\n\n// Config\nvar CONFIG_UPDATE_ADDRESS_BAR = \"$:/config/Navigation/UpdateAddressBar\"; // Can be \"no\", \"permalink\", \"permaview\"\nvar CONFIG_UPDATE_HISTORY = \"$:/config/Navigation/UpdateHistory\"; // Can be \"yes\" or \"no\"\nvar CONFIG_PERMALINKVIEW_COPY_TO_CLIPBOARD = \"$:/config/Navigation/Permalinkview/CopyToClipboard\"; // Can be \"yes\" (default) or \"no\"\nvar CONFIG_PERMALINKVIEW_UPDATE_ADDRESS_BAR = \"$:/config/Navigation/Permalinkview/UpdateAddressBar\"; // Can be \"yes\" (default) or \"no\"\n\n\n// Links to help, if there is no param\nvar HELP_OPEN_EXTERNAL_WINDOW = \"http://tiddlywiki.com/#WidgetMessage%3A%20tm-open-external-window\";\n\nexports.startup = function() {\n\t// Open startup tiddlers\n\topenStartupTiddlers({\n\t\tdisableHistory: $tw.boot.disableStartupNavigation\n\t});\n\tif($tw.browser) {\n\t\t// Set up location hash update\n\t\t$tw.wiki.addEventListener(\"change\",function(changes) {\n\t\t\tif($tw.utils.hop(changes,DEFAULT_STORY_TITLE) || $tw.utils.hop(changes,DEFAULT_HISTORY_TITLE)) {\n\t\t\t\tupdateLocationHash({\n\t\t\t\t\tupdateAddressBar: $tw.wiki.getTiddlerText(CONFIG_UPDATE_ADDRESS_BAR,\"permaview\").trim(),\n\t\t\t\t\tupdateHistory: $tw.wiki.getTiddlerText(CONFIG_UPDATE_HISTORY,\"no\").trim()\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t\t// Listen for changes to the browser location hash\n\t\twindow.addEventListener(\"hashchange\",function() {\n\t\t\tvar hash = $tw.utils.getLocationHash();\n\t\t\tif(hash !== $tw.locationHash) {\n\t\t\t\t$tw.locationHash = hash;\n\t\t\t\tif(hash !== \"#\") {\n\t\t\t\t\topenStartupTiddlers({defaultToCurrentStory: true});\n\t\t\t\t}\n\t\t\t}\n\t\t},false);\n\t\t// Listen for the tm-browser-refresh message\n\t\t$tw.rootWidget.addEventListener(\"tm-browser-refresh\",function(event) {\n\t\t\twindow.location.reload(true);\n\t\t});\n\t\t// Listen for tm-open-external-window message\n\t\t$tw.rootWidget.addEventListener(\"tm-open-external-window\",function(event) {\n\t\t\tvar paramObject = event.paramObject || {},\n\t\t\t\tstrUrl = event.param || HELP_OPEN_EXTERNAL_WINDOW,\n\t\t\t\tstrWindowName = paramObject.windowName,\n\t\t\t\tstrWindowFeatures = paramObject.windowFeatures;\n\t\t\twindow.open(strUrl, strWindowName, strWindowFeatures);\n\t\t});\n\t\t// Listen for the tm-print message\n\t\t$tw.rootWidget.addEventListener(\"tm-print\",function(event) {\n\t\t\t(event.event.view || window).print();\n\t\t});\n\t\t// Listen for the tm-home message\n\t\t$tw.rootWidget.addEventListener(\"tm-home\",function(event) {\n\t\t\twindow.location.hash = \"\";\n\t\t\tvar storyFilter = $tw.wiki.getTiddlerText(DEFAULT_TIDDLERS_TITLE),\n\t\t\t\tstoryList = $tw.wiki.filterTiddlers(storyFilter);\n\t\t\t//invoke any hooks that might change the default story list\n\t\t\tstoryList = $tw.hooks.invokeHook(\"th-opening-default-tiddlers-list\",storyList);\n\t\t\t$tw.wiki.addTiddler({title: DEFAULT_STORY_TITLE, text: \"\", list: storyList},$tw.wiki.getModificationFields());\n\t\t\tif(storyList[0]) {\n\t\t\t\t$tw.wiki.addToHistory(storyList[0]);\n\t\t\t}\n\t\t});\n\t\t// Listen for the tm-permalink message\n\t\t$tw.rootWidget.addEventListener(\"tm-permalink\",function(event) {\n\t\t\tupdateLocationHash({\n\t\t\t\tupdateAddressBar: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_UPDATE_ADDRESS_BAR,\"yes\").trim() === \"yes\" ? \"permalink\" : \"none\",\n\t\t\t\tupdateHistory: $tw.wiki.getTiddlerText(CONFIG_UPDATE_HISTORY,\"no\").trim(),\n\t\t\t\ttargetTiddler: event.param || event.tiddlerTitle,\n\t\t\t\tcopyToClipboard: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_COPY_TO_CLIPBOARD,\"yes\").trim() === \"yes\" ? \"permalink\" : \"none\",\n\t\t\t\tsuccessNotification: event.paramObject && event.paramObject.successNotification,\n\t\t\t\tfailureNotification: event.paramObject && event.paramObject.failureNotification\n\t\t\t});\n\t\t});\n\t\t// Listen for the tm-permaview message\n\t\t$tw.rootWidget.addEventListener(\"tm-permaview\",function(event) {\n\t\t\tupdateLocationHash({\n\t\t\t\tupdateAddressBar: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_UPDATE_ADDRESS_BAR,\"yes\").trim() === \"yes\" ? \"permaview\" : \"none\",\n\t\t\t\tupdateHistory: $tw.wiki.getTiddlerText(CONFIG_UPDATE_HISTORY,\"no\").trim(),\n\t\t\t\ttargetTiddler: event.param || event.tiddlerTitle,\n\t\t\t\tcopyToClipboard: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_COPY_TO_CLIPBOARD,\"yes\").trim() === \"yes\" ? \"permaview\" : \"none\",\n\t\t\t\tsuccessNotification: event.paramObject && event.paramObject.successNotification,\n\t\t\t\tfailureNotification: event.paramObject && event.paramObject.failureNotification\n\t\t\t});\n\t\t});\n\t}\n};\n\n/*\nProcess the location hash to open the specified tiddlers. Options:\ndisableHistory: if true $:/History is NOT updated\ndefaultToCurrentStory: If true, the current story is retained as the default, instead of opening the default tiddlers\n*/\nfunction openStartupTiddlers(options) {\n\toptions = options || {};\n\t// Work out the target tiddler and the story filter. \"null\" means \"unspecified\"\n\tvar target = null,\n\t\tstoryFilter = null;\n\tif($tw.locationHash.length > 1) {\n\t\tvar hash = $tw.locationHash.substr(1),\n\t\t\tsplit = hash.indexOf(\":\");\n\t\tif(split === -1) {\n\t\t\ttarget = $tw.utils.decodeURIComponentSafe(hash.trim());\n\t\t} else {\n\t\t\ttarget = $tw.utils.decodeURIComponentSafe(hash.substr(0,split).trim());\n\t\t\tstoryFilter = $tw.utils.decodeURIComponentSafe(hash.substr(split + 1).trim());\n\t\t}\n\t}\n\t// If the story wasn't specified use the current tiddlers or a blank story\n\tif(storyFilter === null) {\n\t\tif(options.defaultToCurrentStory) {\n\t\t\tvar currStoryList = $tw.wiki.getTiddlerList(DEFAULT_STORY_TITLE);\n\t\t\tstoryFilter = $tw.utils.stringifyList(currStoryList);\n\t\t} else {\n\t\t\tif(target && target !== \"\") {\n\t\t\t\tstoryFilter = \"\";\n\t\t\t} else {\n\t\t\t\tstoryFilter = $tw.wiki.getTiddlerText(DEFAULT_TIDDLERS_TITLE);\n\t\t\t}\n\t\t}\n\t}\n\t// Process the story filter to get the story list\n\tvar storyList = $tw.wiki.filterTiddlers(storyFilter);\n\t// Invoke any hooks that want to change the default story list\n\tstoryList = $tw.hooks.invokeHook(\"th-opening-default-tiddlers-list\",storyList);\n\t// If the target tiddler isn't included then splice it in at the top\n\tif(target && storyList.indexOf(target) === -1) {\n\t\tstoryList.unshift(target);\n\t}\n\t// Save the story list\n\t$tw.wiki.addTiddler({title: DEFAULT_STORY_TITLE, text: \"\", list: storyList},$tw.wiki.getModificationFields());\n\t// Update history\n\tvar story = new $tw.Story({\n\t\twiki: $tw.wiki,\n\t\tstoryTitle: DEFAULT_STORY_TITLE,\n\t\thistoryTitle: DEFAULT_HISTORY_TITLE\n\t});\n\tif(!options.disableHistory) {\n\t\t// If a target tiddler was specified add it to the history stack\n\t\tif(target && target !== \"\") {\n\t\t\t// The target tiddler doesn't need double square brackets, but we'll silently remove them if they're present\n\t\t\tif(target.indexOf(\"[[\") === 0 && target.substr(-2) === \"]]\") {\n\t\t\t\ttarget = target.substr(2,target.length - 4);\n\t\t\t}\n\t\t\tstory.addToHistory(target);\n\t\t} else if(storyList.length > 0) {\n\t\t\tstory.addToHistory(storyList[0]);\n\t\t}\n\t}\n}\n\n/*\noptions: See below\noptions.updateAddressBar: \"permalink\", \"permaview\" or \"no\" (defaults to \"permaview\")\noptions.updateHistory: \"yes\" or \"no\" (defaults to \"no\")\noptions.copyToClipboard: \"permalink\", \"permaview\" or \"no\" (defaults to \"no\")\noptions.targetTiddler: optional title of target tiddler for permalink\noptions.successNotification: optional title of tiddler to use as the notification in case of success\noptions.failureNotification: optional title of tiddler to use as the notification in case of failure\n*/\nfunction updateLocationHash(options) {\n\t// Get the story and the history stack\n\tvar storyList = $tw.wiki.getTiddlerList(DEFAULT_STORY_TITLE),\n\t\thistoryList = $tw.wiki.getTiddlerData(DEFAULT_HISTORY_TITLE,[]),\n\t\ttargetTiddler = \"\";\n\tif(options.targetTiddler) {\n\t\ttargetTiddler = options.targetTiddler;\n\t} else {\n\t\t// The target tiddler is the one at the top of the stack\n\t\tif(historyList.length > 0) {\n\t\t\ttargetTiddler = historyList[historyList.length-1].title;\n\t\t}\n\t\t// Blank the target tiddler if it isn't present in the story\n\t\tif(storyList.indexOf(targetTiddler) === -1) {\n\t\t\ttargetTiddler = \"\";\n\t\t}\n\t}\n\t// Assemble the location hash\n\tswitch(options.updateAddressBar) {\n\t\tcase \"permalink\":\n\t\t\t$tw.locationHash = \"#\" + encodeURIComponent(targetTiddler);\n\t\t\tbreak;\n\t\tcase \"permaview\":\n\t\t\t$tw.locationHash = \"#\" + encodeURIComponent(targetTiddler) + \":\" + encodeURIComponent($tw.utils.stringifyList(storyList));\n\t\t\tbreak;\n\t}\n\t// Copy URL to the clipboard\n\tvar url = \"\";\n\tswitch(options.copyToClipboard) {\n\t\tcase \"permalink\":\n\t\t\turl = $tw.utils.getLocationPath() + \"#\" + encodeURIComponent(targetTiddler);\n\t\t\tbreak;\n\t\tcase \"permaview\":\n\t\t\turl = $tw.utils.getLocationPath() + \"#\" + encodeURIComponent(targetTiddler) + \":\" + encodeURIComponent($tw.utils.stringifyList(storyList));\n\t\t\tbreak;\n\t}\n\tif(url) {\n\t\t$tw.utils.copyToClipboard(url,{successNotification: options.successNotification, failureNotification: options.failureNotification});\n\t}\n\t// Only change the location hash if we must, thus avoiding unnecessary onhashchange events\n\tif($tw.utils.getLocationHash() !== $tw.locationHash) {\n\t\tif(options.updateHistory === \"yes\") {\n\t\t\t// Assign the location hash so that history is updated\n\t\t\twindow.location.hash = $tw.locationHash;\n\t\t} else {\n\t\t\t// We use replace so that browser history isn't affected\n\t\t\twindow.location.replace(window.location.toString().split(\"#\")[0] + $tw.locationHash);\n\t\t}\n\t}\n}\n\n})();\n","type":"application/javascript","module-type":"startup"},"$:/core/modules/startup/windows.js":{"title":"$:/core/modules/startup/windows.js","text":"/*\\\ntitle: $:/core/modules/startup/windows.js\ntype: application/javascript\nmodule-type: startup\n\nSetup root widget handlers for the messages concerned with opening external browser windows\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"windows\";\nexports.platforms = [\"browser\"];\nexports.after = [\"startup\"];\nexports.synchronous = true;\n\n// Global to keep track of open windows (hashmap by title)\n$tw.windows = {};\n// Default template to use for new windows\nvar DEFAULT_WINDOW_TEMPLATE = \"$:/core/templates/single.tiddler.window\";\n\nexports.startup = function() {\n\t// Handle open window message\n\t$tw.rootWidget.addEventListener(\"tm-open-window\",function(event) {\n\t\t// Get the parameters\n\t\tvar refreshHandler,\n\t\t\ttitle = event.param || event.tiddlerTitle,\n\t\t\tparamObject = event.paramObject || {},\n\t\t\twindowTitle = paramObject.windowTitle || title,\n\t\t\twindowID = paramObject.windowID || title,\n\t\t\ttemplate = paramObject.template || DEFAULT_WINDOW_TEMPLATE,\n\t\t\twidth = paramObject.width || \"700\",\n\t\t\theight = paramObject.height || \"600\",\n\t\t\ttop = paramObject.top,\n\t\t\tleft = paramObject.left,\n\t\t\tvariables = $tw.utils.extend({},paramObject,{currentTiddler: title, \"tv-window-id\": windowID});\n\t\t// Open the window\n\t\tvar srcWindow,\n\t\t\tsrcDocument;\n\t\t// In case that popup blockers deny opening a new window\n\t\ttry {\n\t\t\tsrcWindow = window.open(\"\",\"external-\" + windowID,\"scrollbars,width=\" + width + \",height=\" + height + (top ? \",top=\" + top : \"\" ) + (left ? \",left=\" + left : \"\" )),\n\t\t\tsrcDocument = srcWindow.document;\n\t\t}\n\t\tcatch(e) {\n\t\t\treturn;\n\t\t}\n\t\t$tw.windows[windowID] = srcWindow;\n\t\t// Check for reopening the same window\n\t\tif(srcWindow.haveInitialisedWindow) {\n\t\t\tsrcWindow.focus();\n\t\t\treturn;\n\t\t}\n\t\t// Initialise the document\n\t\tsrcDocument.write(\"<!DOCTYPE html><head></head><body class='tc-body tc-single-tiddler-window'></body></html>\");\n\t\tsrcDocument.close();\n\t\tsrcDocument.title = windowTitle;\n\t\tsrcWindow.addEventListener(\"beforeunload\",function(event) {\n\t\t\tdelete $tw.windows[windowID];\n\t\t\t$tw.wiki.removeEventListener(\"change\",refreshHandler);\n\t\t},false);\n\t\t// Set up the styles\n\t\tvar styleWidgetNode = $tw.wiki.makeTranscludeWidget(\"$:/core/ui/PageStylesheet\",{\n\t\t\t\tdocument: $tw.fakeDocument,\n\t\t\t\tvariables: variables,\n\t\t\t\timportPageMacros: true}),\n\t\t\tstyleContainer = $tw.fakeDocument.createElement(\"style\");\n\t\tstyleWidgetNode.render(styleContainer,null);\n\t\tvar styleElement = srcDocument.createElement(\"style\");\n\t\tstyleElement.innerHTML = styleContainer.textContent;\n\t\tsrcDocument.head.insertBefore(styleElement,srcDocument.head.firstChild);\n\t\t// Render the text of the tiddler\n\t\tvar parser = $tw.wiki.parseTiddler(template),\n\t\t\twidgetNode = $tw.wiki.makeWidget(parser,{document: srcDocument, parentWidget: $tw.rootWidget, variables: variables});\n\t\twidgetNode.render(srcDocument.body,srcDocument.body.firstChild);\n\t\t// Function to handle refreshes\n\t\trefreshHandler = function(changes) {\n\t\t\tif(styleWidgetNode.refresh(changes,styleContainer,null)) {\n\t\t\t\tstyleElement.innerHTML = styleContainer.textContent;\n\t\t\t}\n\t\t\twidgetNode.refresh(changes);\n\t\t};\n\t\t$tw.wiki.addEventListener(\"change\",refreshHandler);\n\t\t// Listen for keyboard shortcuts\n\t\t$tw.utils.addEventListeners(srcDocument,[{\n\t\t\tname: \"keydown\",\n\t\t\thandlerObject: $tw.keyboardManager,\n\t\t\thandlerMethod: \"handleKeydownEvent\"\n\t\t}]);\n\t\tsrcWindow.document.documentElement.addEventListener(\"click\",$tw.popup,true);\n\t\tsrcWindow.haveInitialisedWindow = true;\n\t});\n\t$tw.rootWidget.addEventListener(\"tm-close-window\",function(event) {\n\t\tvar windowID = event.param,\n\t\t\twin = $tw.windows[windowID];\n\t\t\tif(win) {\n\t\t\t\twin.close();\n\t\t\t}\n\t});\n\tvar closeAllWindows = function() {\n\t\t$tw.utils.each($tw.windows,function(win) {\n\t\t\twin.close();\n\t\t});\n\t}\n\t$tw.rootWidget.addEventListener(\"tm-close-all-windows\",closeAllWindows);\n\t// Close open windows when unloading main window\n\t$tw.addUnloadTask(closeAllWindows);\n};\n\n})();\n","type":"application/javascript","module-type":"startup"},"$:/core/modules/story.js":{"title":"$:/core/modules/story.js","text":"/*\\\ntitle: $:/core/modules/story.js\ntype: application/javascript\nmodule-type: global\n\nLightweight object for managing interactions with the story and history lists.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nConstruct Story object with options:\nwiki: reference to wiki object to use to resolve tiddler titles\nstoryTitle: title of story list tiddler\nhistoryTitle: title of history list tiddler\n*/\nfunction Story(options) {\n\toptions = options || {};\n\tthis.wiki = options.wiki || $tw.wiki;\n\tthis.storyTitle = options.storyTitle || \"$:/StoryList\";\n\tthis.historyTitle = options.historyTitle || \"$:/HistoryList\";\n};\n\nStory.prototype.navigateTiddler = function(navigateTo,navigateFromTitle,navigateFromClientRect) {\n\tthis.addToStory(navigateTo,navigateFromTitle);\n\tthis.addToHistory(navigateTo,navigateFromClientRect);\n};\n\nStory.prototype.getStoryList = function() {\n\treturn this.wiki.getTiddlerList(this.storyTitle) || [];\n};\n\nStory.prototype.addToStory = function(navigateTo,navigateFromTitle,options) {\n\toptions = options || {};\n\tvar storyList = this.getStoryList();\n\t// See if the tiddler is already there\n\tvar slot = storyList.indexOf(navigateTo);\n\t// Quit if it already exists in the story river\n\tif(slot >= 0) {\n\t\treturn;\n\t}\n\t// First we try to find the position of the story element we navigated from\n\tvar fromIndex = storyList.indexOf(navigateFromTitle);\n\tif(fromIndex >= 0) {\n\t\t// The tiddler is added from inside the river\n\t\t// Determine where to insert the tiddler; Fallback is \"below\"\n\t\tswitch(options.openLinkFromInsideRiver) {\n\t\t\tcase \"top\":\n\t\t\t\tslot = 0;\n\t\t\t\tbreak;\n\t\t\tcase \"bottom\":\n\t\t\t\tslot = storyList.length;\n\t\t\t\tbreak;\n\t\t\tcase \"above\":\n\t\t\t\tslot = fromIndex;\n\t\t\t\tbreak;\n\t\t\tcase \"below\": // Intentional fall-through\n\t\t\tdefault:\n\t\t\t\tslot = fromIndex + 1;\n\t\t\t\tbreak;\n\t\t}\n\t} else {\n\t\t// The tiddler is opened from outside the river. Determine where to insert the tiddler; default is \"top\"\n\t\tif(options.openLinkFromOutsideRiver === \"bottom\") {\n\t\t\t// Insert at bottom\n\t\t\tslot = storyList.length;\n\t\t} else {\n\t\t\t// Insert at top\n\t\t\tslot = 0;\n\t\t}\n\t}\n\t// Add the tiddler\n\tstoryList.splice(slot,0,navigateTo);\n\t// Save the story\n\tthis.saveStoryList(storyList);\n};\n\nStory.prototype.saveStoryList = function(storyList) {\n\tvar storyTiddler = this.wiki.getTiddler(this.storyTitle);\n\tthis.wiki.addTiddler(new $tw.Tiddler(\n\t\tthis.wiki.getCreationFields(),\n\t\t{title: this.storyTitle},\n\t\tstoryTiddler,\n\t\t{list: storyList},\n\t\tthis.wiki.getModificationFields()\n\t));\n};\n\nStory.prototype.addToHistory = function(navigateTo,navigateFromClientRect) {\n\tvar titles = $tw.utils.isArray(navigateTo) ? navigateTo : [navigateTo];\n\t// Add a new record to the top of the history stack\n\tvar historyList = this.wiki.getTiddlerData(this.historyTitle,[]);\n\t$tw.utils.each(titles,function(title) {\n\t\thistoryList.push({title: title, fromPageRect: navigateFromClientRect});\n\t});\n\tthis.wiki.setTiddlerData(this.historyTitle,historyList,{\"current-tiddler\": titles[titles.length-1]});\n};\n\nStory.prototype.storyCloseTiddler = function(targetTitle) {\n// TBD\n};\n\nStory.prototype.storyCloseAllTiddlers = function() {\n// TBD\n};\n\nStory.prototype.storyCloseOtherTiddlers = function(targetTitle) {\n// TBD\n};\n\nStory.prototype.storyEditTiddler = function(targetTitle) {\n// TBD\n};\n\nStory.prototype.storyDeleteTiddler = function(targetTitle) {\n// TBD\n};\n\nStory.prototype.storySaveTiddler = function(targetTitle) {\n// TBD\n};\n\nStory.prototype.storyCancelTiddler = function(targetTitle) {\n// TBD\n};\n\nStory.prototype.storyNewTiddler = function(targetTitle) {\n// TBD\n};\n\nexports.Story = Story;\n\n\n})();\n","type":"application/javascript","module-type":"global"},"$:/core/modules/storyviews/classic.js":{"title":"$:/core/modules/storyviews/classic.js","text":"/*\\\ntitle: $:/core/modules/storyviews/classic.js\ntype: application/javascript\nmodule-type: storyview\n\nViews the story as a linear sequence\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar easing = \"cubic-bezier(0.645, 0.045, 0.355, 1)\"; // From http://easings.net/#easeInOutCubic\n\nvar ClassicStoryView = function(listWidget) {\n\tthis.listWidget = listWidget;\n};\n\nClassicStoryView.prototype.navigateTo = function(historyInfo) {\n\tvar duration = $tw.utils.getAnimationDuration()\n\tvar listElementIndex = this.listWidget.findListItem(0,historyInfo.title);\n\tif(listElementIndex === undefined) {\n\t\treturn;\n\t}\n\tvar listItemWidget = this.listWidget.children[listElementIndex],\n\t\ttargetElement = listItemWidget.findFirstDomNode();\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!targetElement || targetElement.nodeType === Node.TEXT_NODE) {\n\t\treturn;\n\t}\n\t// Scroll the node into view\n\tthis.listWidget.dispatchEvent({type: \"tm-scroll\", target: targetElement});\n};\n\nClassicStoryView.prototype.insert = function(widget) {\n\tvar duration = $tw.utils.getAnimationDuration();\n\tif(duration) {\n\t\tvar targetElement = widget.findFirstDomNode();\n\t\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\t\tif(!targetElement || targetElement.nodeType === Node.TEXT_NODE) {\n\t\t\treturn;\n\t\t}\n\t\t// Get the current height of the tiddler\n\t\tvar computedStyle = window.getComputedStyle(targetElement),\n\t\t\tcurrMarginBottom = parseInt(computedStyle.marginBottom,10),\n\t\t\tcurrMarginTop = parseInt(computedStyle.marginTop,10),\n\t\t\tcurrHeight = targetElement.offsetHeight + currMarginTop;\n\t\t// Reset the margin once the transition is over\n\t\tsetTimeout(function() {\n\t\t\t$tw.utils.setStyle(targetElement,[\n\t\t\t\t{transition: \"none\"},\n\t\t\t\t{marginBottom: \"\"}\n\t\t\t]);\n\t\t},duration);\n\t\t// Set up the initial position of the element\n\t\t$tw.utils.setStyle(targetElement,[\n\t\t\t{transition: \"none\"},\n\t\t\t{marginBottom: (-currHeight) + \"px\"},\n\t\t\t{opacity: \"0.0\"}\n\t\t]);\n\t\t$tw.utils.forceLayout(targetElement);\n\t\t// Transition to the final position\n\t\t$tw.utils.setStyle(targetElement,[\n\t\t\t{transition: \"opacity \" + duration + \"ms \" + easing + \", \" +\n\t\t\t\t\t\t\"margin-bottom \" + duration + \"ms \" + easing},\n\t\t\t{marginBottom: currMarginBottom + \"px\"},\n\t\t\t{opacity: \"1.0\"}\n\t]);\n\t}\n};\n\nClassicStoryView.prototype.remove = function(widget) {\n\tvar duration = $tw.utils.getAnimationDuration();\n\tif(duration) {\n\t\tvar targetElement = widget.findFirstDomNode(),\n\t\t\tremoveElement = function() {\n\t\t\t\twidget.removeChildDomNodes();\n\t\t\t};\n\t\t// Blur the focus if it is within the descendents of the node we are removing\n\t\tif($tw.utils.domContains(targetElement,targetElement.ownerDocument.activeElement)) {\n\t\t\ttargetElement.ownerDocument.activeElement.blur();\n\t\t}\n\t\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\t\tif(!targetElement || targetElement.nodeType === Node.TEXT_NODE) {\n\t\t\tremoveElement();\n\t\t\treturn;\n\t\t}\n\t\t// Get the current height of the tiddler\n\t\tvar currWidth = targetElement.offsetWidth,\n\t\t\tcomputedStyle = window.getComputedStyle(targetElement),\n\t\t\tcurrMarginBottom = parseInt(computedStyle.marginBottom,10),\n\t\t\tcurrMarginTop = parseInt(computedStyle.marginTop,10),\n\t\t\tcurrHeight = targetElement.offsetHeight + currMarginTop;\n\t\t// Remove the dom nodes of the widget at the end of the transition\n\t\tsetTimeout(removeElement,duration);\n\t\t// Animate the closure\n\t\t$tw.utils.setStyle(targetElement,[\n\t\t\t{transition: \"none\"},\n\t\t\t{transform: \"translateX(0px)\"},\n\t\t\t{marginBottom:  currMarginBottom + \"px\"},\n\t\t\t{opacity: \"1.0\"}\n\t\t]);\n\t\t$tw.utils.forceLayout(targetElement);\n\t\t$tw.utils.setStyle(targetElement,[\n\t\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms \" + easing + \", \" +\n\t\t\t\t\t\t\"opacity \" + duration + \"ms \" + easing + \", \" +\n\t\t\t\t\t\t\"margin-bottom \" + duration + \"ms \" + easing},\n\t\t\t{transform: \"translateX(-\" + currWidth + \"px)\"},\n\t\t\t{marginBottom: (-currHeight) + \"px\"},\n\t\t\t{opacity: \"0.0\"}\n\t\t]);\n\t} else {\n\t\twidget.removeChildDomNodes();\n\t}\n};\n\nexports.classic = ClassicStoryView;\n\n})();\n","type":"application/javascript","module-type":"storyview"},"$:/core/modules/storyviews/pop.js":{"title":"$:/core/modules/storyviews/pop.js","text":"/*\\\ntitle: $:/core/modules/storyviews/pop.js\ntype: application/javascript\nmodule-type: storyview\n\nAnimates list insertions and removals\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar PopStoryView = function(listWidget) {\n\tthis.listWidget = listWidget;\n};\n\nPopStoryView.prototype.navigateTo = function(historyInfo) {\n\tvar listElementIndex = this.listWidget.findListItem(0,historyInfo.title);\n\tif(listElementIndex === undefined) {\n\t\treturn;\n\t}\n\tvar listItemWidget = this.listWidget.children[listElementIndex],\n\t\ttargetElement = listItemWidget.findFirstDomNode();\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!targetElement || targetElement.nodeType === Node.TEXT_NODE) {\n\t\treturn;\n\t}\n\t// Scroll the node into view\n\tthis.listWidget.dispatchEvent({type: \"tm-scroll\", target: targetElement});\n};\n\nPopStoryView.prototype.insert = function(widget) {\n\tvar targetElement = widget.findFirstDomNode(),\n\t\tduration = $tw.utils.getAnimationDuration();\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!targetElement || targetElement.nodeType === Node.TEXT_NODE) {\n\t\treturn;\n\t}\n\t// Reset once the transition is over\n\tsetTimeout(function() {\n\t\t$tw.utils.setStyle(targetElement,[\n\t\t\t{transition: \"none\"},\n\t\t\t{transform: \"none\"}\n\t\t]);\n\t\t$tw.utils.setStyle(widget.document.body,[\n\t\t\t{\"overflow-x\": \"\"}\n\t\t]);\n\t},duration);\n\t// Prevent the page from overscrolling due to the zoom factor\n\t$tw.utils.setStyle(widget.document.body,[\n\t\t{\"overflow-x\": \"hidden\"}\n\t]);\n\t// Set up the initial position of the element\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transition: \"none\"},\n\t\t{transform: \"scale(2)\"},\n\t\t{opacity: \"0.0\"}\n\t]);\n\t$tw.utils.forceLayout(targetElement);\n\t// Transition to the final position\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"opacity \" + duration + \"ms ease-in-out\"},\n\t\t{transform: \"scale(1)\"},\n\t\t{opacity: \"1.0\"}\n\t]);\n};\n\nPopStoryView.prototype.remove = function(widget) {\n\tvar targetElement = widget.findFirstDomNode(),\n\t\tduration = $tw.utils.getAnimationDuration(),\n\t\tremoveElement = function() {\n\t\t\tif(targetElement && targetElement.parentNode) {\n\t\t\t\twidget.removeChildDomNodes();\n\t\t\t}\n\t\t};\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!targetElement || targetElement.nodeType === Node.TEXT_NODE) {\n\t\tremoveElement();\n\t\treturn;\n\t}\n\t// Remove the element at the end of the transition\n\tsetTimeout(removeElement,duration);\n\t// Animate the closure\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transition: \"none\"},\n\t\t{transform: \"scale(1)\"},\n\t\t{opacity: \"1.0\"}\n\t]);\n\t$tw.utils.forceLayout(targetElement);\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"opacity \" + duration + \"ms ease-in-out\"},\n\t\t{transform: \"scale(0.1)\"},\n\t\t{opacity: \"0.0\"}\n\t]);\n};\n\nexports.pop = PopStoryView;\n\n})();\n","type":"application/javascript","module-type":"storyview"},"$:/core/modules/storyviews/zoomin.js":{"title":"$:/core/modules/storyviews/zoomin.js","text":"/*\\\ntitle: $:/core/modules/storyviews/zoomin.js\ntype: application/javascript\nmodule-type: storyview\n\nZooms between individual tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar easing = \"cubic-bezier(0.645, 0.045, 0.355, 1)\"; // From http://easings.net/#easeInOutCubic\n\nvar ZoominListView = function(listWidget) {\n\tvar self = this;\n\tthis.listWidget = listWidget;\n\tthis.textNodeLogger = new $tw.utils.Logger(\"zoomin story river view\", {\n\t\tenable: true,\n\t\tcolour: 'red'\n\t});\n\t// Get the index of the tiddler that is at the top of the history\n\tvar history = this.listWidget.wiki.getTiddlerDataCached(this.listWidget.historyTitle,[]),\n\t\ttargetTiddler;\n\tif(history.length > 0) {\n\t\ttargetTiddler = history[history.length-1].title;\n\t}\n\t// Make all the tiddlers position absolute, and hide all but the top (or first) one\n\t$tw.utils.each(this.listWidget.children,function(itemWidget,index) {\n\t\tvar domNode = itemWidget.findFirstDomNode();\n\t\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\t\tif(!(domNode instanceof Element)) {\n\t\t\treturn;\n\t\t}\n\t\tif((targetTiddler && targetTiddler !== itemWidget.parseTreeNode.itemTitle) || (!targetTiddler && index)) {\n\t\t\tdomNode.style.display = \"none\";\n\t\t} else {\n\t\t\tself.currentTiddlerDomNode = domNode;\n\t\t}\n\t\t$tw.utils.addClass(domNode,\"tc-storyview-zoomin-tiddler\");\n\t});\n};\n\nZoominListView.prototype.navigateTo = function(historyInfo) {\n\tvar duration = $tw.utils.getAnimationDuration(),\n\t\tlistElementIndex = this.listWidget.findListItem(0,historyInfo.title);\n\tif(listElementIndex === undefined) {\n\t\treturn;\n\t}\n\tvar listItemWidget = this.listWidget.children[listElementIndex],\n\t\ttargetElement = listItemWidget.findFirstDomNode();\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!targetElement) {\n\t\treturn;\n\t} else if (targetElement.nodeType === Node.TEXT_NODE) {\n\t\tthis.logTextNodeRoot(targetElement);\n\t\treturn;\n\t}\n\t// Make the new tiddler be position absolute and visible so that we can measure it\n\t$tw.utils.addClass(targetElement,\"tc-storyview-zoomin-tiddler\");\n\t$tw.utils.setStyle(targetElement,[\n\t\t{display: \"block\"},\n\t\t{transformOrigin: \"0 0\"},\n\t\t{transform: \"translateX(0px) translateY(0px) scale(1)\"},\n\t\t{transition: \"none\"},\n\t\t{opacity: \"0.0\"}\n\t]);\n\t// Get the position of the source node, or use the centre of the window as the source position\n\tvar sourceBounds = historyInfo.fromPageRect || {\n\t\t\tleft: window.innerWidth/2 - 2,\n\t\t\ttop: window.innerHeight/2 - 2,\n\t\t\twidth: window.innerWidth/8,\n\t\t\theight: window.innerHeight/8\n\t\t};\n\t// Try to find the title node in the target tiddler\n\tvar titleDomNode = findTitleDomNode(listItemWidget) || listItemWidget.findFirstDomNode(),\n\t\tzoomBounds = titleDomNode.getBoundingClientRect();\n\t// Compute the transform for the target tiddler to make the title lie over the source rectange\n\tvar targetBounds = targetElement.getBoundingClientRect(),\n\t\tscale = sourceBounds.width / zoomBounds.width,\n\t\tx = sourceBounds.left - targetBounds.left - (zoomBounds.left - targetBounds.left) * scale,\n\t\ty = sourceBounds.top - targetBounds.top - (zoomBounds.top - targetBounds.top) * scale;\n\t// Transform the target tiddler to its starting position\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transform: \"translateX(\" + x + \"px) translateY(\" + y + \"px) scale(\" + scale + \")\"}\n\t]);\n\t// Force layout\n\t$tw.utils.forceLayout(targetElement);\n\t// Apply the ending transitions with a timeout to ensure that the previously applied transformations are applied first\n\tvar self = this,\n\t\tprevCurrentTiddler = this.currentTiddlerDomNode;\n\tthis.currentTiddlerDomNode = targetElement;\n\t// Transform the target tiddler to its natural size\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms \" + easing + \", opacity \" + duration + \"ms \" + easing},\n\t\t{opacity: \"1.0\"},\n\t\t{transform: \"translateX(0px) translateY(0px) scale(1)\"},\n\t\t{zIndex: \"500\"},\n\t]);\n\t// Transform the previous tiddler out of the way and then hide it\n\tif(prevCurrentTiddler && prevCurrentTiddler !== targetElement) {\n\t\tscale = zoomBounds.width / sourceBounds.width;\n\t\tx =  zoomBounds.left - targetBounds.left - (sourceBounds.left - targetBounds.left) * scale;\n\t\ty =  zoomBounds.top - targetBounds.top - (sourceBounds.top - targetBounds.top) * scale;\n\t\t$tw.utils.setStyle(prevCurrentTiddler,[\n\t\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms \" + easing + \", opacity \" + duration + \"ms \" + easing},\n\t\t\t{opacity: \"0.0\"},\n\t\t\t{transformOrigin: \"0 0\"},\n\t\t\t{transform: \"translateX(\" + x + \"px) translateY(\" + y + \"px) scale(\" + scale + \")\"},\n\t\t\t{zIndex: \"0\"}\n\t\t]);\n\t\t// Hide the tiddler when the transition has finished\n\t\tsetTimeout(function() {\n\t\t\tif(self.currentTiddlerDomNode !== prevCurrentTiddler) {\n\t\t\t\tprevCurrentTiddler.style.display = \"none\";\n\t\t\t}\n\t\t},duration);\n\t}\n\t// Scroll the target into view\n//\t$tw.pageScroller.scrollIntoView(targetElement);\n};\n\n/*\nFind the first child DOM node of a widget that has the class \"tc-title\"\n*/\nfunction findTitleDomNode(widget,targetClass) {\n\ttargetClass = targetClass || \"tc-title\";\n\tvar domNode = widget.findFirstDomNode();\n\tif(domNode && domNode.querySelector) {\n\t\treturn $tw.utils.querySelectorSafe(\".\" + targetClass,domNode);\n\t}\n\treturn null;\n}\n\nZoominListView.prototype.insert = function(widget) {\n\tvar targetElement = widget.findFirstDomNode();\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!targetElement) {\n\t\treturn;\n\t} else if (targetElement.nodeType === Node.TEXT_NODE) {\n\t\tthis.logTextNodeRoot(targetElement);\n\t\treturn;\n\t}\n\t// Make the newly inserted node position absolute and hidden\n\t$tw.utils.addClass(targetElement,\"tc-storyview-zoomin-tiddler\");\n\t$tw.utils.setStyle(targetElement,[\n\t\t{display: \"none\"}\n\t]);\n};\n\nZoominListView.prototype.remove = function(widget) {\n\tvar targetElement = widget.findFirstDomNode(),\n\t\tduration = $tw.utils.getAnimationDuration(),\n\t\tremoveElement = function() {\n\t\t\twidget.removeChildDomNodes();\n\t\t};\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!targetElement || targetElement.nodeType === Node.TEXT_NODE) {\n\t\tremoveElement();\n\t\treturn;\n\t}\n\t// Abandon if hidden\n\tif(targetElement.style.display != \"block\" ) {\n\t\tremoveElement();\n\t\treturn;\n\t}\n\t// Set up the tiddler that is being closed\n\t$tw.utils.addClass(targetElement,\"tc-storyview-zoomin-tiddler\");\n\t$tw.utils.setStyle(targetElement,[\n\t\t{display: \"block\"},\n\t\t{transformOrigin: \"50% 50%\"},\n\t\t{transform: \"translateX(0px) translateY(0px) scale(1)\"},\n\t\t{transition: \"none\"},\n\t\t{zIndex: \"0\"}\n\t]);\n\t// We'll move back to the previous or next element in the story\n\tvar toWidget = widget.previousSibling();\n\tif(!toWidget) {\n\t\ttoWidget = widget.nextSibling();\n\t}\n\tvar toWidgetDomNode = toWidget && toWidget.findFirstDomNode();\n\t// Set up the tiddler we're moving back in\n\tif(toWidgetDomNode) {\n\t\tif (toWidgetDomNode.nodeType === Node.TEXT_NODE) {\n\t\t\tthis.logTextNodeRoot(toWidgetDomNode);\n\t\t\ttoWidgetDomNode = null;\n\t\t} else {\n\t\t\t$tw.utils.addClass(toWidgetDomNode,\"tc-storyview-zoomin-tiddler\");\n\t\t\t$tw.utils.setStyle(toWidgetDomNode,[\n\t\t\t\t{display: \"block\"},\n\t\t\t\t{transformOrigin: \"50% 50%\"},\n\t\t\t\t{transform: \"translateX(0px) translateY(0px) scale(10)\"},\n\t\t\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms \" + easing + \", opacity \" + duration + \"ms \" + easing},\n\t\t\t\t{opacity: \"0\"},\n\t\t\t\t{zIndex: \"500\"}\n\t\t\t]);\n\t\t\tthis.currentTiddlerDomNode = toWidgetDomNode;\n\t\t}\n\t}\n\t// Animate them both\n\t// Force layout\n\t$tw.utils.forceLayout(this.listWidget.parentDomNode);\n\t// First, the tiddler we're closing\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transformOrigin: \"50% 50%\"},\n\t\t{transform: \"translateX(0px) translateY(0px) scale(0.1)\"},\n\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms \" + easing + \", opacity \" + duration + \"ms \" + easing},\n\t\t{opacity: \"0\"},\n\t\t{zIndex: \"0\"}\n\t]);\n\tsetTimeout(removeElement,duration);\n\t// Now the tiddler we're going back to\n\tif(toWidgetDomNode) {\n\t\t$tw.utils.setStyle(toWidgetDomNode,[\n\t\t\t{transform: \"translateX(0px) translateY(0px) scale(1)\"},\n\t\t\t{opacity: \"1\"}\n\t\t]);\n\t}\n\treturn true; // Indicate that we'll delete the DOM node\n};\n\nZoominListView.prototype.logTextNodeRoot = function(node) {\n\tthis.textNodeLogger.log($tw.language.getString(\"Error/ZoominTextNode\") + \" \" + node.textContent);\n};\n\nexports.zoomin = ZoominListView;\n\n})();\n","type":"application/javascript","module-type":"storyview"},"$:/core/modules/syncer.js":{"title":"$:/core/modules/syncer.js","text":"/*\\\ntitle: $:/core/modules/syncer.js\ntype: application/javascript\nmodule-type: global\n\nThe syncer tracks changes to the store and synchronises them to a remote data store represented as a \"sync adaptor\"\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nDefaults\n*/\nSyncer.prototype.titleIsLoggedIn = \"$:/status/IsLoggedIn\";\nSyncer.prototype.titleIsAnonymous = \"$:/status/IsAnonymous\";\nSyncer.prototype.titleIsReadOnly = \"$:/status/IsReadOnly\";\nSyncer.prototype.titleUserName = \"$:/status/UserName\";\nSyncer.prototype.titleSyncFilter = \"$:/config/SyncFilter\";\nSyncer.prototype.titleSyncPollingInterval = \"$:/config/SyncPollingInterval\";\nSyncer.prototype.titleSyncDisableLazyLoading = \"$:/config/SyncDisableLazyLoading\";\nSyncer.prototype.titleSavedNotification = \"$:/language/Notifications/Save/Done\";\nSyncer.prototype.titleSyncThrottleInterval = \"$:/config/SyncThrottleInterval\";\nSyncer.prototype.taskTimerInterval = 0.25 * 1000; // Interval for sync timer\nSyncer.prototype.throttleInterval = 1 * 1000; // Defer saving tiddlers if they've changed in the last 1s...\nSyncer.prototype.errorRetryInterval = 5 * 1000; // Interval to retry after an error\nSyncer.prototype.fallbackInterval = 10 * 1000; // Unless the task is older than 10s\nSyncer.prototype.pollTimerInterval = 60 * 1000; // Interval for polling for changes from the adaptor\n\n/*\nInstantiate the syncer with the following options:\nsyncadaptor: reference to syncadaptor to be used\nwiki: wiki to be synced\n*/\nfunction Syncer(options) {\n\tvar self = this;\n\tthis.wiki = options.wiki;\n\t// Save parameters\n\tthis.syncadaptor = options.syncadaptor;\n\tthis.disableUI = !!options.disableUI;\n\tthis.titleIsLoggedIn = options.titleIsLoggedIn || this.titleIsLoggedIn;\n\tthis.titleUserName = options.titleUserName || this.titleUserName;\n\tthis.titleSyncFilter = options.titleSyncFilter || this.titleSyncFilter;\n\tthis.titleSavedNotification = options.titleSavedNotification || this.titleSavedNotification;\n\tthis.taskTimerInterval = options.taskTimerInterval || this.taskTimerInterval;\n\tthis.throttleInterval = options.throttleInterval || parseInt(this.wiki.getTiddlerText(this.titleSyncThrottleInterval,\"\"),10) || this.throttleInterval;\n\tthis.errorRetryInterval = options.errorRetryInterval || this.errorRetryInterval;\n\tthis.fallbackInterval = options.fallbackInterval || this.fallbackInterval;\n\tthis.pollTimerInterval = options.pollTimerInterval || parseInt(this.wiki.getTiddlerText(this.titleSyncPollingInterval,\"\"),10) || this.pollTimerInterval;\n\tthis.logging = \"logging\" in options ? options.logging : true;\n\t// Make a logger\n\tthis.logger = new $tw.utils.Logger(\"syncer\" + ($tw.browser ? \"-browser\" : \"\") + ($tw.node ? \"-server\" : \"\")  + (this.syncadaptor.name ? (\"-\" + this.syncadaptor.name) : \"\"),{\n\t\tcolour: \"cyan\",\n\t\tenable: this.logging,\n\t\tsaveHistory: true\n\t});\n\t// Make another logger for connection errors\n\tthis.loggerConnection = new $tw.utils.Logger(\"syncer\" + ($tw.browser ? \"-browser\" : \"\") + ($tw.node ? \"-server\" : \"\")  + (this.syncadaptor.name ? (\"-\" + this.syncadaptor.name) : \"\") + \"-connection\",{\n\t\tcolour: \"cyan\",\n\t\tenable: this.logging\n\t});\n\t// Ask the syncadaptor to use the main logger\n\tif(this.syncadaptor.setLoggerSaveBuffer) {\n\t\tthis.syncadaptor.setLoggerSaveBuffer(this.logger);\n\t}\n\t// Compile the dirty tiddler filter\n\tthis.filterFn = this.wiki.compileFilter(this.wiki.getTiddlerText(this.titleSyncFilter));\n\t// Record information for known tiddlers\n\tthis.readTiddlerInfo();\n\tthis.titlesToBeLoaded = {}; // Hashmap of titles of tiddlers that need loading from the server\n\tthis.titlesHaveBeenLazyLoaded = {}; // Hashmap of titles of tiddlers that have already been lazily loaded from the server\n\t// Timers\n\tthis.taskTimerId = null; // Timer for task dispatch\n\t// Number of outstanding requests\n\tthis.numTasksInProgress = 0;\n\t// True when we want to force an immediate sync from the server\n\tthis.forceSyncFromServer = false;\n\tthis.timestampLastSyncFromServer = new Date();\n\t// Listen out for changes to tiddlers\n\tthis.wiki.addEventListener(\"change\",function(changes) {\n\t\t// Filter the changes to just include ones that are being synced\n\t\tvar filteredChanges = self.getSyncedTiddlers(function(callback) {\n\t\t\t$tw.utils.each(changes,function(change,title) {\n\t\t\t\tvar tiddler = self.wiki.tiddlerExists(title) && self.wiki.getTiddler(title);\n\t\t\t\tcallback(tiddler,title);\n\t\t\t});\n\t\t});\n\t\tif(filteredChanges.length > 0) {\n\t\t\tself.processTaskQueue();\n\t\t} else {\n\t\t\t// Look for deletions of tiddlers we're already syncing\t\n\t\t\tvar outstandingDeletion = false\n\t\t\t$tw.utils.each(changes,function(change,title,object) {\n\t\t\t\tif(change.deleted && $tw.utils.hop(self.tiddlerInfo,title)) {\n\t\t\t\t\toutstandingDeletion = true;\n\t\t\t\t}\n\t\t\t});\n\t\t\tif(outstandingDeletion) {\n\t\t\t\tself.processTaskQueue();\n\t\t\t}\n\t\t}\n\t});\n\t// Browser event handlers\n\tif($tw.browser && !this.disableUI) {\n\t\t// Set up our beforeunload handler\n\t\t$tw.addUnloadTask(function(event) {\n\t\t\tvar confirmationMessage;\n\t\t\tif(self.isDirty()) {\n\t\t\t\tconfirmationMessage = $tw.language.getString(\"UnsavedChangesWarning\");\n\t\t\t\tevent.returnValue = confirmationMessage; // Gecko\n\t\t\t}\n\t\t\treturn confirmationMessage;\n\t\t});\n\t\t// Listen out for login/logout/refresh events in the browser\n\t\t$tw.rootWidget.addEventListener(\"tm-login\",function(event) {\n\t\t\tvar username = event && event.paramObject && event.paramObject.username,\n\t\t\t\tpassword = event && event.paramObject && event.paramObject.password;\n\t\t\tif(username && password) {\n\t\t\t\t// Login with username and password\n\t\t\t\tself.login(username,password,function() {});\n\t\t\t} else {\n\t\t\t\t// No username and password, so we display a prompt\n\t\t\t\tself.handleLoginEvent();\t\t\t\t\n\t\t\t}\n\t\t});\n\t\t$tw.rootWidget.addEventListener(\"tm-logout\",function() {\n\t\t\tself.handleLogoutEvent();\n\t\t});\n\t\t$tw.rootWidget.addEventListener(\"tm-server-refresh\",function() {\n\t\t\tself.handleRefreshEvent();\n\t\t});\n\t\t$tw.rootWidget.addEventListener(\"tm-copy-syncer-logs-to-clipboard\",function() {\n\t\t\t$tw.utils.copyToClipboard($tw.utils.getSystemInfo() + \"\\n\\nLog:\\n\" + self.logger.getBuffer());\n\t\t});\n\t}\n\t// Listen out for lazyLoad events\n\tif(!this.disableUI && this.wiki.getTiddlerText(this.titleSyncDisableLazyLoading) !== \"yes\") {\n\t\tthis.wiki.addEventListener(\"lazyLoad\",function(title) {\n\t\t\tself.handleLazyLoadEvent(title);\n\t\t});\t\t\n\t}\n\t// Get the login status\n\tthis.getStatus(function(err,isLoggedIn) {\n\t\t// Do a sync from the server\n\t\tself.syncFromServer();\n\t});\n}\n\n/*\nShow a generic network error alert\n*/\nSyncer.prototype.displayError = function(msg,err) {\n\tif(err === ($tw.language.getString(\"Error/XMLHttpRequest\") + \": 0\")) {\n\t\tthis.loggerConnection.alert($tw.language.getString(\"Error/NetworkErrorAlert\"));\n\t\tthis.logger.log(msg + \":\",err);\n\t} else {\n\t\tthis.logger.alert(msg + \":\",err);\n\t}\n};\n\n/*\nReturn an array of the tiddler titles that are subjected to syncing\n*/\nSyncer.prototype.getSyncedTiddlers = function(source) {\n\treturn this.filterFn.call(this.wiki,source);\n};\n\n/*\nReturn an array of the tiddler titles that are subjected to syncing\n*/\nSyncer.prototype.getTiddlerRevision = function(title) {\n\tif(this.syncadaptor && this.syncadaptor.getTiddlerRevision) {\n\t\treturn this.syncadaptor.getTiddlerRevision(title);\n\t} else {\n\t\treturn this.wiki.getTiddler(title).fields.revision;\t\n\t} \n};\n\n/*\nRead (or re-read) the latest tiddler info from the store\n*/\nSyncer.prototype.readTiddlerInfo = function() {\n\t// Hashmap by title of {revision:,changeCount:,adaptorInfo:}\n\t// \"revision\" is the revision of the tiddler last seen on the server, and \"changecount\" is the corresponding local changecount\n\tthis.tiddlerInfo = {};\n\t// Record information for known tiddlers\n\tvar self = this,\n\t\ttiddlers = this.getSyncedTiddlers();\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tvar tiddler = self.wiki.getTiddler(title);\n\t\tif(tiddler) {\n\t\t\tself.tiddlerInfo[title] = {\n\t\t\t\trevision: self.getTiddlerRevision(title),\n\t\t\t\tadaptorInfo: self.syncadaptor && self.syncadaptor.getTiddlerInfo(tiddler),\n\t\t\t\tchangeCount: self.wiki.getChangeCount(title)\n\t\t\t};\n\t\t}\n\t});\n};\n\n/*\nChecks whether the wiki is dirty (ie the window shouldn't be closed)\n*/\nSyncer.prototype.isDirty = function() {\n\tvar self = this;\n\tfunction checkIsDirty() {\n\t\t// Check tiddlers that are in the store and included in the filter function\n\t\tvar titles = self.getSyncedTiddlers();\n\t\tfor(var index=0; index<titles.length; index++) {\n\t\t\tvar title = titles[index],\n\t\t\t\ttiddlerInfo = self.tiddlerInfo[title];\n\t\t\tif(self.wiki.tiddlerExists(title)) {\n\t\t\t\tif(tiddlerInfo) {\n\t\t\t\t\t// If the tiddler is known on the server and has been modified locally then it needs to be saved to the server\n\t\t\t\t\tif(self.wiki.getChangeCount(title) > tiddlerInfo.changeCount) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// If the tiddler isn't known on the server then it needs to be saved to the server\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Check tiddlers that are known from the server but not currently in the store\n\t\ttitles = Object.keys(self.tiddlerInfo);\n\t\tfor(index=0; index<titles.length; index++) {\n\t\t\tif(!self.wiki.tiddlerExists(titles[index])) {\n\t\t\t\t// There must be a pending delete\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\tvar dirtyStatus = checkIsDirty();\n\treturn dirtyStatus;\n};\n\n/*\nUpdate the document body with the class \"tc-dirty\" if the wiki has unsaved/unsynced changes\n*/\nSyncer.prototype.updateDirtyStatus = function() {\n\tif($tw.browser && !this.disableUI) {\n\t\tvar dirty = this.isDirty();\n\t\t$tw.utils.toggleClass(document.body,\"tc-dirty\",dirty);\n\t\tif(!dirty) {\n\t\t\tthis.loggerConnection.clearAlerts();\n\t\t}\n\t}\n};\n\n/*\nSave an incoming tiddler in the store, and updates the associated tiddlerInfo\n*/\nSyncer.prototype.storeTiddler = function(tiddlerFields) {\n\t// Save the tiddler\n\tvar tiddler = new $tw.Tiddler(tiddlerFields);\n\tthis.wiki.addTiddler(tiddler);\n\t// Save the tiddler revision and changeCount details\n\tthis.tiddlerInfo[tiddlerFields.title] = {\n\t\trevision: this.getTiddlerRevision(tiddlerFields.title),\n\t\tadaptorInfo: this.syncadaptor.getTiddlerInfo(tiddler),\n\t\tchangeCount: this.wiki.getChangeCount(tiddlerFields.title)\n\t};\n};\n\nSyncer.prototype.getStatus = function(callback) {\n\tvar self = this;\n\t// Check if the adaptor supports getStatus()\n\tif(this.syncadaptor && this.syncadaptor.getStatus) {\n\t\t// Mark us as not logged in\n\t\tthis.wiki.addTiddler({title: this.titleIsLoggedIn,text: \"no\"});\n\t\t// Get login status\n\t\tthis.syncadaptor.getStatus(function(err,isLoggedIn,username,isReadOnly,isAnonymous) {\n\t\t\tif(err) {\n\t\t\t\tself.displayError(\"Get Status Error\",err);\n\t\t\t} else {\n\t\t\t\t// Set the various status tiddlers\n\t\t\t\tself.wiki.addTiddler({title: self.titleIsReadOnly,text: isReadOnly ? \"yes\" : \"no\"});\n\t\t\t\tself.wiki.addTiddler({title: self.titleIsAnonymous,text: isAnonymous ? \"yes\" : \"no\"});\n\t\t\t\tself.wiki.addTiddler({title: self.titleIsLoggedIn,text: isLoggedIn ? \"yes\" : \"no\"});\n\t\t\t\tif(isLoggedIn) {\n\t\t\t\t\tself.wiki.addTiddler({title: self.titleUserName,text: username || \"\"});\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Invoke the callback\n\t\t\tif(callback) {\n\t\t\t\tcallback(err,isLoggedIn,username);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tcallback(null,true,\"UNAUTHENTICATED\");\n\t}\n};\n\n/*\nSynchronise from the server by reading the skinny tiddler list and queuing up loads for any tiddlers that we don't already have up to date\n*/\nSyncer.prototype.syncFromServer = function() {\n\tif(this.canSyncFromServer()) {\n\t\tthis.forceSyncFromServer = true;\n\t\tthis.processTaskQueue();\t\n\t}\n};\n\nSyncer.prototype.canSyncFromServer = function() {\n\treturn !!this.syncadaptor.getUpdatedTiddlers || !!this.syncadaptor.getSkinnyTiddlers;\n}\n\n/*\nForce load a tiddler from the server\n*/\nSyncer.prototype.enqueueLoadTiddler = function(title) {\n\tthis.titlesToBeLoaded[title] = true;\n\tthis.processTaskQueue();\n};\n\n/*\nLazily load a skinny tiddler if we can\n*/\nSyncer.prototype.handleLazyLoadEvent = function(title) {\n\t// Ignore if the syncadaptor doesn't handle it\n\tif(!this.syncadaptor.supportsLazyLoading) {\n\t\treturn;\n\t}\n\t// Don't lazy load the same tiddler twice\n\tif(!this.titlesHaveBeenLazyLoaded[title]) {\n\t\t// Don't lazy load if the tiddler isn't included in the sync filter\n\t\tif(this.getSyncedTiddlers().indexOf(title) !== -1) {\n\t\t\t// Mark the tiddler as needing loading, and having already been lazily loaded\n\t\t\tthis.titlesToBeLoaded[title] = true;\n\t\t\tthis.titlesHaveBeenLazyLoaded[title] = true;\n\t\t\tthis.processTaskQueue();\n\t\t}\n\t}\n};\n\n/*\nDispay a password prompt and allow the user to login\n*/\nSyncer.prototype.handleLoginEvent = function() {\n\tvar self = this;\n\tthis.getStatus(function(err,isLoggedIn,username) {\n\t\tif(!err && !isLoggedIn) {\n\t\t\tif(self.syncadaptor && self.syncadaptor.displayLoginPrompt) {\n\t\t\t\tself.syncadaptor.displayLoginPrompt(self);\n\t\t\t} else {\n\t\t\t\tself.displayLoginPrompt();\n\t\t\t}\n\t\t}\n\t});\n};\n\n/*\nDispay a password prompt\n*/\nSyncer.prototype.displayLoginPrompt = function() {\n\tvar self = this;\n\tvar promptInfo = $tw.passwordPrompt.createPrompt({\n\t\tserviceName: $tw.language.getString(\"LoginToTiddlySpace\"),\n\t\tcallback: function(data) {\n\t\t\tself.login(data.username,data.password,function(err,isLoggedIn) {\n\t\t\t\tself.syncFromServer();\n\t\t\t});\n\t\t\treturn true; // Get rid of the password prompt\n\t\t}\n\t});\n};\n\n/*\nAttempt to login to TiddlyWeb.\n\tusername: username\n\tpassword: password\n\tcallback: invoked with arguments (err,isLoggedIn)\n*/\nSyncer.prototype.login = function(username,password,callback) {\n\tthis.logger.log(\"Attempting to login as\",username);\n\tvar self = this;\n\tif(this.syncadaptor.login) {\n\t\tthis.syncadaptor.login(username,password,function(err) {\n\t\t\tif(err) {\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\tself.getStatus(function(err,isLoggedIn,username) {\n\t\t\t\tif(callback) {\n\t\t\t\t\tcallback(err,isLoggedIn);\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t} else {\n\t\tcallback(null,true);\n\t}\n};\n\n/*\nAttempt to log out of TiddlyWeb\n*/\nSyncer.prototype.handleLogoutEvent = function() {\n\tthis.logger.log(\"Attempting to logout\");\n\tvar self = this;\n\tif(this.syncadaptor.logout) {\n\t\tthis.syncadaptor.logout(function(err) {\n\t\t\tif(err) {\n\t\t\t\tself.displayError(\"Logout Error\",err);\n\t\t\t} else {\n\t\t\t\tself.getStatus();\n\t\t\t}\n\t\t});\n\t}\n};\n\n/*\nImmediately refresh from the server\n*/\nSyncer.prototype.handleRefreshEvent = function() {\n\tthis.syncFromServer();\n};\n\n/*\nProcess the next task\n*/\nSyncer.prototype.processTaskQueue = function() {\n\tvar self = this;\n\t// Only process a task if the sync adaptor is fully initialised and we're not already performing\n\t// a task. If we are already performing a task then we'll dispatch the next one when it completes\n\tif((!this.syncadaptor.isReady || this.syncadaptor.isReady()) && this.numTasksInProgress === 0) {\n\t\t// Choose the next task to perform\n\t\tvar task = this.chooseNextTask();\n\t\t// Perform the task if we had one\n\t\tif(typeof task === \"object\" && task !== null) {\n\t\t\tthis.numTasksInProgress += 1;\n\t\t\ttask.run(function(err) {\n\t\t\t\tself.numTasksInProgress -= 1;\n\t\t\t\tif(err) {\n\t\t\t\t\tself.displayError(\"Sync error while processing \" + task.type + \" of '\" + task.title + \"'\",err);\n\t\t\t\t\tself.updateDirtyStatus();\n\t\t\t\t\tself.triggerTimeout(self.errorRetryInterval);\n\t\t\t\t} else {\n\t\t\t\t\tself.updateDirtyStatus();\n\t\t\t\t\t// Process the next task\n\t\t\t\t\tself.processTaskQueue.call(self);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\t// No task is ready so update the status\n\t\t\tthis.updateDirtyStatus();\n\t\t\t// And trigger a timeout if there is a pending task\n\t\t\tif(task === true) {\n\t\t\t\tthis.triggerTimeout(this.taskTimerInterval);\n\t\t\t} else if(this.canSyncFromServer()) {\n\t\t\t\tthis.triggerTimeout(this.pollTimerInterval);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tthis.updateDirtyStatus();\n\t\tthis.triggerTimeout(this.taskTimerInterval);\n\t}\n};\n\nSyncer.prototype.triggerTimeout = function(interval) {\n\tvar self = this;\n\tif(this.taskTimerId) {\n\t\tclearTimeout(this.taskTimerId);\n\t}\n\tthis.taskTimerId = setTimeout(function() {\n\t\tself.taskTimerId = null;\n\t\tself.processTaskQueue.call(self);\n\t},interval || self.taskTimerInterval);\n};\n\n/*\nChoose the next sync task. We prioritise saves to the server, then getting updates from the server, then deletes to the server, then loads from the server\n\nReturns either:\n* a task object\n* the boolean true if there are pending sync tasks that aren't yet due\n* null if there's no pending sync tasks (just the next poll)\n*/\nSyncer.prototype.chooseNextTask = function() {\n\tvar now = new Date(),\n\t\tthresholdLastSaved = now - this.throttleInterval,\n\t\thavePending = null;\n\t// First we look for tiddlers that have been modified locally and need saving back to the server\n\tvar titles = this.getSyncedTiddlers();\n\tfor(var index=0; index<titles.length; index++) {\n\t\tvar title = titles[index],\n\t\t\ttiddler = this.wiki.tiddlerExists(title) && this.wiki.getTiddler(title),\n\t\t\ttiddlerInfo = this.tiddlerInfo[title];\n\t\tif(tiddler) {\n\t\t\t// If the tiddler is not known on the server, or has been modified locally no more recently than the threshold then it needs to be saved to the server\n\t\t\tvar hasChanged = !tiddlerInfo || this.wiki.getChangeCount(title) > tiddlerInfo.changeCount,\n\t\t\t\tisReadyToSave = !tiddlerInfo || !tiddlerInfo.timestampLastSaved || tiddlerInfo.timestampLastSaved < thresholdLastSaved;\n\t\t\tif(hasChanged) {\n\t\t\t\tif(isReadyToSave) {\n\t\t\t\t\treturn new SaveTiddlerTask(this,title);\n\t\t\t\t} else {\n\t\t\t\t\thavePending = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t// Second we check for an outstanding sync from server\n\tif(this.forceSyncFromServer || (this.timestampLastSyncFromServer && (now.valueOf() >= (this.timestampLastSyncFromServer.valueOf() + this.pollTimerInterval)))) {\n\t\treturn new SyncFromServerTask(this);\n\t}\n\t// Third, we check tiddlers that are known from the server but not currently in the store, and so need deleting on the server\n\ttitles = Object.keys(this.tiddlerInfo);\n\tfor(index=0; index<titles.length; index++) {\n\t\ttitle = titles[index];\n\t\ttiddlerInfo = this.tiddlerInfo[title];\n\t\ttiddler = this.wiki.tiddlerExists(title) && this.wiki.getTiddler(title);\n\t\tif(!tiddler) {\n\t\t\treturn new DeleteTiddlerTask(this,title);\n\t\t}\n\t}\n\t// Finally, check for tiddlers that need loading\n\ttitle = Object.keys(this.titlesToBeLoaded)[0];\n\tif(title) {\n\t\tdelete this.titlesToBeLoaded[title];\n\t\treturn new LoadTiddlerTask(this,title);\n\t}\n\t// No tasks are ready now, but might be in the future\n\treturn havePending;\n};\n\nfunction SaveTiddlerTask(syncer,title) {\n\tthis.syncer = syncer;\n\tthis.title = title;\n\tthis.type = \"save\";\n}\n\nSaveTiddlerTask.prototype.toString = function() {\n\treturn \"SAVE \" + this.title;\n}\n\nSaveTiddlerTask.prototype.run = function(callback) {\n\tvar self = this,\n\t\tchangeCount = this.syncer.wiki.getChangeCount(this.title),\n\t\ttiddler = this.syncer.wiki.tiddlerExists(this.title) && this.syncer.wiki.getTiddler(this.title);\n\tthis.syncer.logger.log(\"Dispatching 'save' task:\",this.title);\n\tif(tiddler) {\n\t\tthis.syncer.syncadaptor.saveTiddler(tiddler,function(err,adaptorInfo,revision) {\n\t\t\t// If there's an error, exit without changing any internal state\n\t\t\tif(err) {\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\t// Adjust the info stored about this tiddler\n\t\t\tself.syncer.tiddlerInfo[self.title] = {\n\t\t\t\tchangeCount: changeCount,\n\t\t\t\tadaptorInfo: adaptorInfo,\n\t\t\t\trevision: revision,\n\t\t\t\ttimestampLastSaved: new Date()\n\t\t\t};\n\t\t\t// Invoke the callback\n\t\t\tcallback(null);\n\t\t},{\n\t\t\ttiddlerInfo: self.syncer.tiddlerInfo[self.title]\n\t\t});\n\t} else {\n\t\t$tw.utils.nextTick(callback(null));\n\t}\n};\n\nfunction DeleteTiddlerTask(syncer,title) {\n\tthis.syncer = syncer;\n\tthis.title = title;\n\tthis.type = \"delete\";\n}\n\nDeleteTiddlerTask.prototype.toString = function() {\n\treturn \"DELETE \" + this.title;\n}\n\nDeleteTiddlerTask.prototype.run = function(callback) {\n\tvar self = this;\n\tthis.syncer.logger.log(\"Dispatching 'delete' task:\",this.title);\n\tthis.syncer.syncadaptor.deleteTiddler(this.title,function(err) {\n\t\t// If there's an error, exit without changing any internal state\n\t\tif(err) {\n\t\t\treturn callback(err);\n\t\t}\n\t\t// Remove the info stored about this tiddler\n\t\tdelete self.syncer.tiddlerInfo[self.title];\n\t\t// Invoke the callback\n\t\tcallback(null);\n\t},{\n\t\ttiddlerInfo: self.syncer.tiddlerInfo[this.title]\n\t});\n};\n\nfunction LoadTiddlerTask(syncer,title) {\n\tthis.syncer = syncer;\n\tthis.title = title;\n\tthis.type = \"load\";\n}\n\nLoadTiddlerTask.prototype.toString = function() {\n\treturn \"LOAD \" + this.title;\n}\n\nLoadTiddlerTask.prototype.run = function(callback) {\n\tvar self = this;\n\tthis.syncer.logger.log(\"Dispatching 'load' task:\",this.title);\n\tthis.syncer.syncadaptor.loadTiddler(this.title,function(err,tiddlerFields) {\n\t\t// If there's an error, exit without changing any internal state\n\t\tif(err) {\n\t\t\treturn callback(err);\n\t\t}\n\t\t// Update the info stored about this tiddler\n\t\tif(tiddlerFields) {\n\t\t\tself.syncer.storeTiddler(tiddlerFields);\n\t\t}\n\t\t// Invoke the callback\n\t\tcallback(null);\n\t});\n};\n\nfunction SyncFromServerTask(syncer) {\n\tthis.syncer = syncer;\n\tthis.type = \"syncfromserver\";\n}\n\nSyncFromServerTask.prototype.toString = function() {\n\treturn \"SYNCFROMSERVER\";\n}\n\nSyncFromServerTask.prototype.run = function(callback) {\n\tvar self = this;\n\tvar syncSystemFromServer = (self.syncer.wiki.getTiddlerText(\"$:/config/SyncSystemTiddlersFromServer\") === \"yes\" ? true : false);\n\tvar successCallback = function() {\n\t\tself.syncer.forceSyncFromServer = false;\n\t\tself.syncer.timestampLastSyncFromServer = new Date();\n\t\tcallback(null);\n\t};\n\tif(this.syncer.syncadaptor.getUpdatedTiddlers) {\n\t\tthis.syncer.syncadaptor.getUpdatedTiddlers(self.syncer,function(err,updates) {\n\t\t\tif(err) {\n\t\t\t\tself.syncer.displayError($tw.language.getString(\"Error/RetrievingSkinny\"),err);\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\tif(updates) {\n\t\t\t\t$tw.utils.each(updates.modifications,function(title) {\n\t\t\t\t\tself.syncer.titlesToBeLoaded[title] = true;\n\t\t\t\t});\n\t\t\t\t$tw.utils.each(updates.deletions,function(title) {\n\t\t\t\t\tif(syncSystemFromServer || !self.syncer.wiki.isSystemTiddler(title)) {\n\t\t\t\t\t\tdelete self.syncer.tiddlerInfo[title];\n\t\t\t\t\t\tself.syncer.logger.log(\"Deleting tiddler missing from server:\",title);\n\t\t\t\t\t\tself.syncer.wiki.deleteTiddler(title);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn successCallback();\n\t\t});\n\t} else if(this.syncer.syncadaptor.getSkinnyTiddlers) {\n\t\tthis.syncer.syncadaptor.getSkinnyTiddlers(function(err,tiddlers) {\n\t\t\t// Check for errors\n\t\t\tif(err) {\n\t\t\t\tself.syncer.displayError($tw.language.getString(\"Error/RetrievingSkinny\"),err);\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\t// Keep track of which tiddlers we already know about have been reported this time\n\t\t\tvar previousTitles = Object.keys(self.syncer.tiddlerInfo);\n\t\t\t// Process each incoming tiddler\n\t\t\tfor(var t=0; t<tiddlers.length; t++) {\n\t\t\t\t// Get the incoming tiddler fields, and the existing tiddler\n\t\t\t\tvar tiddlerFields = tiddlers[t],\n\t\t\t\t\tincomingRevision = tiddlerFields.revision + \"\",\n\t\t\t\t\ttiddler = self.syncer.wiki.tiddlerExists(tiddlerFields.title) && self.syncer.wiki.getTiddler(tiddlerFields.title),\n\t\t\t\t\ttiddlerInfo = self.syncer.tiddlerInfo[tiddlerFields.title],\n\t\t\t\t\tcurrRevision = tiddlerInfo ? tiddlerInfo.revision : null,\n\t\t\t\t\tindexInPreviousTitles = previousTitles.indexOf(tiddlerFields.title);\n\t\t\t\tif(indexInPreviousTitles !== -1) {\n\t\t\t\t\tpreviousTitles.splice(indexInPreviousTitles,1);\n\t\t\t\t}\n\t\t\t\t// Ignore the incoming tiddler if it's the same as the revision we've already got\n\t\t\t\tif(currRevision !== incomingRevision) {\n\t\t\t\t\t// Only load the skinny version if we don't already have a fat version of the tiddler\n\t\t\t\t\tif(!tiddler || tiddler.fields.text === undefined) {\n\t\t\t\t\t\tself.syncer.storeTiddler(tiddlerFields);\n\t\t\t\t\t}\n\t\t\t\t\t// Do a full load of this tiddler\n\t\t\t\t\tself.syncer.titlesToBeLoaded[tiddlerFields.title] = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Delete any tiddlers that were previously reported but missing this time\n\t\t\t$tw.utils.each(previousTitles,function(title) {\n\t\t\t\tif(syncSystemFromServer || !self.syncer.wiki.isSystemTiddler(title)) {\n\t\t\t\t\tdelete self.syncer.tiddlerInfo[title];\n\t\t\t\t\tself.syncer.logger.log(\"Deleting tiddler missing from server:\",title);\n\t\t\t\t\tself.syncer.wiki.deleteTiddler(title);\n\t\t\t\t}\n\t\t\t});\n\t\t\tself.syncer.forceSyncFromServer = false;\n\t\t\tself.syncer.timestampLastSyncFromServer = new Date();\n\t\t\treturn successCallback();\n\t\t});\n\t} else {\n\t\treturn successCallback();\n\t}\n};\n\nexports.Syncer = Syncer;\n\n})();\n","type":"application/javascript","module-type":"global"},"$:/core/modules/tiddler.js":{"title":"$:/core/modules/tiddler.js","text":"/*\\\ntitle: $:/core/modules/tiddler.js\ntype: application/javascript\nmodule-type: tiddlermethod\n\nExtension methods for the $tw.Tiddler object (constructor and methods required at boot time are in boot/boot.js)\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.hasTag = function(tag) {\n\treturn this.fields.tags && this.fields.tags.indexOf(tag) !== -1;\n};\n\nexports.isPlugin = function() {\n\treturn this.fields.type === \"application/json\" && this.hasField(\"plugin-type\");\n};\n\nexports.isDraft = function() {\n\treturn this.hasField(\"draft.of\");\n};\n\nexports.getFieldString = function(field,defaultValue) {\n\tvar value = this.fields[field];\n\t// Check for a missing field\n\tif(value === undefined || value === null) {\n\t\treturn defaultValue || \"\";\n\t}\n\t// Stringify the field with the associated tiddler field module (if any)\n\tvar fieldModule = $tw.Tiddler.fieldModules[field];\n\tif(fieldModule && fieldModule.stringify) {\n\t\treturn fieldModule.stringify.call(this,value);\n\t} else {\n\t\treturn value.toString();\n\t}\n};\n\n/*\nGet the value of a field as a list\n*/\nexports.getFieldList = function(field) {\n\tvar value = this.fields[field];\n\t// Check for a missing field\n\tif(value === undefined || value === null) {\n\t\treturn [];\n\t}\n\treturn $tw.utils.parseStringArray(value);\n};\n\n/*\nGet all the fields as a hashmap of strings. Options:\n\texclude: an array of field names to exclude\n*/\nexports.getFieldStrings = function(options) {\n\toptions = options || {};\n\tvar exclude = options.exclude || [];\n\tvar fields = {};\n\tfor(var field in this.fields) {\n\t\tif($tw.utils.hop(this.fields,field)) {\n\t\t\tif(exclude.indexOf(field) === -1) {\n\t\t\t\tfields[field] = this.getFieldString(field);\n\t\t\t}\n\t\t}\n\t}\n\treturn fields;\n};\n\n/*\nGet all the fields as a name:value block. Options:\n\texclude: an array of field names to exclude\n*/\nexports.getFieldStringBlock = function(options) {\n\toptions = options || {};\n\tvar exclude = options.exclude || [],\n\t\tfields = Object.keys(this.fields).sort(),\n\t\tresult = [];\n\tfor(var t=0; t<fields.length; t++) {\n\t\tvar field = fields[t];\n\t\tif(exclude.indexOf(field) === -1) {\n\t\t\tresult.push(field + \": \" + this.getFieldString(field));\n\t\t}\n\t}\n\treturn result.join(\"\\n\");\n};\n\nexports.getFieldDay = function(field) {\n\tif(this.cache && this.cache.day && $tw.utils.hop(this.cache.day,field) ) {\n\t\treturn this.cache.day[field];\n\t}\n\tvar day = \"\";\n\tif(this.fields[field]) {\n\t\tday = (new Date($tw.utils.parseDate(this.fields[field]))).setHours(0,0,0,0);\n\t}\n\tthis.cache.day = this.cache.day || {};\n\tthis.cache.day[field] = day;\n\treturn day;\n};\n\n})();\n","type":"application/javascript","module-type":"tiddlermethod"},"$:/core/modules/upgraders/plugins.js":{"title":"$:/core/modules/upgraders/plugins.js","text":"/*\\\ntitle: $:/core/modules/upgraders/plugins.js\ntype: application/javascript\nmodule-type: upgrader\n\nUpgrader module that checks that plugins are newer than any already installed version\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar UPGRADE_LIBRARY_TITLE = \"$:/UpgradeLibrary\";\n\nvar BLOCKED_PLUGINS = {\n\t\"$:/themes/tiddlywiki/stickytitles\": {\n\t\tversions: [\"*\"]\n\t},\n\t\"$:/plugins/tiddlywiki/fullscreen\": {\n\t\tversions: [\"*\"]\n\t}\n};\n\nexports.upgrade = function(wiki,titles,tiddlers) {\n\tvar self = this,\n\t\tmessages = {},\n\t\tupgradeLibrary,\n\t\tgetLibraryTiddler = function(title) {\n\t\t\tif(!upgradeLibrary) {\n\t\t\t\tupgradeLibrary = wiki.getTiddlerData(UPGRADE_LIBRARY_TITLE,{});\n\t\t\t\tupgradeLibrary.tiddlers = upgradeLibrary.tiddlers || {};\n\t\t\t}\n\t\t\treturn upgradeLibrary.tiddlers[title];\n\t\t};\n\n\t// Go through all the incoming tiddlers\n\t$tw.utils.each(titles,function(title) {\n\t\tvar incomingTiddler = tiddlers[title];\n\t\t// Check if we're dealing with a plugin\n\t\tif(incomingTiddler && incomingTiddler[\"plugin-type\"]) {\n\t\t\t// Check whether the plugin contains JS modules\n\t\t\tvar requiresReload = wiki.doesPluginInfoRequireReload($tw.utils.parseJSONSafe(incomingTiddler.text)) ? (wiki.getTiddlerText(\"$:/language/ControlPanel/Plugins/PluginWillRequireReload\") + \" \") : \"\";\n\t\t\tmessages[title] = requiresReload;\n\t\t\tif(incomingTiddler.version) {\n\t\t\t\t// Upgrade the incoming plugin if it is in the upgrade library\n\t\t\t\tvar libraryTiddler = getLibraryTiddler(title);\n\t\t\t\tif(libraryTiddler && libraryTiddler[\"plugin-type\"] && libraryTiddler.version) {\n\t\t\t\t\ttiddlers[title] = libraryTiddler;\n\t\t\t\t\tmessages[title] = requiresReload + $tw.language.getString(\"Import/Upgrader/Plugins/Upgraded\",{variables: {incoming: incomingTiddler.version, upgraded: libraryTiddler.version}});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// Suppress the incoming plugin if it is older than the currently installed one\n\t\t\t\tvar existingTiddler = wiki.getTiddler(title);\n\t\t\t\tif(existingTiddler && existingTiddler.hasField(\"plugin-type\") && existingTiddler.hasField(\"version\")) {\n\t\t\t\t\t// Reject the incoming plugin by blanking all its fields\n\t\t\t\t\tif($tw.utils.checkVersions(existingTiddler.fields.version,incomingTiddler.version)) {\n\t\t\t\t\t\ttiddlers[title] = Object.create(null);\n\t\t\t\t\t\tmessages[title] = $tw.language.getString(\"Import/Upgrader/Plugins/Suppressed/Version\",{variables: {incoming: incomingTiddler.version, existing: existingTiddler.fields.version}});\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Check whether the plugin is on the blocked list\n\t\t\tvar blockInfo = BLOCKED_PLUGINS[title];\n\t\t\tif(blockInfo) {\n\t\t\t\tif(blockInfo.versions.indexOf(\"*\") !== -1 || (incomingTiddler.version && blockInfo.versions.indexOf(incomingTiddler.version) !== -1)) {\n\t\t\t\t\ttiddlers[title] = Object.create(null);\n\t\t\t\t\tmessages[title] = $tw.language.getString(\"Import/Upgrader/Plugins/Suppressed/Incompatible\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\treturn messages;\n};\n\n})();\n","type":"application/javascript","module-type":"upgrader"},"$:/core/modules/upgraders/system.js":{"title":"$:/core/modules/upgraders/system.js","text":"/*\\\ntitle: $:/core/modules/upgraders/system.js\ntype: application/javascript\nmodule-type: upgrader\n\nUpgrader module that suppresses certain system tiddlers that shouldn't be imported\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar DONT_IMPORT_LIST = [\"$:/Import\", \"$:/build\"],\n\tUNSELECT_PREFIX_LIST = [\"$:/temp/\",\"$:/state/\",\"$:/StoryList\",\"$:/HistoryList\"],\n\tWARN_IMPORT_PREFIX_LIST = [\"$:/core/modules/\"];\n\nexports.upgrade = function(wiki,titles,tiddlers) {\n\tvar self = this,\n\t\tmessages = {},\n\t\tshowAlert = false;\n\t// Check for tiddlers on our list\n\t$tw.utils.each(titles,function(title) {\n\t\tif(DONT_IMPORT_LIST.indexOf(title) !== -1) {\n\t\t\ttiddlers[title] = Object.create(null);\n\t\t\tmessages[title] = $tw.language.getString(\"Import/Upgrader/System/Suppressed\");\n\t\t} else {\n\t\t\tfor(var t=0; t<UNSELECT_PREFIX_LIST.length; t++) {\n\t\t\t\tvar prefix = UNSELECT_PREFIX_LIST[t];\n\t\t\t\tif(title.substr(0,prefix.length) === prefix) {\n\t\t\t\t\tmessages[title] = $tw.language.getString(\"Import/Upgrader/Tiddler/Unselected\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor(var t=0; t<WARN_IMPORT_PREFIX_LIST.length; t++) {\n\t\t\t\tvar prefix = WARN_IMPORT_PREFIX_LIST[t];\n\t\t\t\tif(title.substr(0,prefix.length) === prefix && wiki.isShadowTiddler(title)) {\n\t\t\t\t\tshowAlert = true;\n\t\t\t\t\tmessages[title] = $tw.language.getString(\"Import/Upgrader/System/Warning\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\tif(showAlert) {\n\t\tvar logger = new $tw.utils.Logger(\"import\");\n\t\tlogger.alert($tw.language.getString(\"Import/Upgrader/System/Alert\"));\n\t}\n\treturn messages;\n};\n\n})();\n","type":"application/javascript","module-type":"upgrader"},"$:/core/modules/upgraders/themetweaks.js":{"title":"$:/core/modules/upgraders/themetweaks.js","text":"/*\\\ntitle: $:/core/modules/upgraders/themetweaks.js\ntype: application/javascript\nmodule-type: upgrader\n\nUpgrader module that handles the change in theme tweak storage introduced in 5.0.14-beta.\n\nPreviously, theme tweaks were stored in two data tiddlers:\n\n* $:/themes/tiddlywiki/vanilla/metrics\n* $:/themes/tiddlywiki/vanilla/settings\n\nNow, each tweak is stored in its own separate tiddler.\n\nThis upgrader copies any values from the old format to the new. The old data tiddlers are not deleted in case they have been used to store additional indexes.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar MAPPINGS = {\n\t\"$:/themes/tiddlywiki/vanilla/metrics\": {\n\t\t\"fontsize\": \"$:/themes/tiddlywiki/vanilla/metrics/fontsize\",\n\t\t\"lineheight\": \"$:/themes/tiddlywiki/vanilla/metrics/lineheight\",\n\t\t\"storyleft\": \"$:/themes/tiddlywiki/vanilla/metrics/storyleft\",\n\t\t\"storytop\": \"$:/themes/tiddlywiki/vanilla/metrics/storytop\",\n\t\t\"storyright\": \"$:/themes/tiddlywiki/vanilla/metrics/storyright\",\n\t\t\"storywidth\": \"$:/themes/tiddlywiki/vanilla/metrics/storywidth\",\n\t\t\"tiddlerwidth\": \"$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth\"\n\t},\n\t\"$:/themes/tiddlywiki/vanilla/settings\": {\n\t\t\"fontfamily\": \"$:/themes/tiddlywiki/vanilla/settings/fontfamily\"\n\t}\n};\n\nexports.upgrade = function(wiki,titles,tiddlers) {\n\tvar self = this,\n\t\tmessages = {};\n\t// Check for tiddlers on our list\n\t$tw.utils.each(titles,function(title) {\n\t\tvar mapping = MAPPINGS[title];\n\t\tif(mapping) {\n\t\t\tvar tiddler = new $tw.Tiddler(tiddlers[title]),\n\t\t\t\ttiddlerData = wiki.getTiddlerDataCached(tiddler,{});\n\t\t\tfor(var index in mapping) {\n\t\t\t\tvar mappedTitle = mapping[index];\n\t\t\t\tif(!tiddlers[mappedTitle] || tiddlers[mappedTitle].title !== mappedTitle) {\n\t\t\t\t\ttiddlers[mappedTitle] = {\n\t\t\t\t\t\ttitle: mappedTitle,\n\t\t\t\t\t\ttext: tiddlerData[index]\n\t\t\t\t\t};\n\t\t\t\t\tmessages[mappedTitle] = $tw.language.getString(\"Import/Upgrader/ThemeTweaks/Created\",{variables: {\n\t\t\t\t\t\tfrom: title + \"##\" + index\n\t\t\t\t\t}});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\treturn messages;\n};\n\n})();\n","type":"application/javascript","module-type":"upgrader"},"$:/core/modules/utils/base64-utf8/base64-utf8.module.js":{"text":"(function(){// From https://gist.github.com/Nijikokun/5192472\n//\n// UTF8 Module\n//\n// Cleaner and modularized utf-8 encoding and decoding library for javascript.\n//\n// copyright: MIT\n// author: Nijiko Yonskai, @nijikokun, nijikokun@gmail.com\n!function(r,e,o,t){void 0!==o.module&&o.module.exports?o.module.exports=e.apply(o):void 0!==o.define&&\"function\"===o.define&&o.define.amd?define(\"utf8\",[],e):o.utf8=e.apply(o)}(0,function(){return{encode:function(r){if(\"string\"!=typeof r)return r;r=r.replace(/\\r\\n/g,\"\\n\");for(var e,o=\"\",t=0;t<r.length;t++)if((e=r.charCodeAt(t))<128)o+=String.fromCharCode(e);else if(e>127&&e<2048)o+=String.fromCharCode(e>>6|192),o+=String.fromCharCode(63&e|128);else if(e>55295&&e<57344&&r.length>t+1){var i=e,n=r.charCodeAt(t+1);t++;var d=65536+(i-55296<<10|n-56320);o+=String.fromCharCode(d>>18|240),o+=String.fromCharCode(d>>12&63|128),o+=String.fromCharCode(d>>6&63|128),o+=String.fromCharCode(63&d|128)}else o+=String.fromCharCode(e>>12|224),o+=String.fromCharCode(e>>6&63|128),o+=String.fromCharCode(63&e|128);return o},decode:function(r){if(\"string\"!=typeof r)return r;for(var e=\"\",o=0,t=0;o<r.length;)if((t=r.charCodeAt(o))<128)e+=String.fromCharCode(t),o++;else if(t>191&&t<224)e+=String.fromCharCode((31&t)<<6|63&r.charCodeAt(o+1)),o+=2;else if(t>223&&t<240)e+=String.fromCharCode((15&t)<<12|(63&r.charCodeAt(o+1))<<6|63&r.charCodeAt(o+2)),o+=3;else{var i=(7&t)<<18|(63&r.charCodeAt(o+1))<<12|(63&r.charCodeAt(o+2))<<6|63&r.charCodeAt(o+3);e+=String.fromCharCode(55296+(i-65536>>10))+String.fromCharCode(56320+(i-65536&1023)),o+=4}return e}}},this),function(r,e,o,t){if(void 0!==o.module&&o.module.exports){if(t&&o.require)for(var i=0;i<t.length;i++)o[t[i]]=o.require(t[i]);o.module.exports=e.apply(o)}else void 0!==o.define&&\"function\"===o.define&&o.define.amd?define(\"base64\",t||[],e):o.base64=e.apply(o)}(0,function(r){var e=r||this.utf8,o=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\";return{encode:function(r){if(void 0===e)throw{error:\"MissingMethod\",message:\"UTF8 Module is missing.\"};if(\"string\"!=typeof r)return r;r=e.encode(r);for(var t,i,n,d,f,a,h,C=\"\",c=0;c<r.length;)d=(t=r.charCodeAt(c++))>>2,f=(3&t)<<4|(i=r.charCodeAt(c++))>>4,a=(15&i)<<2|(n=r.charCodeAt(c++))>>6,h=63&n,isNaN(i)?a=h=64:isNaN(n)&&(h=64),C+=o.charAt(d)+o.charAt(f)+o.charAt(a)+o.charAt(h);return C},decode:function(r){if(void 0===e)throw{error:\"MissingMethod\",message:\"UTF8 Module is missing.\"};if(\"string\"!=typeof r)return r;r=r.replace(/[^A-Za-z0-9\\+\\/\\=]/g,\"\");for(var t,i,n,d,f,a,h=\"\",C=0;C<r.length;)t=o.indexOf(r.charAt(C++))<<2|(d=o.indexOf(r.charAt(C++)))>>4,i=(15&d)<<4|(f=o.indexOf(r.charAt(C++)))>>2,n=(3&f)<<6|(a=o.indexOf(r.charAt(C++))),h+=String.fromCharCode(t),64!=f&&(h+=String.fromCharCode(i)),64!=a&&(h+=String.fromCharCode(n));return e.decode(h)}}},this,[\"utf8\"]);}).call(exports);","type":"application/javascript","title":"$:/core/modules/utils/base64-utf8/base64-utf8.module.js","module-type":"library"},"$:/core/modules/utils/crypto.js":{"title":"$:/core/modules/utils/crypto.js","text":"/*\\\ntitle: $:/core/modules/utils/crypto.js\ntype: application/javascript\nmodule-type: utils\n\nUtility functions related to crypto.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nLook for an encrypted store area in the text of a TiddlyWiki file\n*/\nexports.extractEncryptedStoreArea = function(text) {\n\tvar encryptedStoreAreaStartMarker = \"<pre id=\\\"encryptedStoreArea\\\" type=\\\"text/plain\\\" style=\\\"display:none;\\\">\",\n\t\tencryptedStoreAreaStart = text.indexOf(encryptedStoreAreaStartMarker);\n\tif(encryptedStoreAreaStart !== -1) {\n\t\tvar encryptedStoreAreaEnd = text.indexOf(\"</pre>\",encryptedStoreAreaStart);\n\t\tif(encryptedStoreAreaEnd !== -1) {\n\t\t\treturn $tw.utils.htmlDecode(text.substring(encryptedStoreAreaStart + encryptedStoreAreaStartMarker.length,encryptedStoreAreaEnd));\n\t\t}\n\t}\n\treturn null;\n};\n\n/*\nAttempt to extract the tiddlers from an encrypted store area using the current password. If the password is not provided then the password in the password store will be used\n*/\nexports.decryptStoreArea = function(encryptedStoreArea,password) {\n\tvar decryptedText = $tw.crypto.decrypt(encryptedStoreArea,password);\n\tif(decryptedText) {\n\t\tvar json = $tw.utils.parseJSONSafe(decryptedText),\n\t\t\ttiddlers = [];\n\t\tfor(var title in json) {\n\t\t\tif(title !== \"$:/isEncrypted\") {\n\t\t\t\ttiddlers.push(json[title]);\n\t\t\t}\n\t\t}\n\t\treturn tiddlers;\n\t} else {\n\t\treturn null;\n\t}\n};\n\n\n/*\nAttempt to extract the tiddlers from an encrypted store area using the current password. If that fails, the user is prompted for a password.\nencryptedStoreArea: text of the TiddlyWiki encrypted store area\ncallback: function(tiddlers) called with the array of decrypted tiddlers\n\nThe following configuration settings are supported:\n\n$tw.config.usePasswordVault: causes any password entered by the user to also be put into the system password vault\n*/\nexports.decryptStoreAreaInteractive = function(encryptedStoreArea,callback,options) {\n\t// Try to decrypt with the current password\n\tvar tiddlers = $tw.utils.decryptStoreArea(encryptedStoreArea);\n\tif(tiddlers) {\n\t\tcallback(tiddlers);\n\t} else {\n\t\t// Prompt for a new password and keep trying\n\t\t$tw.passwordPrompt.createPrompt({\n\t\t\tserviceName: \"Enter a password to decrypt the imported TiddlyWiki\",\n\t\t\tnoUserName: true,\n\t\t\tcanCancel: true,\n\t\t\tsubmitText: \"Decrypt\",\n\t\t\tcallback: function(data) {\n\t\t\t\t// Exit if the user cancelled\n\t\t\t\tif(!data) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\t// Attempt to decrypt the tiddlers\n\t\t\t\tvar tiddlers = $tw.utils.decryptStoreArea(encryptedStoreArea,data.password);\n\t\t\t\tif(tiddlers) {\n\t\t\t\t\tif($tw.config.usePasswordVault) {\n\t\t\t\t\t\t$tw.crypto.setPassword(data.password);\n\t\t\t\t\t}\n\t\t\t\t\tcallback(tiddlers);\n\t\t\t\t\t// Exit and remove the password prompt\n\t\t\t\t\treturn true;\n\t\t\t\t} else {\n\t\t\t\t\t// We didn't decrypt everything, so continue to prompt for password\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n};\n\n})();\n","type":"application/javascript","module-type":"utils"},"$:/core/modules/utils/csv.js":{"title":"$:/core/modules/utils/csv.js","text":"/*\\\ntitle: $:/core/modules/utils/csv.js\ntype: application/javascript\nmodule-type: utils\n\nA barebones CSV parser\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar QUOTE = '\"';\n\nvar getCellInfo = function(text, start, length, SEPARATOR) {\n\tvar isCellQuoted = text.charAt(start) === QUOTE;\n\tvar cellStart = isCellQuoted ? start + 1 : start;\n\t\n\tif (text.charAt(i) === SEPARATOR) {\n\t\treturn [cellStart, cellStart, false];\n\t}\n\t\n\tfor (var i = cellStart; i < length; i++) {\n\t\tvar cellCharacter = text.charAt(i);\n\t\tvar isEOL = cellCharacter === \"\\n\" || cellCharacter === \"\\r\";\n\t\t\n\t\tif (isEOL && !isCellQuoted) {\n\t\t\treturn [cellStart, i, false];\n\t\t\t\n\t\t} else if (cellCharacter === SEPARATOR && !isCellQuoted) {\n\t\t\treturn [cellStart, i, false];\n\t\t\t\n\t\t} else if (cellCharacter === QUOTE && isCellQuoted) {\n\t\t\tvar nextCharacter = i + 1 < length ? text.charAt(i + 1) : '';\n\t\t\tif (nextCharacter !== QUOTE) {\n\t\t\t\treturn [cellStart, i, true];\n\t\t\t} else {\n\t\t\t\ti++;\n\t\t\t}\n\t\t}\n\t}\n\t\n\treturn [cellStart, i, isCellQuoted];\n}\n\t\nexports.parseCsvString = function(text, options) {\n\tif (!text) {\n\t\treturn [];\n\t}\n\t\n\toptions = options || {};\n\tvar SEPARATOR = options.separator || \",\",\n\t\tlength = text.length,\n\t\trows = [],\n\t\tnextRow = [];\n\t\t\n\tfor (var i = 0; i < length; i++) {\n\t\tvar cellInfo = getCellInfo(text, i, length, SEPARATOR);\n\t\tvar cellText = text.substring(cellInfo[0], cellInfo[1]);\n\t\tif (cellInfo[2]) {\n\t\t\tcellText = cellText.replace(/\"\"/g, '\"');\n\t\t\tcellInfo[1]++;\n\t\t}\n\t\tnextRow.push(cellText);\n\t\t\n\t\ti = cellInfo[1];\n\t\t\n\t\tvar character = text.charAt(i);\n\t\tvar nextCharacter = i + 1 < length ? text.charAt(i + 1) : '';\n\t\t\n\t\tif (character === \"\\r\" || character === \"\\n\") {\n\t\t\t// Edge case for empty rows\n\t\t\tif (nextRow.length === 1 && nextRow[0] === '') {\n\t\t\t\tnextRow.length = 0;\n\t\t\t}\n\t\t\trows.push(nextRow);\n\t\t\tnextRow = [];\n\t\t\t\n\t\t\tif (character === \"\\r\") {\n\t\t\t\tvar nextCharacter = i + 1 < length ? text.charAt(i + 1) : '';\n\t\t\t\t\n\t\t\t\tif (nextCharacter === \"\\n\") {\n\t\t\t\t\ti++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t\n\t// Special case if last cell in last row is an empty cell\n\tif (text.charAt(length - 1) === SEPARATOR) {\n\t\tnextRow.push(\"\");\n\t}\n\t\n\trows.push(nextRow);\n\t\n\treturn rows;\n}\n\n/*\nParse a CSV string with a header row and return an array of hashmaps.\n*/\nexports.parseCsvStringWithHeader = function(text,options) {\n\tvar csv = $tw.utils.parseCsvString(text, options);\n\tvar headers = csv[0];\n\t\n\tcsv = csv.slice(1);\n\tfor (var i = 0; i < csv.length; i++) {\n\t\tvar row = csv[i];\n\t\tvar rowObject = Object.create(null);\n\n\t\tfor(var columnIndex=0; columnIndex<headers.length; columnIndex++) {\n\t\t\tvar columnName = headers[columnIndex];\n\t\t\tif (columnName) {\n\t\t\t\trowObject[columnName] = $tw.utils.trim(row[columnIndex] || \"\");\n\t\t\t}\n\t\t}\n\t\tcsv[i] = rowObject;\n\t}\n\treturn csv;\n}\n\n})();\n","type":"application/javascript","module-type":"utils"},"$:/core/modules/utils/diff-match-patch/diff_match_patch.js":{"text":"(function(){function diff_match_patch(){this.Diff_Timeout=1;this.Diff_EditCost=4;this.Match_Threshold=.5;this.Match_Distance=1E3;this.Patch_DeleteThreshold=.5;this.Patch_Margin=4;this.Match_MaxBits=32}var DIFF_DELETE=-1,DIFF_INSERT=1,DIFF_EQUAL=0;\ndiff_match_patch.prototype.diff_main=function(a,b,c,d){\"undefined\"==typeof d&&(d=0>=this.Diff_Timeout?Number.MAX_VALUE:(new Date).getTime()+1E3*this.Diff_Timeout);if(null==a||null==b)throw Error(\"Null input. (diff_main)\");if(a==b)return a?[[DIFF_EQUAL,a]]:[];\"undefined\"==typeof c&&(c=!0);var e=c,f=this.diff_commonPrefix(a,b);c=a.substring(0,f);a=a.substring(f);b=b.substring(f);f=this.diff_commonSuffix(a,b);var g=a.substring(a.length-f);a=a.substring(0,a.length-f);b=b.substring(0,b.length-f);a=this.diff_compute_(a,\nb,e,d);c&&a.unshift([DIFF_EQUAL,c]);g&&a.push([DIFF_EQUAL,g]);this.diff_cleanupMerge(a);return a};\ndiff_match_patch.prototype.diff_compute_=function(a,b,c,d){if(!a)return[[DIFF_INSERT,b]];if(!b)return[[DIFF_DELETE,a]];var e=a.length>b.length?a:b,f=a.length>b.length?b:a,g=e.indexOf(f);return-1!=g?(c=[[DIFF_INSERT,e.substring(0,g)],[DIFF_EQUAL,f],[DIFF_INSERT,e.substring(g+f.length)]],a.length>b.length&&(c[0][0]=c[2][0]=DIFF_DELETE),c):1==f.length?[[DIFF_DELETE,a],[DIFF_INSERT,b]]:(e=this.diff_halfMatch_(a,b))?(b=e[1],f=e[3],a=e[4],e=this.diff_main(e[0],e[2],c,d),c=this.diff_main(b,f,c,d),e.concat([[DIFF_EQUAL,\na]],c)):c&&100<a.length&&100<b.length?this.diff_lineMode_(a,b,d):this.diff_bisect_(a,b,d)};\ndiff_match_patch.prototype.diff_lineMode_=function(a,b,c){var d=this.diff_linesToChars_(a,b);a=d.chars1;b=d.chars2;d=d.lineArray;a=this.diff_main(a,b,!1,c);this.diff_charsToLines_(a,d);this.diff_cleanupSemantic(a);a.push([DIFF_EQUAL,\"\"]);for(var e=d=b=0,f=\"\",g=\"\";b<a.length;){switch(a[b][0]){case DIFF_INSERT:e++;g+=a[b][1];break;case DIFF_DELETE:d++;f+=a[b][1];break;case DIFF_EQUAL:if(1<=d&&1<=e){a.splice(b-d-e,d+e);b=b-d-e;d=this.diff_main(f,g,!1,c);for(e=d.length-1;0<=e;e--)a.splice(b,0,d[e]);b+=\nd.length}d=e=0;g=f=\"\"}b++}a.pop();return a};\ndiff_match_patch.prototype.diff_bisect_=function(a,b,c){for(var d=a.length,e=b.length,f=Math.ceil((d+e)/2),g=2*f,h=Array(g),l=Array(g),k=0;k<g;k++)h[k]=-1,l[k]=-1;h[f+1]=0;l[f+1]=0;k=d-e;for(var m=0!=k%2,p=0,x=0,w=0,q=0,t=0;t<f&&!((new Date).getTime()>c);t++){for(var v=-t+p;v<=t-x;v+=2){var n=f+v;var r=v==-t||v!=t&&h[n-1]<h[n+1]?h[n+1]:h[n-1]+1;for(var y=r-v;r<d&&y<e&&a.charAt(r)==b.charAt(y);)r++,y++;h[n]=r;if(r>d)x+=2;else if(y>e)p+=2;else if(m&&(n=f+k-v,0<=n&&n<g&&-1!=l[n])){var u=d-l[n];if(r>=\nu)return this.diff_bisectSplit_(a,b,r,y,c)}}for(v=-t+w;v<=t-q;v+=2){n=f+v;u=v==-t||v!=t&&l[n-1]<l[n+1]?l[n+1]:l[n-1]+1;for(r=u-v;u<d&&r<e&&a.charAt(d-u-1)==b.charAt(e-r-1);)u++,r++;l[n]=u;if(u>d)q+=2;else if(r>e)w+=2;else if(!m&&(n=f+k-v,0<=n&&n<g&&-1!=h[n]&&(r=h[n],y=f+r-n,u=d-u,r>=u)))return this.diff_bisectSplit_(a,b,r,y,c)}}return[[DIFF_DELETE,a],[DIFF_INSERT,b]]};\ndiff_match_patch.prototype.diff_bisectSplit_=function(a,b,c,d,e){var f=a.substring(0,c),g=b.substring(0,d);a=a.substring(c);b=b.substring(d);f=this.diff_main(f,g,!1,e);e=this.diff_main(a,b,!1,e);return f.concat(e)};\ndiff_match_patch.prototype.diff_linesToChars_=function(a,b){function c(a){for(var b=\"\",c=0,f=-1,g=d.length;f<a.length-1;){f=a.indexOf(\"\\n\",c);-1==f&&(f=a.length-1);var h=a.substring(c,f+1);c=f+1;(e.hasOwnProperty?e.hasOwnProperty(h):void 0!==e[h])?b+=String.fromCharCode(e[h]):(b+=String.fromCharCode(g),e[h]=g,d[g++]=h)}return b}var d=[],e={};d[0]=\"\";var f=c(a),g=c(b);return{chars1:f,chars2:g,lineArray:d}};\ndiff_match_patch.prototype.diff_charsToLines_=function(a,b){for(var c=0;c<a.length;c++){for(var d=a[c][1],e=[],f=0;f<d.length;f++)e[f]=b[d.charCodeAt(f)];a[c][1]=e.join(\"\")}};diff_match_patch.prototype.diff_commonPrefix=function(a,b){if(!a||!b||a.charAt(0)!=b.charAt(0))return 0;for(var c=0,d=Math.min(a.length,b.length),e=d,f=0;c<e;)a.substring(f,e)==b.substring(f,e)?f=c=e:d=e,e=Math.floor((d-c)/2+c);return e};\ndiff_match_patch.prototype.diff_commonSuffix=function(a,b){if(!a||!b||a.charAt(a.length-1)!=b.charAt(b.length-1))return 0;for(var c=0,d=Math.min(a.length,b.length),e=d,f=0;c<e;)a.substring(a.length-e,a.length-f)==b.substring(b.length-e,b.length-f)?f=c=e:d=e,e=Math.floor((d-c)/2+c);return e};\ndiff_match_patch.prototype.diff_commonOverlap_=function(a,b){var c=a.length,d=b.length;if(0==c||0==d)return 0;c>d?a=a.substring(c-d):c<d&&(b=b.substring(0,c));c=Math.min(c,d);if(a==b)return c;d=0;for(var e=1;;){var f=a.substring(c-e);f=b.indexOf(f);if(-1==f)return d;e+=f;if(0==f||a.substring(c-e)==b.substring(0,e))d=e,e++}};\ndiff_match_patch.prototype.diff_halfMatch_=function(a,b){function c(a,b,c){for(var d=a.substring(c,c+Math.floor(a.length/4)),e=-1,g=\"\",h,k,l,m;-1!=(e=b.indexOf(d,e+1));){var p=f.diff_commonPrefix(a.substring(c),b.substring(e)),u=f.diff_commonSuffix(a.substring(0,c),b.substring(0,e));g.length<u+p&&(g=b.substring(e-u,e)+b.substring(e,e+p),h=a.substring(0,c-u),k=a.substring(c+p),l=b.substring(0,e-u),m=b.substring(e+p))}return 2*g.length>=a.length?[h,k,l,m,g]:null}if(0>=this.Diff_Timeout)return null;\nvar d=a.length>b.length?a:b,e=a.length>b.length?b:a;if(4>d.length||2*e.length<d.length)return null;var f=this,g=c(d,e,Math.ceil(d.length/4));d=c(d,e,Math.ceil(d.length/2));if(g||d)g=d?g?g[4].length>d[4].length?g:d:d:g;else return null;if(a.length>b.length){d=g[0];e=g[1];var h=g[2];var l=g[3]}else h=g[0],l=g[1],d=g[2],e=g[3];return[d,e,h,l,g[4]]};\ndiff_match_patch.prototype.diff_cleanupSemantic=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=0,h=0,l=0,k=0;f<a.length;)a[f][0]==DIFF_EQUAL?(c[d++]=f,g=l,h=k,k=l=0,e=a[f][1]):(a[f][0]==DIFF_INSERT?l+=a[f][1].length:k+=a[f][1].length,e&&e.length<=Math.max(g,h)&&e.length<=Math.max(l,k)&&(a.splice(c[d-1],0,[DIFF_DELETE,e]),a[c[d-1]+1][0]=DIFF_INSERT,d--,d--,f=0<d?c[d-1]:-1,k=l=h=g=0,e=null,b=!0)),f++;b&&this.diff_cleanupMerge(a);this.diff_cleanupSemanticLossless(a);for(f=1;f<a.length;){if(a[f-1][0]==\nDIFF_DELETE&&a[f][0]==DIFF_INSERT){b=a[f-1][1];c=a[f][1];d=this.diff_commonOverlap_(b,c);e=this.diff_commonOverlap_(c,b);if(d>=e){if(d>=b.length/2||d>=c.length/2)a.splice(f,0,[DIFF_EQUAL,c.substring(0,d)]),a[f-1][1]=b.substring(0,b.length-d),a[f+1][1]=c.substring(d),f++}else if(e>=b.length/2||e>=c.length/2)a.splice(f,0,[DIFF_EQUAL,b.substring(0,e)]),a[f-1][0]=DIFF_INSERT,a[f-1][1]=c.substring(0,c.length-e),a[f+1][0]=DIFF_DELETE,a[f+1][1]=b.substring(e),f++;f++}f++}};\ndiff_match_patch.prototype.diff_cleanupSemanticLossless=function(a){function b(a,b){if(!a||!b)return 6;var c=a.charAt(a.length-1),d=b.charAt(0),e=c.match(diff_match_patch.nonAlphaNumericRegex_),f=d.match(diff_match_patch.nonAlphaNumericRegex_),g=e&&c.match(diff_match_patch.whitespaceRegex_),h=f&&d.match(diff_match_patch.whitespaceRegex_);c=g&&c.match(diff_match_patch.linebreakRegex_);d=h&&d.match(diff_match_patch.linebreakRegex_);var k=c&&a.match(diff_match_patch.blanklineEndRegex_),l=d&&b.match(diff_match_patch.blanklineStartRegex_);\nreturn k||l?5:c||d?4:e&&!g&&h?3:g||h?2:e||f?1:0}for(var c=1;c<a.length-1;){if(a[c-1][0]==DIFF_EQUAL&&a[c+1][0]==DIFF_EQUAL){var d=a[c-1][1],e=a[c][1],f=a[c+1][1],g=this.diff_commonSuffix(d,e);if(g){var h=e.substring(e.length-g);d=d.substring(0,d.length-g);e=h+e.substring(0,e.length-g);f=h+f}g=d;h=e;for(var l=f,k=b(d,e)+b(e,f);e.charAt(0)===f.charAt(0);){d+=e.charAt(0);e=e.substring(1)+f.charAt(0);f=f.substring(1);var m=b(d,e)+b(e,f);m>=k&&(k=m,g=d,h=e,l=f)}a[c-1][1]!=g&&(g?a[c-1][1]=g:(a.splice(c-\n1,1),c--),a[c][1]=h,l?a[c+1][1]=l:(a.splice(c+1,1),c--))}c++}};diff_match_patch.nonAlphaNumericRegex_=/[^a-zA-Z0-9]/;diff_match_patch.whitespaceRegex_=/\\s/;diff_match_patch.linebreakRegex_=/[\\r\\n]/;diff_match_patch.blanklineEndRegex_=/\\n\\r?\\n$/;diff_match_patch.blanklineStartRegex_=/^\\r?\\n\\r?\\n/;\ndiff_match_patch.prototype.diff_cleanupEfficiency=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=!1,h=!1,l=!1,k=!1;f<a.length;)a[f][0]==DIFF_EQUAL?(a[f][1].length<this.Diff_EditCost&&(l||k)?(c[d++]=f,g=l,h=k,e=a[f][1]):(d=0,e=null),l=k=!1):(a[f][0]==DIFF_DELETE?k=!0:l=!0,e&&(g&&h&&l&&k||e.length<this.Diff_EditCost/2&&3==g+h+l+k)&&(a.splice(c[d-1],0,[DIFF_DELETE,e]),a[c[d-1]+1][0]=DIFF_INSERT,d--,e=null,g&&h?(l=k=!0,d=0):(d--,f=0<d?c[d-1]:-1,l=k=!1),b=!0)),f++;b&&this.diff_cleanupMerge(a)};\ndiff_match_patch.prototype.diff_cleanupMerge=function(a){a.push([DIFF_EQUAL,\"\"]);for(var b=0,c=0,d=0,e=\"\",f=\"\",g;b<a.length;)switch(a[b][0]){case DIFF_INSERT:d++;f+=a[b][1];b++;break;case DIFF_DELETE:c++;e+=a[b][1];b++;break;case DIFF_EQUAL:1<c+d?(0!==c&&0!==d&&(g=this.diff_commonPrefix(f,e),0!==g&&(0<b-c-d&&a[b-c-d-1][0]==DIFF_EQUAL?a[b-c-d-1][1]+=f.substring(0,g):(a.splice(0,0,[DIFF_EQUAL,f.substring(0,g)]),b++),f=f.substring(g),e=e.substring(g)),g=this.diff_commonSuffix(f,e),0!==g&&(a[b][1]=f.substring(f.length-\ng)+a[b][1],f=f.substring(0,f.length-g),e=e.substring(0,e.length-g))),0===c?a.splice(b-d,c+d,[DIFF_INSERT,f]):0===d?a.splice(b-c,c+d,[DIFF_DELETE,e]):a.splice(b-c-d,c+d,[DIFF_DELETE,e],[DIFF_INSERT,f]),b=b-c-d+(c?1:0)+(d?1:0)+1):0!==b&&a[b-1][0]==DIFF_EQUAL?(a[b-1][1]+=a[b][1],a.splice(b,1)):b++,c=d=0,f=e=\"\"}\"\"===a[a.length-1][1]&&a.pop();c=!1;for(b=1;b<a.length-1;)a[b-1][0]==DIFF_EQUAL&&a[b+1][0]==DIFF_EQUAL&&(a[b][1].substring(a[b][1].length-a[b-1][1].length)==a[b-1][1]?(a[b][1]=a[b-1][1]+a[b][1].substring(0,\na[b][1].length-a[b-1][1].length),a[b+1][1]=a[b-1][1]+a[b+1][1],a.splice(b-1,1),c=!0):a[b][1].substring(0,a[b+1][1].length)==a[b+1][1]&&(a[b-1][1]+=a[b+1][1],a[b][1]=a[b][1].substring(a[b+1][1].length)+a[b+1][1],a.splice(b+1,1),c=!0)),b++;c&&this.diff_cleanupMerge(a)};\ndiff_match_patch.prototype.diff_xIndex=function(a,b){var c=0,d=0,e=0,f=0,g;for(g=0;g<a.length;g++){a[g][0]!==DIFF_INSERT&&(c+=a[g][1].length);a[g][0]!==DIFF_DELETE&&(d+=a[g][1].length);if(c>b)break;e=c;f=d}return a.length!=g&&a[g][0]===DIFF_DELETE?f:f+(b-e)};\ndiff_match_patch.prototype.diff_prettyHtml=function(a){for(var b=[],c=/&/g,d=/</g,e=/>/g,f=/\\n/g,g=0;g<a.length;g++){var h=a[g][0],l=a[g][1].replace(c,\"&amp;\").replace(d,\"&lt;\").replace(e,\"&gt;\").replace(f,\"&para;<br>\");switch(h){case DIFF_INSERT:b[g]='<ins style=\"background:#e6ffe6;\">'+l+\"</ins>\";break;case DIFF_DELETE:b[g]='<del style=\"background:#ffe6e6;\">'+l+\"</del>\";break;case DIFF_EQUAL:b[g]=\"<span>\"+l+\"</span>\"}}return b.join(\"\")};\ndiff_match_patch.prototype.diff_text1=function(a){for(var b=[],c=0;c<a.length;c++)a[c][0]!==DIFF_INSERT&&(b[c]=a[c][1]);return b.join(\"\")};diff_match_patch.prototype.diff_text2=function(a){for(var b=[],c=0;c<a.length;c++)a[c][0]!==DIFF_DELETE&&(b[c]=a[c][1]);return b.join(\"\")};\ndiff_match_patch.prototype.diff_levenshtein=function(a){for(var b=0,c=0,d=0,e=0;e<a.length;e++){var f=a[e][1];switch(a[e][0]){case DIFF_INSERT:c+=f.length;break;case DIFF_DELETE:d+=f.length;break;case DIFF_EQUAL:b+=Math.max(c,d),d=c=0}}return b+=Math.max(c,d)};\ndiff_match_patch.prototype.diff_toDelta=function(a){for(var b=[],c=0;c<a.length;c++)switch(a[c][0]){case DIFF_INSERT:b[c]=\"+\"+encodeURI(a[c][1]);break;case DIFF_DELETE:b[c]=\"-\"+a[c][1].length;break;case DIFF_EQUAL:b[c]=\"=\"+a[c][1].length}return b.join(\"\\t\").replace(/%20/g,\" \")};\ndiff_match_patch.prototype.diff_fromDelta=function(a,b){for(var c=[],d=0,e=0,f=b.split(/\\t/g),g=0;g<f.length;g++){var h=f[g].substring(1);switch(f[g].charAt(0)){case \"+\":try{c[d++]=[DIFF_INSERT,decodeURI(h)]}catch(k){throw Error(\"Illegal escape in diff_fromDelta: \"+h);}break;case \"-\":case \"=\":var l=parseInt(h,10);if(isNaN(l)||0>l)throw Error(\"Invalid number in diff_fromDelta: \"+h);h=a.substring(e,e+=l);\"=\"==f[g].charAt(0)?c[d++]=[DIFF_EQUAL,h]:c[d++]=[DIFF_DELETE,h];break;default:if(f[g])throw Error(\"Invalid diff operation in diff_fromDelta: \"+\nf[g]);}}if(e!=a.length)throw Error(\"Delta length (\"+e+\") does not equal source text length (\"+a.length+\").\");return c};diff_match_patch.prototype.match_main=function(a,b,c){if(null==a||null==b||null==c)throw Error(\"Null input. (match_main)\");c=Math.max(0,Math.min(c,a.length));return a==b?0:a.length?a.substring(c,c+b.length)==b?c:this.match_bitap_(a,b,c):-1};\ndiff_match_patch.prototype.match_bitap_=function(a,b,c){function d(a,d){var e=a/b.length,g=Math.abs(c-d);return f.Match_Distance?e+g/f.Match_Distance:g?1:e}if(b.length>this.Match_MaxBits)throw Error(\"Pattern too long for this browser.\");var e=this.match_alphabet_(b),f=this,g=this.Match_Threshold,h=a.indexOf(b,c);-1!=h&&(g=Math.min(d(0,h),g),h=a.lastIndexOf(b,c+b.length),-1!=h&&(g=Math.min(d(0,h),g)));var l=1<<b.length-1;h=-1;for(var k,m,p=b.length+a.length,x,w=0;w<b.length;w++){k=0;for(m=p;k<m;)d(w,\nc+m)<=g?k=m:p=m,m=Math.floor((p-k)/2+k);p=m;k=Math.max(1,c-m+1);var q=Math.min(c+m,a.length)+b.length;m=Array(q+2);for(m[q+1]=(1<<w)-1;q>=k;q--){var t=e[a.charAt(q-1)];m[q]=0===w?(m[q+1]<<1|1)&t:(m[q+1]<<1|1)&t|(x[q+1]|x[q])<<1|1|x[q+1];if(m[q]&l&&(t=d(w,q-1),t<=g))if(g=t,h=q-1,h>c)k=Math.max(1,2*c-h);else break}if(d(w+1,c)>g)break;x=m}return h};\ndiff_match_patch.prototype.match_alphabet_=function(a){for(var b={},c=0;c<a.length;c++)b[a.charAt(c)]=0;for(c=0;c<a.length;c++)b[a.charAt(c)]|=1<<a.length-c-1;return b};\ndiff_match_patch.prototype.patch_addContext_=function(a,b){if(0!=b.length){for(var c=b.substring(a.start2,a.start2+a.length1),d=0;b.indexOf(c)!=b.lastIndexOf(c)&&c.length<this.Match_MaxBits-this.Patch_Margin-this.Patch_Margin;)d+=this.Patch_Margin,c=b.substring(a.start2-d,a.start2+a.length1+d);d+=this.Patch_Margin;(c=b.substring(a.start2-d,a.start2))&&a.diffs.unshift([DIFF_EQUAL,c]);(d=b.substring(a.start2+a.length1,a.start2+a.length1+d))&&a.diffs.push([DIFF_EQUAL,d]);a.start1-=c.length;a.start2-=\nc.length;a.length1+=c.length+d.length;a.length2+=c.length+d.length}};\ndiff_match_patch.prototype.patch_make=function(a,b,c){if(\"string\"==typeof a&&\"string\"==typeof b&&\"undefined\"==typeof c){var d=a;b=this.diff_main(d,b,!0);2<b.length&&(this.diff_cleanupSemantic(b),this.diff_cleanupEfficiency(b))}else if(a&&\"object\"==typeof a&&\"undefined\"==typeof b&&\"undefined\"==typeof c)b=a,d=this.diff_text1(b);else if(\"string\"==typeof a&&b&&\"object\"==typeof b&&\"undefined\"==typeof c)d=a;else if(\"string\"==typeof a&&\"string\"==typeof b&&c&&\"object\"==typeof c)d=a,b=c;else throw Error(\"Unknown call format to patch_make.\");\nif(0===b.length)return[];c=[];a=new diff_match_patch.patch_obj;for(var e=0,f=0,g=0,h=d,l=0;l<b.length;l++){var k=b[l][0],m=b[l][1];e||k===DIFF_EQUAL||(a.start1=f,a.start2=g);switch(k){case DIFF_INSERT:a.diffs[e++]=b[l];a.length2+=m.length;d=d.substring(0,g)+m+d.substring(g);break;case DIFF_DELETE:a.length1+=m.length;a.diffs[e++]=b[l];d=d.substring(0,g)+d.substring(g+m.length);break;case DIFF_EQUAL:m.length<=2*this.Patch_Margin&&e&&b.length!=l+1?(a.diffs[e++]=b[l],a.length1+=m.length,a.length2+=m.length):\nm.length>=2*this.Patch_Margin&&e&&(this.patch_addContext_(a,h),c.push(a),a=new diff_match_patch.patch_obj,e=0,h=d,f=g)}k!==DIFF_INSERT&&(f+=m.length);k!==DIFF_DELETE&&(g+=m.length)}e&&(this.patch_addContext_(a,h),c.push(a));return c};\ndiff_match_patch.prototype.patch_deepCopy=function(a){for(var b=[],c=0;c<a.length;c++){var d=a[c],e=new diff_match_patch.patch_obj;e.diffs=[];for(var f=0;f<d.diffs.length;f++)e.diffs[f]=d.diffs[f].slice();e.start1=d.start1;e.start2=d.start2;e.length1=d.length1;e.length2=d.length2;b[c]=e}return b};\ndiff_match_patch.prototype.patch_apply=function(a,b){if(0==a.length)return[b,[]];a=this.patch_deepCopy(a);var c=this.patch_addPadding(a);b=c+b+c;this.patch_splitMax(a);for(var d=0,e=[],f=0;f<a.length;f++){var g=a[f].start2+d,h=this.diff_text1(a[f].diffs),l=-1;if(h.length>this.Match_MaxBits){var k=this.match_main(b,h.substring(0,this.Match_MaxBits),g);-1!=k&&(l=this.match_main(b,h.substring(h.length-this.Match_MaxBits),g+h.length-this.Match_MaxBits),-1==l||k>=l)&&(k=-1)}else k=this.match_main(b,h,\ng);if(-1==k)e[f]=!1,d-=a[f].length2-a[f].length1;else if(e[f]=!0,d=k-g,g=-1==l?b.substring(k,k+h.length):b.substring(k,l+this.Match_MaxBits),h==g)b=b.substring(0,k)+this.diff_text2(a[f].diffs)+b.substring(k+h.length);else if(g=this.diff_main(h,g,!1),h.length>this.Match_MaxBits&&this.diff_levenshtein(g)/h.length>this.Patch_DeleteThreshold)e[f]=!1;else{this.diff_cleanupSemanticLossless(g);h=0;var m;for(l=0;l<a[f].diffs.length;l++){var p=a[f].diffs[l];p[0]!==DIFF_EQUAL&&(m=this.diff_xIndex(g,h));p[0]===\nDIFF_INSERT?b=b.substring(0,k+m)+p[1]+b.substring(k+m):p[0]===DIFF_DELETE&&(b=b.substring(0,k+m)+b.substring(k+this.diff_xIndex(g,h+p[1].length)));p[0]!==DIFF_DELETE&&(h+=p[1].length)}}}b=b.substring(c.length,b.length-c.length);return[b,e]};\ndiff_match_patch.prototype.patch_addPadding=function(a){for(var b=this.Patch_Margin,c=\"\",d=1;d<=b;d++)c+=String.fromCharCode(d);for(d=0;d<a.length;d++)a[d].start1+=b,a[d].start2+=b;d=a[0];var e=d.diffs;if(0==e.length||e[0][0]!=DIFF_EQUAL)e.unshift([DIFF_EQUAL,c]),d.start1-=b,d.start2-=b,d.length1+=b,d.length2+=b;else if(b>e[0][1].length){var f=b-e[0][1].length;e[0][1]=c.substring(e[0][1].length)+e[0][1];d.start1-=f;d.start2-=f;d.length1+=f;d.length2+=f}d=a[a.length-1];e=d.diffs;0==e.length||e[e.length-\n1][0]!=DIFF_EQUAL?(e.push([DIFF_EQUAL,c]),d.length1+=b,d.length2+=b):b>e[e.length-1][1].length&&(f=b-e[e.length-1][1].length,e[e.length-1][1]+=c.substring(0,f),d.length1+=f,d.length2+=f);return c};\ndiff_match_patch.prototype.patch_splitMax=function(a){for(var b=this.Match_MaxBits,c=0;c<a.length;c++)if(!(a[c].length1<=b)){var d=a[c];a.splice(c--,1);for(var e=d.start1,f=d.start2,g=\"\";0!==d.diffs.length;){var h=new diff_match_patch.patch_obj,l=!0;h.start1=e-g.length;h.start2=f-g.length;\"\"!==g&&(h.length1=h.length2=g.length,h.diffs.push([DIFF_EQUAL,g]));for(;0!==d.diffs.length&&h.length1<b-this.Patch_Margin;){g=d.diffs[0][0];var k=d.diffs[0][1];g===DIFF_INSERT?(h.length2+=k.length,f+=k.length,h.diffs.push(d.diffs.shift()),\nl=!1):g===DIFF_DELETE&&1==h.diffs.length&&h.diffs[0][0]==DIFF_EQUAL&&k.length>2*b?(h.length1+=k.length,e+=k.length,l=!1,h.diffs.push([g,k]),d.diffs.shift()):(k=k.substring(0,b-h.length1-this.Patch_Margin),h.length1+=k.length,e+=k.length,g===DIFF_EQUAL?(h.length2+=k.length,f+=k.length):l=!1,h.diffs.push([g,k]),k==d.diffs[0][1]?d.diffs.shift():d.diffs[0][1]=d.diffs[0][1].substring(k.length))}g=this.diff_text2(h.diffs);g=g.substring(g.length-this.Patch_Margin);k=this.diff_text1(d.diffs).substring(0,\nthis.Patch_Margin);\"\"!==k&&(h.length1+=k.length,h.length2+=k.length,0!==h.diffs.length&&h.diffs[h.diffs.length-1][0]===DIFF_EQUAL?h.diffs[h.diffs.length-1][1]+=k:h.diffs.push([DIFF_EQUAL,k]));l||a.splice(++c,0,h)}}};diff_match_patch.prototype.patch_toText=function(a){for(var b=[],c=0;c<a.length;c++)b[c]=a[c];return b.join(\"\")};\ndiff_match_patch.prototype.patch_fromText=function(a){var b=[];if(!a)return b;a=a.split(\"\\n\");for(var c=0,d=/^@@ -(\\d+),?(\\d*) \\+(\\d+),?(\\d*) @@$/;c<a.length;){var e=a[c].match(d);if(!e)throw Error(\"Invalid patch string: \"+a[c]);var f=new diff_match_patch.patch_obj;b.push(f);f.start1=parseInt(e[1],10);\"\"===e[2]?(f.start1--,f.length1=1):\"0\"==e[2]?f.length1=0:(f.start1--,f.length1=parseInt(e[2],10));f.start2=parseInt(e[3],10);\"\"===e[4]?(f.start2--,f.length2=1):\"0\"==e[4]?f.length2=0:(f.start2--,f.length2=\nparseInt(e[4],10));for(c++;c<a.length;){e=a[c].charAt(0);try{var g=decodeURI(a[c].substring(1))}catch(h){throw Error(\"Illegal escape in patch_fromText: \"+g);}if(\"-\"==e)f.diffs.push([DIFF_DELETE,g]);else if(\"+\"==e)f.diffs.push([DIFF_INSERT,g]);else if(\" \"==e)f.diffs.push([DIFF_EQUAL,g]);else if(\"@\"==e)break;else if(\"\"!==e)throw Error('Invalid patch mode \"'+e+'\" in: '+g);c++}}return b};diff_match_patch.patch_obj=function(){this.diffs=[];this.start2=this.start1=null;this.length2=this.length1=0};\ndiff_match_patch.patch_obj.prototype.toString=function(){for(var a=[\"@@ -\"+(0===this.length1?this.start1+\",0\":1==this.length1?this.start1+1:this.start1+1+\",\"+this.length1)+\" +\"+(0===this.length2?this.start2+\",0\":1==this.length2?this.start2+1:this.start2+1+\",\"+this.length2)+\" @@\\n\"],b,c=0;c<this.diffs.length;c++){switch(this.diffs[c][0]){case DIFF_INSERT:b=\"+\";break;case DIFF_DELETE:b=\"-\";break;case DIFF_EQUAL:b=\" \"}a[c+1]=b+encodeURI(this.diffs[c][1])+\"\\n\"}return a.join(\"\").replace(/%20/g,\" \")};\nthis.diff_match_patch=diff_match_patch;this.DIFF_DELETE=DIFF_DELETE;this.DIFF_INSERT=DIFF_INSERT;this.DIFF_EQUAL=DIFF_EQUAL;\n}).call(exports);","type":"application/javascript","title":"$:/core/modules/utils/diff-match-patch/diff_match_patch.js","module-type":"library"},"$:/core/modules/utils/dom/animations/slide.js":{"title":"$:/core/modules/utils/dom/animations/slide.js","text":"/*\\\ntitle: $:/core/modules/utils/dom/animations/slide.js\ntype: application/javascript\nmodule-type: animation\n\nA simple slide animation that varies the height of the element\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nfunction slideOpen(domNode,options) {\n\toptions = options || {};\n\tvar duration = options.duration || $tw.utils.getAnimationDuration();\n\t// Get the current height of the domNode\n\tvar computedStyle = window.getComputedStyle(domNode),\n\t\tcurrMarginBottom = parseInt(computedStyle.marginBottom,10),\n\t\tcurrMarginTop = parseInt(computedStyle.marginTop,10),\n\t\tcurrPaddingBottom = parseInt(computedStyle.paddingBottom,10),\n\t\tcurrPaddingTop = parseInt(computedStyle.paddingTop,10),\n\t\tcurrHeight = domNode.offsetHeight;\n\t// Reset the margin once the transition is over\n\tsetTimeout(function() {\n\t\t$tw.utils.setStyle(domNode,[\n\t\t\t{transition: \"none\"},\n\t\t\t{marginBottom: \"\"},\n\t\t\t{marginTop: \"\"},\n\t\t\t{paddingBottom: \"\"},\n\t\t\t{paddingTop: \"\"},\n\t\t\t{height: \"auto\"},\n\t\t\t{opacity: \"\"}\n\t\t]);\n\t\tif(options.callback) {\n\t\t\toptions.callback();\n\t\t}\n\t},duration);\n\t// Set up the initial position of the element\n\t$tw.utils.setStyle(domNode,[\n\t\t{transition: \"none\"},\n\t\t{marginTop: \"0px\"},\n\t\t{marginBottom: \"0px\"},\n\t\t{paddingTop: \"0px\"},\n\t\t{paddingBottom: \"0px\"},\n\t\t{height: \"0px\"},\n\t\t{opacity: \"0\"}\n\t]);\n\t$tw.utils.forceLayout(domNode);\n\t// Transition to the final position\n\t$tw.utils.setStyle(domNode,[\n\t\t{transition: \"margin-top \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"margin-bottom \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"padding-top \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"padding-bottom \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"height \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"opacity \" + duration + \"ms ease-in-out\"},\n\t\t{marginBottom: currMarginBottom + \"px\"},\n\t\t{marginTop: currMarginTop + \"px\"},\n\t\t{paddingBottom: currPaddingBottom + \"px\"},\n\t\t{paddingTop: currPaddingTop + \"px\"},\n\t\t{height: currHeight + \"px\"},\n\t\t{opacity: \"1\"}\n\t]);\n}\n\nfunction slideClosed(domNode,options) {\n\toptions = options || {};\n\tvar duration = options.duration || $tw.utils.getAnimationDuration(),\n\t\tcurrHeight = domNode.offsetHeight;\n\t// Clear the properties we've set when the animation is over\n\tsetTimeout(function() {\n\t\t$tw.utils.setStyle(domNode,[\n\t\t\t{transition: \"none\"},\n\t\t\t{marginBottom: \"\"},\n\t\t\t{marginTop: \"\"},\n\t\t\t{paddingBottom: \"\"},\n\t\t\t{paddingTop: \"\"},\n\t\t\t{height: \"auto\"},\n\t\t\t{opacity: \"\"}\n\t\t]);\n\t\tif(options.callback) {\n\t\t\toptions.callback();\n\t\t}\n\t},duration);\n\t// Set up the initial position of the element\n\t$tw.utils.setStyle(domNode,[\n\t\t{height: currHeight + \"px\"},\n\t\t{opacity: \"1\"}\n\t]);\n\t$tw.utils.forceLayout(domNode);\n\t// Transition to the final position\n\t$tw.utils.setStyle(domNode,[\n\t\t{transition: \"margin-top \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"margin-bottom \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"padding-top \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"padding-bottom \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"height \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"opacity \" + duration + \"ms ease-in-out\"},\n\t\t{marginTop: \"0px\"},\n\t\t{marginBottom: \"0px\"},\n\t\t{paddingTop: \"0px\"},\n\t\t{paddingBottom: \"0px\"},\n\t\t{height: \"0px\"},\n\t\t{opacity: \"0\"}\n\t]);\n}\n\nexports.slide = {\n\topen: slideOpen,\n\tclose: slideClosed\n};\n\n})();\n","type":"application/javascript","module-type":"animation"},"$:/core/modules/utils/dom/animator.js":{"title":"$:/core/modules/utils/dom/animator.js","text":"/*\\\ntitle: $:/core/modules/utils/dom/animator.js\ntype: application/javascript\nmodule-type: utils\n\nOrchestrates animations and transitions\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nfunction Animator() {\n\t// Get the registered animation modules\n\tthis.animations = {};\n\t$tw.modules.applyMethods(\"animation\",this.animations);\n}\n\nAnimator.prototype.perform = function(type,domNode,options) {\n\toptions = options || {};\n\t// Find an animation that can handle this type\n\tvar chosenAnimation;\n\t$tw.utils.each(this.animations,function(animation,name) {\n\t\tif($tw.utils.hop(animation,type)) {\n\t\t\tchosenAnimation = animation[type];\n\t\t}\n\t});\n\tif(!chosenAnimation) {\n\t\tchosenAnimation = function(domNode,options) {\n\t\t\tif(options.callback) {\n\t\t\t\toptions.callback();\n\t\t\t}\n\t\t};\n\t}\n\t// Call the animation\n\tchosenAnimation(domNode,options);\n};\n\nexports.Animator = Animator;\n\n})();\n","type":"application/javascript","module-type":"utils"},"$:/core/modules/utils/dom/browser.js":{"title":"$:/core/modules/utils/dom/browser.js","text":"/*\\\ntitle: $:/core/modules/utils/dom/browser.js\ntype: application/javascript\nmodule-type: utils\n\nBrowser feature detection\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSet style properties of an element\n\telement: dom node\n\tstyles: ordered array of {name: value} pairs\n*/\nexports.setStyle = function(element,styles) {\n\tif(element.nodeType === 1) { // Element.ELEMENT_NODE\n\t\tfor(var t=0; t<styles.length; t++) {\n\t\t\tfor(var styleName in styles[t]) {\n\t\t\t\telement.style[$tw.utils.convertStyleNameToPropertyName(styleName)] = styles[t][styleName];\n\t\t\t}\n\t\t}\n\t}\n};\n\n/*\nConverts a standard CSS property name into the local browser-specific equivalent. For example:\n\t\"background-color\" --> \"backgroundColor\"\n\t\"transition\" --> \"webkitTransition\"\n*/\n\nvar styleNameCache = {}; // We'll cache the style name conversions\n\nexports.convertStyleNameToPropertyName = function(styleName) {\n\t// Return from the cache if we can\n\tif(styleNameCache[styleName]) {\n\t\treturn styleNameCache[styleName];\n\t}\n\t// Convert it by first removing any hyphens\n\tvar propertyName = $tw.utils.unHyphenateCss(styleName);\n\t// Then check if it needs a prefix\n\tif($tw.browser && document.body.style[propertyName] === undefined) {\n\t\tvar prefixes = [\"O\",\"MS\",\"Moz\",\"webkit\"];\n\t\tfor(var t=0; t<prefixes.length; t++) {\n\t\t\tvar prefixedName = prefixes[t] + propertyName.substr(0,1).toUpperCase() + propertyName.substr(1);\n\t\t\tif(document.body.style[prefixedName] !== undefined) {\n\t\t\t\tpropertyName = prefixedName;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\t// Put it in the cache too\n\tstyleNameCache[styleName] = propertyName;\n\treturn propertyName;\n};\n\n/*\nConverts a JS format CSS property name back into the dashed form used in CSS declarations. For example:\n\t\"backgroundColor\" --> \"background-color\"\n\t\"webkitTransform\" --> \"-webkit-transform\"\n*/\nexports.convertPropertyNameToStyleName = function(propertyName) {\n\t// Rehyphenate the name\n\tvar styleName = $tw.utils.hyphenateCss(propertyName);\n\t// If there's a webkit prefix, add a dash (other browsers have uppercase prefixes, and so get the dash automatically)\n\tif(styleName.indexOf(\"webkit\") === 0) {\n\t\tstyleName = \"-\" + styleName;\n\t} else if(styleName.indexOf(\"-m-s\") === 0) {\n\t\tstyleName = \"-ms\" + styleName.substr(4);\n\t}\n\treturn styleName;\n};\n\n/*\nRound trip a stylename to a property name and back again. For example:\n\t\"transform\" --> \"webkitTransform\" --> \"-webkit-transform\"\n*/\nexports.roundTripPropertyName = function(propertyName) {\n\treturn $tw.utils.convertPropertyNameToStyleName($tw.utils.convertStyleNameToPropertyName(propertyName));\n};\n\n/*\nConverts a standard event name into the local browser specific equivalent. For example:\n\t\"animationEnd\" --> \"webkitAnimationEnd\"\n*/\n\nvar eventNameCache = {}; // We'll cache the conversions\n\nvar eventNameMappings = {\n\t\"transitionEnd\": {\n\t\tcorrespondingCssProperty: \"transition\",\n\t\tmappings: {\n\t\t\ttransition: \"transitionend\",\n\t\t\tOTransition: \"oTransitionEnd\",\n\t\t\tMSTransition: \"msTransitionEnd\",\n\t\t\tMozTransition: \"transitionend\",\n\t\t\twebkitTransition: \"webkitTransitionEnd\"\n\t\t}\n\t},\n\t\"animationEnd\": {\n\t\tcorrespondingCssProperty: \"animation\",\n\t\tmappings: {\n\t\t\tanimation: \"animationend\",\n\t\t\tOAnimation: \"oAnimationEnd\",\n\t\t\tMSAnimation: \"msAnimationEnd\",\n\t\t\tMozAnimation: \"animationend\",\n\t\t\twebkitAnimation: \"webkitAnimationEnd\"\n\t\t}\n\t}\n};\n\nexports.convertEventName = function(eventName) {\n\tif(eventNameCache[eventName]) {\n\t\treturn eventNameCache[eventName];\n\t}\n\tvar newEventName = eventName,\n\t\tmappings = eventNameMappings[eventName];\n\tif(mappings) {\n\t\tvar convertedProperty = $tw.utils.convertStyleNameToPropertyName(mappings.correspondingCssProperty);\n\t\tif(mappings.mappings[convertedProperty]) {\n\t\t\tnewEventName = mappings.mappings[convertedProperty];\n\t\t}\n\t}\n\t// Put it in the cache too\n\teventNameCache[eventName] = newEventName;\n\treturn newEventName;\n};\n\n/*\nReturn the names of the fullscreen APIs\n*/\nexports.getFullScreenApis = function() {\n\tvar d = document,\n\t\tdb = d.body,\n\t\tresult = {\n\t\t\"_requestFullscreen\": db.webkitRequestFullscreen !== undefined ? \"webkitRequestFullscreen\" :\n\t\t\t\t\t\t\tdb.mozRequestFullScreen !== undefined ? \"mozRequestFullScreen\" :\n\t\t\t\t\t\t\tdb.msRequestFullscreen !== undefined ? \"msRequestFullscreen\" :\n\t\t\t\t\t\t\tdb.requestFullscreen !== undefined ? \"requestFullscreen\" : \"\",\n\t\t\"_exitFullscreen\": d.webkitExitFullscreen !== undefined ? \"webkitExitFullscreen\" :\n\t\t\t\t\t\t\td.mozCancelFullScreen !== undefined ? \"mozCancelFullScreen\" :\n\t\t\t\t\t\t\td.msExitFullscreen !== undefined ? \"msExitFullscreen\" :\n\t\t\t\t\t\t\td.exitFullscreen !== undefined ? \"exitFullscreen\" : \"\",\n\t\t\"_fullscreenElement\": d.webkitFullscreenElement !== undefined ? \"webkitFullscreenElement\" :\n\t\t\t\t\t\t\td.mozFullScreenElement !== undefined ? \"mozFullScreenElement\" :\n\t\t\t\t\t\t\td.msFullscreenElement !== undefined ? \"msFullscreenElement\" :\n\t\t\t\t\t\t\td.fullscreenElement !== undefined ? \"fullscreenElement\" : \"\",\n\t\t\"_fullscreenChange\": d.webkitFullscreenElement !== undefined ? \"webkitfullscreenchange\" :\n\t\t\t\t\t\t\td.mozFullScreenElement !== undefined ? \"mozfullscreenchange\" :\n\t\t\t\t\t\t\td.msFullscreenElement !== undefined ? \"MSFullscreenChange\" :\n\t\t\t\t\t\t\td.fullscreenElement !== undefined ? \"fullscreenchange\" : \"\"\n\t};\n\tif(!result._requestFullscreen || !result._exitFullscreen || !result._fullscreenElement || !result._fullscreenChange) {\n\t\treturn null;\n\t} else {\n\t\treturn result;\n\t}\n};\n\n})();\n","type":"application/javascript","module-type":"utils"},"$:/core/modules/utils/dom/csscolorparser.js":{"title":"$:/core/modules/utils/dom/csscolorparser.js","text":"// (c) Dean McNamee <dean@gmail.com>, 2012.\n//\n// https://github.com/deanm/css-color-parser-js\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal in the Software without restriction, including without limitation the\n// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n// sell copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n// IN THE SOFTWARE.\n\n// http://www.w3.org/TR/css3-color/\nvar kCSSColorTable = {\n  \"transparent\": [0,0,0,0], \"aliceblue\": [240,248,255,1],\n  \"antiquewhite\": [250,235,215,1], \"aqua\": [0,255,255,1],\n  \"aquamarine\": [127,255,212,1], \"azure\": [240,255,255,1],\n  \"beige\": [245,245,220,1], \"bisque\": [255,228,196,1],\n  \"black\": [0,0,0,1], \"blanchedalmond\": [255,235,205,1],\n  \"blue\": [0,0,255,1], \"blueviolet\": [138,43,226,1],\n  \"brown\": [165,42,42,1], \"burlywood\": [222,184,135,1],\n  \"cadetblue\": [95,158,160,1], \"chartreuse\": [127,255,0,1],\n  \"chocolate\": [210,105,30,1], \"coral\": [255,127,80,1],\n  \"cornflowerblue\": [100,149,237,1], \"cornsilk\": [255,248,220,1],\n  \"crimson\": [220,20,60,1], \"cyan\": [0,255,255,1],\n  \"darkblue\": [0,0,139,1], \"darkcyan\": [0,139,139,1],\n  \"darkgoldenrod\": [184,134,11,1], \"darkgray\": [169,169,169,1],\n  \"darkgreen\": [0,100,0,1], \"darkgrey\": [169,169,169,1],\n  \"darkkhaki\": [189,183,107,1], \"darkmagenta\": [139,0,139,1],\n  \"darkolivegreen\": [85,107,47,1], \"darkorange\": [255,140,0,1],\n  \"darkorchid\": [153,50,204,1], \"darkred\": [139,0,0,1],\n  \"darksalmon\": [233,150,122,1], \"darkseagreen\": [143,188,143,1],\n  \"darkslateblue\": [72,61,139,1], \"darkslategray\": [47,79,79,1],\n  \"darkslategrey\": [47,79,79,1], \"darkturquoise\": [0,206,209,1],\n  \"darkviolet\": [148,0,211,1], \"deeppink\": [255,20,147,1],\n  \"deepskyblue\": [0,191,255,1], \"dimgray\": [105,105,105,1],\n  \"dimgrey\": [105,105,105,1], \"dodgerblue\": [30,144,255,1],\n  \"firebrick\": [178,34,34,1], \"floralwhite\": [255,250,240,1],\n  \"forestgreen\": [34,139,34,1], \"fuchsia\": [255,0,255,1],\n  \"gainsboro\": [220,220,220,1], \"ghostwhite\": [248,248,255,1],\n  \"gold\": [255,215,0,1], \"goldenrod\": [218,165,32,1],\n  \"gray\": [128,128,128,1], \"green\": [0,128,0,1],\n  \"greenyellow\": [173,255,47,1], \"grey\": [128,128,128,1],\n  \"honeydew\": [240,255,240,1], \"hotpink\": [255,105,180,1],\n  \"indianred\": [205,92,92,1], \"indigo\": [75,0,130,1],\n  \"ivory\": [255,255,240,1], \"khaki\": [240,230,140,1],\n  \"lavender\": [230,230,250,1], \"lavenderblush\": [255,240,245,1],\n  \"lawngreen\": [124,252,0,1], \"lemonchiffon\": [255,250,205,1],\n  \"lightblue\": [173,216,230,1], \"lightcoral\": [240,128,128,1],\n  \"lightcyan\": [224,255,255,1], \"lightgoldenrodyellow\": [250,250,210,1],\n  \"lightgray\": [211,211,211,1], \"lightgreen\": [144,238,144,1],\n  \"lightgrey\": [211,211,211,1], \"lightpink\": [255,182,193,1],\n  \"lightsalmon\": [255,160,122,1], \"lightseagreen\": [32,178,170,1],\n  \"lightskyblue\": [135,206,250,1], \"lightslategray\": [119,136,153,1],\n  \"lightslategrey\": [119,136,153,1], \"lightsteelblue\": [176,196,222,1],\n  \"lightyellow\": [255,255,224,1], \"lime\": [0,255,0,1],\n  \"limegreen\": [50,205,50,1], \"linen\": [250,240,230,1],\n  \"magenta\": [255,0,255,1], \"maroon\": [128,0,0,1],\n  \"mediumaquamarine\": [102,205,170,1], \"mediumblue\": [0,0,205,1],\n  \"mediumorchid\": [186,85,211,1], \"mediumpurple\": [147,112,219,1],\n  \"mediumseagreen\": [60,179,113,1], \"mediumslateblue\": [123,104,238,1],\n  \"mediumspringgreen\": [0,250,154,1], \"mediumturquoise\": [72,209,204,1],\n  \"mediumvioletred\": [199,21,133,1], \"midnightblue\": [25,25,112,1],\n  \"mintcream\": [245,255,250,1], \"mistyrose\": [255,228,225,1],\n  \"moccasin\": [255,228,181,1], \"navajowhite\": [255,222,173,1],\n  \"navy\": [0,0,128,1], \"oldlace\": [253,245,230,1],\n  \"olive\": [128,128,0,1], \"olivedrab\": [107,142,35,1],\n  \"orange\": [255,165,0,1], \"orangered\": [255,69,0,1],\n  \"orchid\": [218,112,214,1], \"palegoldenrod\": [238,232,170,1],\n  \"palegreen\": [152,251,152,1], \"paleturquoise\": [175,238,238,1],\n  \"palevioletred\": [219,112,147,1], \"papayawhip\": [255,239,213,1],\n  \"peachpuff\": [255,218,185,1], \"peru\": [205,133,63,1],\n  \"pink\": [255,192,203,1], \"plum\": [221,160,221,1],\n  \"powderblue\": [176,224,230,1], \"purple\": [128,0,128,1],\n  \"red\": [255,0,0,1], \"rosybrown\": [188,143,143,1],\n  \"royalblue\": [65,105,225,1], \"saddlebrown\": [139,69,19,1],\n  \"salmon\": [250,128,114,1], \"sandybrown\": [244,164,96,1],\n  \"seagreen\": [46,139,87,1], \"seashell\": [255,245,238,1],\n  \"sienna\": [160,82,45,1], \"silver\": [192,192,192,1],\n  \"skyblue\": [135,206,235,1], \"slateblue\": [106,90,205,1],\n  \"slategray\": [112,128,144,1], \"slategrey\": [112,128,144,1],\n  \"snow\": [255,250,250,1], \"springgreen\": [0,255,127,1],\n  \"steelblue\": [70,130,180,1], \"tan\": [210,180,140,1],\n  \"teal\": [0,128,128,1], \"thistle\": [216,191,216,1],\n  \"tomato\": [255,99,71,1], \"turquoise\": [64,224,208,1],\n  \"violet\": [238,130,238,1], \"wheat\": [245,222,179,1],\n  \"white\": [255,255,255,1], \"whitesmoke\": [245,245,245,1],\n  \"yellow\": [255,255,0,1], \"yellowgreen\": [154,205,50,1]}\n\nfunction clamp_css_byte(i) {  // Clamp to integer 0 .. 255.\n  i = Math.round(i);  // Seems to be what Chrome does (vs truncation).\n  return i < 0 ? 0 : i > 255 ? 255 : i;\n}\n\nfunction clamp_css_float(f) {  // Clamp to float 0.0 .. 1.0.\n  return f < 0 ? 0 : f > 1 ? 1 : f;\n}\n\nfunction parse_css_int(str) {  // int or percentage.\n  if (str[str.length - 1] === '%')\n    return clamp_css_byte(parseFloat(str) / 100 * 255);\n  return clamp_css_byte(parseInt(str));\n}\n\nfunction parse_css_float(str) {  // float or percentage.\n  if (str[str.length - 1] === '%')\n    return clamp_css_float(parseFloat(str) / 100);\n  return clamp_css_float(parseFloat(str));\n}\n\nfunction css_hue_to_rgb(m1, m2, h) {\n  if (h < 0) h += 1;\n  else if (h > 1) h -= 1;\n\n  if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;\n  if (h * 2 < 1) return m2;\n  if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;\n  return m1;\n}\n\nfunction parseCSSColor(css_str) {\n  // Remove all whitespace, not compliant, but should just be more accepting.\n  var str = css_str.replace(/ /g, '').toLowerCase();\n\n  // Color keywords (and transparent) lookup.\n  if (str in kCSSColorTable) return kCSSColorTable[str].slice();  // dup.\n\n  // #abc and #abc123 syntax.\n  if (str[0] === '#') {\n    if (str.length === 4) {\n      var iv = parseInt(str.substr(1), 16);  // TODO(deanm): Stricter parsing.\n      if (!(iv >= 0 && iv <= 0xfff)) return null;  // Covers NaN.\n      return [((iv & 0xf00) >> 4) | ((iv & 0xf00) >> 8),\n              (iv & 0xf0) | ((iv & 0xf0) >> 4),\n              (iv & 0xf) | ((iv & 0xf) << 4),\n              1];\n    } else if (str.length === 7) {\n      var iv = parseInt(str.substr(1), 16);  // TODO(deanm): Stricter parsing.\n      if (!(iv >= 0 && iv <= 0xffffff)) return null;  // Covers NaN.\n      return [(iv & 0xff0000) >> 16,\n              (iv & 0xff00) >> 8,\n              iv & 0xff,\n              1];\n    }\n\n    return null;\n  }\n\n  var op = str.indexOf('('), ep = str.indexOf(')');\n  if (op !== -1 && ep + 1 === str.length) {\n    var fname = str.substr(0, op);\n    var params = str.substr(op+1, ep-(op+1)).split(',');\n    var alpha = 1;  // To allow case fallthrough.\n    switch (fname) {\n      case 'rgba':\n        if (params.length !== 4) return null;\n        alpha = parse_css_float(params.pop());\n        // Fall through.\n      case 'rgb':\n        if (params.length !== 3) return null;\n        return [parse_css_int(params[0]),\n                parse_css_int(params[1]),\n                parse_css_int(params[2]),\n                alpha];\n      case 'hsla':\n        if (params.length !== 4) return null;\n        alpha = parse_css_float(params.pop());\n        // Fall through.\n      case 'hsl':\n        if (params.length !== 3) return null;\n        var h = (((parseFloat(params[0]) % 360) + 360) % 360) / 360;  // 0 .. 1\n        // NOTE(deanm): According to the CSS spec s/l should only be\n        // percentages, but we don't bother and let float or percentage.\n        var s = parse_css_float(params[1]);\n        var l = parse_css_float(params[2]);\n        var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;\n        var m1 = l * 2 - m2;\n        return [clamp_css_byte(css_hue_to_rgb(m1, m2, h+1/3) * 255),\n                clamp_css_byte(css_hue_to_rgb(m1, m2, h) * 255),\n                clamp_css_byte(css_hue_to_rgb(m1, m2, h-1/3) * 255),\n                alpha];\n      default:\n        return null;\n    }\n  }\n\n  return null;\n}\n\ntry { exports.parseCSSColor = parseCSSColor } catch(e) { }\n","type":"application/javascript","module-type":"utils"},"$:/core/modules/utils/dom.js":{"title":"$:/core/modules/utils/dom.js","text":"/*\\\ntitle: $:/core/modules/utils/dom.js\ntype: application/javascript\nmodule-type: utils\n\nVarious static DOM-related utility functions.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Popup = require(\"$:/core/modules/utils/dom/popup.js\");\n\n/*\nDetermines whether element 'a' contains element 'b'\nCode thanks to John Resig, http://ejohn.org/blog/comparing-document-position/\n*/\nexports.domContains = function(a,b) {\n\treturn a.contains ?\n\t\ta !== b && a.contains(b) :\n\t\t!!(a.compareDocumentPosition(b) & 16);\n};\n\nexports.domMatchesSelector = function(node,selector) {\n\treturn node.matches ? node.matches(selector) : node.msMatchesSelector(selector);\n};\n\n/*\nSelect text in a an input or textarea (setSelectionRange crashes on certain input types)\n*/\nexports.setSelectionRangeSafe = function(node,start,end,direction) {\n\ttry {\n\t\tnode.setSelectionRange(start,end,direction);\n\t} catch(e) {\n\t\tnode.select();\n\t}\n};\n\n/*\nSelect the text in an input or textarea by position\n*/\nexports.setSelectionByPosition = function(node,selectFromStart,selectFromEnd) {\n\t$tw.utils.setSelectionRangeSafe(node,selectFromStart,node.value.length - selectFromEnd);\n};\n\nexports.removeChildren = function(node) {\n\twhile(node.hasChildNodes()) {\n\t\tnode.removeChild(node.firstChild);\n\t}\n};\n\nexports.hasClass = function(el,className) {\n\treturn el && el.hasAttribute && el.hasAttribute(\"class\") && el.getAttribute(\"class\").split(\" \").indexOf(className) !== -1;\n};\n\nexports.addClass = function(el,className) {\n\tvar c = (el.getAttribute(\"class\") || \"\").split(\" \");\n\tif(c.indexOf(className) === -1) {\n\t\tc.push(className);\n\t\tel.setAttribute(\"class\",c.join(\" \"));\n\t}\n};\n\nexports.removeClass = function(el,className) {\n\tvar c = (el.getAttribute(\"class\") || \"\").split(\" \"),\n\t\tp = c.indexOf(className);\n\tif(p !== -1) {\n\t\tc.splice(p,1);\n\t\tel.setAttribute(\"class\",c.join(\" \"));\n\t}\n};\n\nexports.toggleClass = function(el,className,status) {\n\tif(status === undefined) {\n\t\tstatus = !exports.hasClass(el,className);\n\t}\n\tif(status) {\n\t\texports.addClass(el,className);\n\t} else {\n\t\texports.removeClass(el,className);\n\t}\n};\n\n/*\nGet the first parent element that has scrollbars or use the body as fallback.\n*/\nexports.getScrollContainer = function(el) {\n\tvar doc = el.ownerDocument;\n\twhile(el.parentNode) {\n\t\tel = el.parentNode;\n\t\tif(el.scrollTop) {\n\t\t\treturn el;\n\t\t}\n\t}\n\treturn doc.body;\n};\n\n/*\nGet the scroll position of the viewport\nReturns:\n\t{\n\t\tx: horizontal scroll position in pixels,\n\t\ty: vertical scroll position in pixels\n\t}\n*/\nexports.getScrollPosition = function(srcWindow) {\n\tvar scrollWindow = srcWindow || window;\n\tif(\"scrollX\" in scrollWindow) {\n\t\treturn {x: scrollWindow.scrollX, y: scrollWindow.scrollY};\n\t} else {\n\t\treturn {x: scrollWindow.document.documentElement.scrollLeft, y: scrollWindow.document.documentElement.scrollTop};\n\t}\n};\n\n/*\nAdjust the height of a textarea to fit its content, preserving scroll position, and return the height\n*/\nexports.resizeTextAreaToFit = function(domNode,minHeight) {\n\t// Get the scroll container and register the current scroll position\n\tvar container = $tw.utils.getScrollContainer(domNode),\n\t\tscrollTop = container.scrollTop;\n    // Measure the specified minimum height\n\tdomNode.style.height = minHeight;\n\tvar measuredHeight = domNode.offsetHeight || parseInt(minHeight,10);\n\t// Set its height to auto so that it snaps to the correct height\n\tdomNode.style.height = \"auto\";\n\t// Calculate the revised height\n\tvar newHeight = Math.max(domNode.scrollHeight + domNode.offsetHeight - domNode.clientHeight,measuredHeight);\n\t// Only try to change the height if it has changed\n\tif(newHeight !== domNode.offsetHeight) {\n\t\tdomNode.style.height = newHeight + \"px\";\n\t\t// Make sure that the dimensions of the textarea are recalculated\n\t\t$tw.utils.forceLayout(domNode);\n\t\t// Set the container to the position we registered at the beginning\n\t\tcontainer.scrollTop = scrollTop;\n\t}\n\treturn newHeight;\n};\n\n/*\nGets the bounding rectangle of an element in absolute page coordinates\n*/\nexports.getBoundingPageRect = function(element) {\n\tvar scrollPos = $tw.utils.getScrollPosition(element.ownerDocument.defaultView),\n\t\tclientRect = element.getBoundingClientRect();\n\treturn {\n\t\tleft: clientRect.left + scrollPos.x,\n\t\twidth: clientRect.width,\n\t\tright: clientRect.right + scrollPos.x,\n\t\ttop: clientRect.top + scrollPos.y,\n\t\theight: clientRect.height,\n\t\tbottom: clientRect.bottom + scrollPos.y\n\t};\n};\n\n/*\nSaves a named password in the browser\n*/\nexports.savePassword = function(name,password) {\n\tvar done = false;\n\ttry {\n\t\twindow.localStorage.setItem(\"tw5-password-\" + name,password);\n\t\tdone = true;\n\t} catch(e) {\n\t}\n\tif(!done) {\n\t\t$tw.savedPasswords = $tw.savedPasswords || Object.create(null);\n\t\t$tw.savedPasswords[name] = password;\n\t}\n};\n\n/*\nRetrieve a named password from the browser\n*/\nexports.getPassword = function(name) {\n\tvar value;\n\ttry {\n\t\tvalue = window.localStorage.getItem(\"tw5-password-\" + name);\n\t} catch(e) {\n\t}\n\tif(value !== undefined) {\n\t\treturn value;\n\t} else {\n\t\treturn ($tw.savedPasswords || Object.create(null))[name] || \"\";\n\t}\n};\n\n/*\nForce layout of a dom node and its descendents\n*/\nexports.forceLayout = function(element) {\n\tvar dummy = element.offsetWidth;\n};\n\n/*\nPulse an element for debugging purposes\n*/\nexports.pulseElement = function(element) {\n\t// Event handler to remove the class at the end\n\telement.addEventListener($tw.browser.animationEnd,function handler(event) {\n\t\telement.removeEventListener($tw.browser.animationEnd,handler,false);\n\t\t$tw.utils.removeClass(element,\"pulse\");\n\t},false);\n\t// Apply the pulse class\n\t$tw.utils.removeClass(element,\"pulse\");\n\t$tw.utils.forceLayout(element);\n\t$tw.utils.addClass(element,\"pulse\");\n};\n\n/*\nAttach specified event handlers to a DOM node\ndomNode: where to attach the event handlers\nevents: array of event handlers to be added (see below)\nEach entry in the events array is an object with these properties:\nhandlerFunction: optional event handler function\nhandlerObject: optional event handler object\nhandlerMethod: optionally specifies object handler method name (defaults to `handleEvent`)\n*/\nexports.addEventListeners = function(domNode,events) {\n\t$tw.utils.each(events,function(eventInfo) {\n\t\tvar handler;\n\t\tif(eventInfo.handlerFunction) {\n\t\t\thandler = eventInfo.handlerFunction;\n\t\t} else if(eventInfo.handlerObject) {\n\t\t\tif(eventInfo.handlerMethod) {\n\t\t\t\thandler = function(event) {\n\t\t\t\t\teventInfo.handlerObject[eventInfo.handlerMethod].call(eventInfo.handlerObject,event);\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\thandler = eventInfo.handlerObject;\n\t\t\t}\n\t\t}\n\t\tdomNode.addEventListener(eventInfo.name,handler,false);\n\t});\n};\n\n/*\nGet the computed styles applied to an element as an array of strings of individual CSS properties\n*/\nexports.getComputedStyles = function(domNode) {\n\tvar textAreaStyles = window.getComputedStyle(domNode,null),\n\t\tstyleDefs = [],\n\t\tname;\n\tfor(var t=0; t<textAreaStyles.length; t++) {\n\t\tname = textAreaStyles[t];\n\t\tstyleDefs.push(name + \": \" + textAreaStyles.getPropertyValue(name) + \";\");\n\t}\n\treturn styleDefs;\n};\n\n/*\nApply a set of styles passed as an array of strings of individual CSS properties\n*/\nexports.setStyles = function(domNode,styleDefs) {\n\tdomNode.style.cssText = styleDefs.join(\"\");\n};\n\n/*\nCopy the computed styles from a source element to a destination element\n*/\nexports.copyStyles = function(srcDomNode,dstDomNode) {\n\t$tw.utils.setStyles(dstDomNode,$tw.utils.getComputedStyles(srcDomNode));\n};\n\n/*\nCopy plain text to the clipboard on browsers that support it\n*/\nexports.copyToClipboard = function(text,options) {\n\toptions = options || {};\n\ttext = text || \"\";\n\tvar textArea = document.createElement(\"textarea\");\n\ttextArea.style.position = \"fixed\";\n\ttextArea.style.top = 0;\n\ttextArea.style.left = 0;\n\ttextArea.style.fontSize = \"12pt\";\n\ttextArea.style.width = \"2em\";\n\ttextArea.style.height = \"2em\";\n\ttextArea.style.padding = 0;\n\ttextArea.style.border = \"none\";\n\ttextArea.style.outline = \"none\";\n\ttextArea.style.boxShadow = \"none\";\n\ttextArea.style.background = \"transparent\";\n\ttextArea.value = text;\n\tdocument.body.appendChild(textArea);\n\ttextArea.select();\n\ttextArea.setSelectionRange(0,text.length);\n\tvar succeeded = false;\n\ttry {\n\t\tsucceeded = document.execCommand(\"copy\");\n\t} catch(err) {\n\t}\n\tif(!options.doNotNotify) {\n\t\tvar successNotification = options.successNotification || \"$:/language/Notifications/CopiedToClipboard/Succeeded\",\n\t\t\tfailureNotification = options.failureNotification || \"$:/language/Notifications/CopiedToClipboard/Failed\"\n\t\t$tw.notifier.display(succeeded ? successNotification : failureNotification);\n\t}\n\tdocument.body.removeChild(textArea);\n};\n\nexports.getLocationPath = function() {\n\treturn window.location.toString().split(\"#\")[0];\n};\n\n/*\nCollect DOM variables\n*/\nexports.collectDOMVariables = function(selectedNode,domNode,event) {\n\tvar variables = {},\n\t    selectedNodeRect,\n\t    domNodeRect;\n\tif(selectedNode) {\n\t\t$tw.utils.each(selectedNode.attributes,function(attribute) {\n\t\t\tvariables[\"dom-\" + attribute.name] = attribute.value.toString();\n\t\t});\n\t\t\n\t\tif(\"offsetLeft\" in selectedNode) {\n\t\t\t// Add variables with a (relative and absolute) popup coordinate string for the selected node\n\t\t\tvar nodeRect = {\n\t\t\t\tleft: selectedNode.offsetLeft,\n\t\t\t\ttop: selectedNode.offsetTop,\n\t\t\t\twidth: selectedNode.offsetWidth,\n\t\t\t\theight: selectedNode.offsetHeight\n\t\t\t};\n\t\t\tvariables[\"tv-popup-coords\"] = Popup.buildCoordinates(Popup.coordinatePrefix.csOffsetParent,nodeRect);\n\n\t\t\tvar absRect = $tw.utils.extend({}, nodeRect);\n\t\t\tfor(var currentNode = selectedNode.offsetParent; currentNode; currentNode = currentNode.offsetParent) {\n\t\t\t\tabsRect.left += currentNode.offsetLeft;\n\t\t\t\tabsRect.top += currentNode.offsetTop;\n\t\t\t}\n\t\t\tvariables[\"tv-popup-abs-coords\"] = Popup.buildCoordinates(Popup.coordinatePrefix.csAbsolute,absRect);\n\n\t\t\t// Add variables for offset of selected node\n\t\t\tvariables[\"tv-selectednode-posx\"] = selectedNode.offsetLeft.toString();\n\t\t\tvariables[\"tv-selectednode-posy\"] = selectedNode.offsetTop.toString();\n\t\t\tvariables[\"tv-selectednode-width\"] = selectedNode.offsetWidth.toString();\n\t\t\tvariables[\"tv-selectednode-height\"] = selectedNode.offsetHeight.toString();\n\t\t}\n\t}\n\t\n\tif(domNode && (\"offsetWidth\" in domNode)) {\n\t\tvariables[\"tv-widgetnode-width\"] = domNode.offsetWidth.toString();\n\t\tvariables[\"tv-widgetnode-height\"] = domNode.offsetHeight.toString();\n\t}\n\n\tif(event && (\"clientX\" in event) && (\"clientY\" in event)) {\n\t\tif(selectedNode) {\n\t\t\t// Add variables for event X and Y position relative to selected node\n\t\t\tselectedNodeRect = selectedNode.getBoundingClientRect();\n\t\t\tvariables[\"event-fromselected-posx\"] = (event.clientX - selectedNodeRect.left).toString();\n\t\t\tvariables[\"event-fromselected-posy\"] = (event.clientY - selectedNodeRect.top).toString();\n\t\t}\n\t\t\n\t\tif(domNode) {\n\t\t\t// Add variables for event X and Y position relative to event catcher node\n\t\t\tdomNodeRect = domNode.getBoundingClientRect();\n\t\t\tvariables[\"event-fromcatcher-posx\"] = (event.clientX - domNodeRect.left).toString();\n\t\t\tvariables[\"event-fromcatcher-posy\"] = (event.clientY - domNodeRect.top).toString();\n\t\t}\n\n\t\t// Add variables for event X and Y position relative to the viewport\n\t\tvariables[\"event-fromviewport-posx\"] = event.clientX.toString();\n\t\tvariables[\"event-fromviewport-posy\"] = event.clientY.toString();\n\t}\n\treturn variables;\n};\n\n/*\nMake sure the CSS selector is not invalid\n*/\nexports.querySelectorSafe = function(selector,baseElement) {\n\tbaseElement = baseElement || document;\n\ttry {\n\t\treturn baseElement.querySelector(selector);\n\t} catch(e) {\n\t\tconsole.log(\"Invalid selector: \",selector);\n\t}\n};\n\nexports.querySelectorAllSafe = function(selector,baseElement) {\n\tbaseElement = baseElement || document;\n\ttry {\n\t\treturn baseElement.querySelectorAll(selector);\n\t} catch(e) {\n\t\tconsole.log(\"Invalid selector: \",selector);\n\t}\n};\n\n})();\n","type":"application/javascript","module-type":"utils"},"$:/core/modules/utils/dom/dragndrop.js":{"title":"$:/core/modules/utils/dom/dragndrop.js","text":"/*\\\ntitle: $:/core/modules/utils/dom/dragndrop.js\ntype: application/javascript\nmodule-type: utils\n\nBrowser data transfer utilities, used with the clipboard and drag and drop\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nOptions:\n\ndomNode: dom node to make draggable\nselector: CSS selector to identify element within domNode to be used as drag handle (optional)\ndragImageType: \"pill\", \"blank\" or \"dom\" (the default)\ndragTiddlerFn: optional function to retrieve the title of tiddler to drag\ndragFilterFn: optional function to retreive the filter defining a list of tiddlers to drag\nwidget: widget to use as the context for the filter\n*/\nexports.makeDraggable = function(options) {\n\tvar dragImageType = options.dragImageType || \"dom\",\n\t\tdragImage,\n\t\tdomNode = options.domNode;\n\t// Make the dom node draggable (not necessary for anchor tags)\n\tif(!options.selector && ((domNode.tagName || \"\").toLowerCase() !== \"a\")) {\n\t\tdomNode.setAttribute(\"draggable\",\"true\");\n\t}\n\t// Add event handlers\n\t$tw.utils.addEventListeners(domNode,[\n\t\t{name: \"dragstart\", handlerFunction: function(event) {\n\t\t\tif(event.dataTransfer === undefined) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// Collect the tiddlers being dragged\n\t\t\tvar dragTiddler = options.dragTiddlerFn && options.dragTiddlerFn(),\n\t\t\t\tdragFilter = options.dragFilterFn && options.dragFilterFn(),\n\t\t\t\ttitles = dragTiddler ? [dragTiddler] : [],\n\t\t\t\tstartActions = options.startActions,\n\t\t\t\tvariables,\n\t\t\t\tdomNodeRect;\n\t\t\tif(dragFilter) {\n\t\t\t\ttitles.push.apply(titles,options.widget.wiki.filterTiddlers(dragFilter,options.widget));\n\t\t\t}\n\t\t\tvar titleString = $tw.utils.stringifyList(titles);\n\t\t\t// Check that we've something to drag\n\t\t\tif(titles.length > 0 && (options.selector && $tw.utils.domMatchesSelector(event.target,options.selector) || event.target === domNode)) {\n\t\t\t\t// Mark the drag in progress\n\t\t\t\t$tw.dragInProgress = domNode;\n\t\t\t\t// Set the dragging class on the element being dragged\n\t\t\t\t$tw.utils.addClass(domNode,\"tc-dragging\");\n\t\t\t\t// Invoke drag-start actions if given\n\t\t\t\tif(startActions !== undefined) {\n\t\t\t\t\t// Collect our variables\n\t\t\t\t\tvariables = $tw.utils.collectDOMVariables(domNode,null,event);\n\t\t\t\t\tvariables.modifier = $tw.keyboardManager.getEventModifierKeyDescriptor(event);\n\t\t\t\t\tvariables[\"actionTiddler\"] = titleString;\n\t\t\t\t\toptions.widget.invokeActionString(startActions,options.widget,event,variables);\n\t\t\t\t}\n\t\t\t\t// Create the drag image elements\n\t\t\t\tdragImage = options.widget.document.createElement(\"div\");\n\t\t\t\tdragImage.className = \"tc-tiddler-dragger\";\n\t\t\t\tvar inner = options.widget.document.createElement(\"div\");\n\t\t\t\tinner.className = \"tc-tiddler-dragger-inner\";\n\t\t\t\tinner.appendChild(options.widget.document.createTextNode(\n\t\t\t\t\ttitles.length === 1 ? \n\t\t\t\t\t\ttitles[0] :\n\t\t\t\t\t\ttitles.length + \" tiddlers\"\n\t\t\t\t));\n\t\t\t\tdragImage.appendChild(inner);\n\t\t\t\toptions.widget.document.body.appendChild(dragImage);\n\t\t\t\t// Set the data transfer properties\n\t\t\t\tvar dataTransfer = event.dataTransfer;\n\t\t\t\t// Set up the image\n\t\t\t\tdataTransfer.effectAllowed = \"all\";\n\t\t\t\tif(dataTransfer.setDragImage) {\n\t\t\t\t\tif(dragImageType === \"pill\") {\n\t\t\t\t\t\tdataTransfer.setDragImage(dragImage.firstChild,-16,-16);\n\t\t\t\t\t} else if(dragImageType === \"blank\") {\n\t\t\t\t\t\tdragImage.removeChild(dragImage.firstChild);\n\t\t\t\t\t\tdataTransfer.setDragImage(dragImage,0,0);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvar r = domNode.getBoundingClientRect();\n\t\t\t\t\t\tdataTransfer.setDragImage(domNode,event.clientX-r.left,event.clientY-r.top);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Set up the data transfer\n\t\t\t\tif(dataTransfer.clearData) {\n\t\t\t\t\tdataTransfer.clearData();\n\t\t\t\t}\n\t\t\t\tvar jsonData = [];\n\t\t\t\tif(titles.length > 1) {\n\t\t\t\t\ttitles.forEach(function(title) {\n\t\t\t\t\t\tjsonData.push(options.widget.wiki.getTiddlerAsJson(title));\n\t\t\t\t\t});\n\t\t\t\t\tjsonData = \"[\" + jsonData.join(\",\") + \"]\";\n\t\t\t\t} else {\n\t\t\t\t\tjsonData = options.widget.wiki.getTiddlerAsJson(titles[0]);\n\t\t\t\t}\n\t\t\t\t// IE doesn't like these content types\n\t\t\t\tif(!$tw.browser.isIE) {\n\t\t\t\t\tdataTransfer.setData(\"text/vnd.tiddler\",jsonData);\n\t\t\t\t\tdataTransfer.setData(\"text/plain\",titleString);\n\t\t\t\t\tdataTransfer.setData(\"text/x-moz-url\",\"data:text/vnd.tiddler,\" + encodeURIComponent(jsonData));\n\t\t\t\t}\n\t\t\t\t// If browser is Chrome-like and has a touch-input device do NOT .setData\n\t\t\t\tif(!($tw.browser.isMobileChrome)) {\n\t\t\t\t\tdataTransfer.setData(\"URL\",\"data:text/vnd.tiddler,\" + encodeURIComponent(jsonData));\n\t\t\t\t}\n\t\t\t\tdataTransfer.setData(\"Text\",titleString);\n\t\t\t\tevent.stopPropagation();\n\t\t\t}\n\t\t\treturn false;\n\t\t}},\n\t\t{name: \"dragend\", handlerFunction: function(event) {\n\t\t\tif((options.selector && $tw.utils.domMatchesSelector(event.target,options.selector)) || event.target === domNode) {\n\t\t\t\t// Collect the tiddlers being dragged\n\t\t\t\tvar dragTiddler = options.dragTiddlerFn && options.dragTiddlerFn(),\n\t\t\t\t\tdragFilter = options.dragFilterFn && options.dragFilterFn(),\n\t\t\t\t\ttitles = dragTiddler ? [dragTiddler] : [],\n\t\t\t\t\tendActions = options.endActions,\n\t\t\t\t\tvariables;\n\t\t\t\tif(dragFilter) {\n\t\t\t\t\ttitles.push.apply(titles,options.widget.wiki.filterTiddlers(dragFilter,options.widget));\n\t\t\t\t}\n\t\t\t\tvar titleString = $tw.utils.stringifyList(titles);\n\t\t\t\t$tw.dragInProgress = null;\n\t\t\t\t// Invoke drag-end actions if given\n\t\t\t\tif(endActions !== undefined) {\n\t\t\t\t\tvariables = $tw.utils.collectDOMVariables(domNode,null,event);\n\t\t\t\t\tvariables.modifier = $tw.keyboardManager.getEventModifierKeyDescriptor(event);\n\t\t\t\t\tvariables[\"actionTiddler\"] = titleString;\n\t\t\t\t\toptions.widget.invokeActionString(endActions,options.widget,event,variables);\n\t\t\t\t}\n\t\t\t\t// Remove the dragging class on the element being dragged\n\t\t\t\t$tw.utils.removeClass(domNode,\"tc-dragging\");\n\t\t\t\t// Delete the drag image element\n\t\t\t\tif(dragImage) {\n\t\t\t\t\tdragImage.parentNode.removeChild(dragImage);\n\t\t\t\t\tdragImage = null;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}}\n\t]);\n};\n\nexports.importDataTransfer = function(dataTransfer,fallbackTitle,callback) {\n\t// Try each provided data type in turn\n\tif($tw.log.IMPORT) {\n\t\tconsole.log(\"Available data types:\");\n\t\tfor(var type=0; type<dataTransfer.types.length; type++) {\n\t\t\tconsole.log(\"type\",dataTransfer.types[type],dataTransfer.getData(dataTransfer.types[type]))\n\t\t}\n\t}\n\tfor(var t=0; t<importDataTypes.length; t++) {\n\t\tif(!$tw.browser.isIE || importDataTypes[t].IECompatible) {\n\t\t\t// Get the data\n\t\t\tvar dataType = importDataTypes[t];\n\t\t\tvar data = dataTransfer.getData(dataType.type);\n\t\t\t// Import the tiddlers in the data\n\t\t\tif(data !== \"\" && data !== null) {\n\t\t\t\tif($tw.log.IMPORT) {\n\t\t\t\t\tconsole.log(\"Importing data type '\" + dataType.type + \"', data: '\" + data + \"'\")\n\t\t\t\t}\n\t\t\t\tvar tiddlerFields = dataType.toTiddlerFieldsArray(data,fallbackTitle);\n\t\t\t\tcallback(tiddlerFields);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n};\n\nexports.importPaste = function(item,fallbackTitle,callback) {\n\t// Try each provided data type in turn\n\tfor(var t=0; t<importDataTypes.length; t++) {\n\t\tif(item.type === importDataTypes[t].type) {\n\t\t\t// Get the data\n\t\t\tvar dataType = importDataTypes[t];\n\n\t\t\titem.getAsString(function(data){\n\t\t\t\tif($tw.log.IMPORT) {\n\t\t\t\t\tconsole.log(\"Importing data type '\" + dataType.type + \"', data: '\" + data + \"'\")\n\t\t\t\t}\n\t\t\t\tvar tiddlerFields = dataType.toTiddlerFieldsArray(data,fallbackTitle);\n\t\t\t\tcallback(tiddlerFields);\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t}\n};\n\nexports.itemHasValidDataType = function(item) {\n\tfor(var t=0; t<importDataTypes.length; t++) {\n\t\tif(!$tw.browser.isIE || importDataTypes[t].IECompatible) {\n\t\t\tif(item.type === importDataTypes[t].type) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n}\n\nvar importDataTypes = [\n\t{type: \"text/vnd.tiddler\", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {\n\t\treturn parseJSONTiddlers(data,fallbackTitle);\n\t}},\n\t{type: \"URL\", IECompatible: true, toTiddlerFieldsArray: function(data,fallbackTitle) {\n\t\t// Check for tiddler data URI\n\t\tvar match = $tw.utils.decodeURIComponentSafe(data).match(/^data\\:text\\/vnd\\.tiddler,(.*)/i);\n\t\tif(match) {\n\t\t\treturn parseJSONTiddlers(match[1],fallbackTitle);\n\t\t} else {\n\t\t\treturn [{title: fallbackTitle, text: data}]; // As URL string\n\t\t}\n\t}},\n\t{type: \"text/x-moz-url\", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {\n\t\t// Check for tiddler data URI\n\t\tvar match = $tw.utils.decodeURIComponentSafe(data).match(/^data\\:text\\/vnd\\.tiddler,(.*)/i);\n\t\tif(match) {\n\t\t\treturn parseJSONTiddlers(match[1],fallbackTitle);\n\t\t} else {\n\t\t\treturn [{title: fallbackTitle, text: data}]; // As URL string\n\t\t}\n\t}},\n\t{type: \"text/html\", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {\n\t\treturn [{title: fallbackTitle, text: data}];\n\t}},\n\t{type: \"text/plain\", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {\n\t\treturn [{title: fallbackTitle, text: data}];\n\t}},\n\t{type: \"Text\", IECompatible: true, toTiddlerFieldsArray: function(data,fallbackTitle) {\n\t\treturn [{title: fallbackTitle, text: data}];\n\t}},\n\t{type: \"text/uri-list\", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {\n\t\t// Check for tiddler data URI\n\t\tvar match = $tw.utils.decodeURIComponentSafe(data).match(/^data\\:text\\/vnd\\.tiddler,(.*)/i);\n\t\tif(match) {\n\t\t\treturn parseJSONTiddlers(match[1],fallbackTitle);\n\t\t} else {\n\t\t\treturn [{title: fallbackTitle, text: data}]; // As URL string\n\t\t}\n\t}}\n];\n\nfunction parseJSONTiddlers(json,fallbackTitle) {\n\tvar data = $tw.utils.parseJSONSafe(json);\n\tif(!$tw.utils.isArray(data)) {\n\t\tdata = [data];\n\t}\n\tdata.forEach(function(fields) {\n\t\tfields.title = fields.title || fallbackTitle;\n\t});\n\treturn data;\n};\n\nfunction dragEventContainsType(event,targetType) {\n\tif(event.dataTransfer.types) {\n\t\tfor(var i=0; i<event.dataTransfer.types.length; i++) {\n\t\t\tif(event.dataTransfer.types[i] === targetType) {\n\t\t\t\treturn true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n};\n\nexports.dragEventContainsFiles = function(event) {\n\treturn (dragEventContainsType(event,\"Files\") && !dragEventContainsType(event,\"text/plain\"));\n};\n\nexports.dragEventContainsType = dragEventContainsType;\n\n})();\n","type":"application/javascript","module-type":"utils"},"$:/core/modules/utils/dom/http.js":{"title":"$:/core/modules/utils/dom/http.js","text":"/*\\\ntitle: $:/core/modules/utils/dom/http.js\ntype: application/javascript\nmodule-type: utils\n\nHTTP support\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nManage tm-http-request events. Options include:\nwiki: Reference to the wiki to be used for state tiddler tracking\nstateTrackerTitle: Title of tiddler to be used for state tiddler tracking\n*/\nfunction HttpClient(options) {\n\toptions = options || {};\n\tthis.nextId = 1;\n\tthis.wiki = options.wiki || $tw.wiki;\n\tthis.stateTrackerTitle = options.stateTrackerTitle || \"$:/state/http-requests\";\n\tthis.requests = []; // Array of {id: string,request: HttpClientRequest}\n\tthis.updateRequestTracker();\n}\n\n/*\nReturn the index into this.requests[] corresponding to a given ID. Returns null if not found\n*/\nHttpClient.prototype.getRequestIndex = function(targetId) {\n\tvar targetIndex = null;\n\t$tw.utils.each(this.requests,function(requestInfo,index) {\n\t\tif(requestInfo.id === targetId) {\n\t\t\ttargetIndex = index;\n\t\t}\n\t});\n\treturn targetIndex;\n};\n\n/*\nUpdate the state tiddler that is tracking the outstanding requests\n*/\nHttpClient.prototype.updateRequestTracker = function() {\n\tthis.wiki.addTiddler({title: this.stateTrackerTitle, text: \"\" + this.requests.length});\n};\n\nHttpClient.prototype.initiateHttpRequest = function(options) {\n\tvar self = this,\n\t\tid = this.nextId,\n\t\trequest = new HttpClientRequest(options);\n\tthis.nextId += 1;\n\tthis.requests.push({id: id, request: request});\n\tthis.updateRequestTracker();\n\trequest.send(function(err) {\n\t\tvar targetIndex = self.getRequestIndex(id);\n\t\tif(targetIndex !== null) {\n\t\t\tself.requests.splice(targetIndex,1);\n\t\t\tself.updateRequestTracker();\n\t\t}\n\t});\n\treturn id;\n};\n\nHttpClient.prototype.cancelAllHttpRequests = function() {\n\tvar self = this;\n\tif(this.requests.length > 0) {\n\t\tfor(var t=this.requests.length - 1; t--; t>=0) {\n\t\t\tvar requestInfo = this.requests[t];\n\t\t\trequestInfo.request.cancel();\n\t\t}\n\t}\n\tthis.requests = [];\n\tthis.updateRequestTracker();\n};\n\nHttpClient.prototype.cancelHttpRequest = function(targetId) {\n\tvar targetIndex = this.getRequestIndex(targetId);\n\tif(targetIndex !== null) {\n\t\tthis.requests[targetIndex].request.cancel();\n\t\tthis.requests.splice(targetIndex,1);\n\t\tthis.updateRequestTracker();\n\t}\n};\n\n/*\nInitiate an HTTP request. Options:\nwiki: wiki to be used for executing action strings\nurl: URL for request\nmethod: method eg GET, POST\nbody: text of request body\nbinary: set to \"yes\" to force binary processing of response payload\noncompletion: action string to be invoked on completion\nonprogress: action string to be invoked on progress updates\nbindStatus: optional title of tiddler to which status (\"pending\", \"complete\", \"error\") should be written\nbindProgress: optional title of tiddler to which the progress of the request (0 to 100) should be bound\nvariables: hashmap of variable name to string value passed to action strings\nheaders: hashmap of header name to header value to be sent with the request\npasswordHeaders: hashmap of header name to password store name to be sent with the request\nqueryStrings: hashmap of query string parameter name to parameter value to be sent with the request\npasswordQueryStrings: hashmap of query string parameter name to password store name to be sent with the request\nbasicAuthUsername: plain username for basic authentication\nbasicAuthUsernameFromStore: name of password store entry containing username\nbasicAuthPassword: plain password for basic authentication\nbasicAuthPasswordFromStore: name of password store entry containing password\nbearerAuthToken: plain text token for bearer authentication\nbearerAuthTokenFromStore: name of password store entry contain bear authorization token\n*/\nfunction HttpClientRequest(options) {\n\tvar self = this;\n\tconsole.log(\"Initiating an HTTP request\",options)\n\tthis.wiki = options.wiki;\n\tthis.completionActions = options.oncompletion;\n\tthis.progressActions = options.onprogress;\n\tthis.bindStatus = options[\"bindStatus\"];\n\tthis.bindProgress = options[\"bindProgress\"];\n\tthis.method = options.method || \"GET\";\n\tthis.body = options.body || \"\";\n\tthis.binary = options.binary || \"\";\n\tthis.useDefaultHeaders = options.useDefaultHeaders !== \"false\" ? true : false,\n\tthis.variables = options.variables;\n\tvar url = options.url;\n\t$tw.utils.each(options.queryStrings,function(value,name) {\n\t\turl = $tw.utils.setQueryStringParameter(url,name,value);\n\t});\n\t$tw.utils.each(options.passwordQueryStrings,function(value,name) {\n\t\turl = $tw.utils.setQueryStringParameter(url,name,$tw.utils.getPassword(value) || \"\");\n\t});\n\tthis.url = url;\n\tthis.requestHeaders = {};\n\t$tw.utils.each(options.headers,function(value,name) {\n\t\tself.requestHeaders[name] = value;\n\t});\n\t$tw.utils.each(options.passwordHeaders,function(value,name) {\n\t\tself.requestHeaders[name] = $tw.utils.getPassword(value) || \"\";\n\t});\n\tthis.basicAuthUsername = options.basicAuthUsername || (options.basicAuthUsernameFromStore && $tw.utils.getPassword(options.basicAuthUsernameFromStore)) || \"\";\n\tthis.basicAuthPassword = options.basicAuthPassword || (options.basicAuthPasswordFromStore && $tw.utils.getPassword(options.basicAuthPasswordFromStore)) || \"\";\n\tthis.bearerAuthToken = options.bearerAuthToken || (options.bearerAuthTokenFromStore && $tw.utils.getPassword(options.bearerAuthTokenFromStore)) || \"\";\n\tif(this.basicAuthUsername && this.basicAuthPassword) {\n\t\tthis.requestHeaders.Authorization = \"Basic \" + $tw.utils.base64Encode(this.basicAuthUsername + \":\" + this.basicAuthPassword);\n\t} else if(this.bearerAuthToken) {\n\t\tthis.requestHeaders.Authorization = \"Bearer \" + this.bearerAuthToken;\n\t}\n}\n\nHttpClientRequest.prototype.send = function(callback) {\n\tvar self = this,\n\t\tsetBinding = function(title,text) {\n\t\t\tif(title) {\n\t\t\t\tself.wiki.addTiddler(new $tw.Tiddler({title: title, text: text}));\n\t\t\t}\n\t\t};\n\tif(this.url) {\n\t\tsetBinding(this.bindStatus,\"pending\");\n\t\tsetBinding(this.bindProgress,\"0\");\n\t\t// Set the request tracker tiddler\n\t\tvar requestTrackerTitle = this.wiki.generateNewTitle(\"$:/temp/HttpRequest\");\n\t\tthis.wiki.addTiddler({\n\t\t\ttitle: requestTrackerTitle,\n\t\t\ttags: \"$:/tags/HttpRequest\",\n\t\t\ttext: JSON.stringify({\n\t\t\t\turl: this.url,\n\t\t\t\ttype: this.method,\n\t\t\t\tstatus: \"inprogress\",\n\t\t\t\theaders: this.requestHeaders,\n\t\t\t\tdata: this.body\n\t\t\t})\n\t\t});\n\t\tthis.xhr = $tw.utils.httpRequest({\n\t\t\turl: this.url,\n\t\t\ttype: this.method,\n\t\t\tuseDefaultHeaders: this.useDefaultHeaders,\n\t\t\theaders: this.requestHeaders,\n\t\t\tdata: this.body,\n\t\t\treturnProp: this.binary === \"\" ? \"responseText\" : \"response\",\n\t\t\tresponseType: this.binary === \"\" ? \"text\" : \"arraybuffer\",\n\t\t\tcallback: function(err,data,xhr) {\n\t\t\t\tvar hasSucceeded = xhr.status >= 200 && xhr.status < 300,\n\t\t\t\t\tcompletionCode = hasSucceeded ? \"complete\" : \"error\",\n\t\t\t\t\theaders = {};\n\t\t\t\t$tw.utils.each(xhr.getAllResponseHeaders().split(\"\\r\\n\"),function(line) {\n\t\t\t\t\tvar pos = line.indexOf(\":\");\n\t\t\t\t\tif(pos !== -1) {\n\t\t\t\t\t\theaders[line.substr(0,pos)] = line.substr(pos + 1).trim();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tsetBinding(self.bindStatus,completionCode);\n\t\t\t\tsetBinding(self.bindProgress,\"100\");\n\t\t\t\tvar resultVariables = {\n\t\t\t\t\tstatus: xhr.status.toString(),\n\t\t\t\t\tstatusText: xhr.statusText,\n\t\t\t\t\terror: (err || \"\").toString(),\n\t\t\t\t\tdata: (data || \"\").toString(),\n\t\t\t\t\theaders: JSON.stringify(headers)\n\t\t\t\t};\n\t\t\t\t/* Convert data from binary to base64 */\n\t\t\t\tif (xhr.responseType === \"arraybuffer\") {\n\t\t\t\t\tvar binary = \"\",\n\t\t\t\t\t\tbytes = new Uint8Array(data),\n\t\t\t\t\t\tlen = bytes.byteLength;\n\t\t\t\t\tfor (var i=0; i<len; i++) {\n\t\t\t\t\t\tbinary += String.fromCharCode(bytes[i]);\n\t\t\t\t\t}\n\t\t\t\t\tresultVariables.data = $tw.utils.base64Encode(binary,true);\n\t\t\t\t}\n\t\t\t\tself.wiki.addTiddler(new $tw.Tiddler(self.wiki.getTiddler(requestTrackerTitle),{\n\t\t\t\t\tstatus: completionCode,\n\t\t\t\t}));\n\t\t\t\tself.wiki.invokeActionString(self.completionActions,undefined,$tw.utils.extend({},self.variables,resultVariables),{parentWidget: $tw.rootWidget});\n\t\t\t\tcallback(hasSucceeded ? null : xhr.statusText);\n\t\t\t\t// console.log(\"Back!\",err,data,xhr);\n\t\t\t},\n\t\t\tprogress: function(lengthComputable,loaded,total) {\n\t\t\t\tif(lengthComputable) {\n\t\t\t\t\tsetBinding(self.bindProgress,\"\" + Math.floor((loaded/total) * 100))\n\t\t\t\t}\n\t\t\t\tself.wiki.invokeActionString(self.progressActions,undefined,{\n\t\t\t\t\tlengthComputable: lengthComputable ? \"yes\" : \"no\",\n\t\t\t\t\tloaded: loaded,\n\t\t\t\t\ttotal: total\n\t\t\t\t},{parentWidget: $tw.rootWidget});\n\t\t\t}\n\t\t});\n\t}\n};\n\nHttpClientRequest.prototype.cancel = function() {\n\tif(this.xhr) {\n\t\tthis.xhr.abort();\n\t}\n};\n\nexports.HttpClient = HttpClient;\n\n/*\nMake an HTTP request. Options are:\n\turl: URL to retrieve\n\theaders: hashmap of headers to send\n\ttype: GET, PUT, POST etc\n\tcallback: function invoked with (err,data,xhr)\n\tprogress: optional function invoked with (lengthComputable,loaded,total)\n\treturnProp: string name of the property to return as first argument of callback\n\tresponseType: \"text\" or \"arraybuffer\"\n*/\nexports.httpRequest = function(options) {\n\tvar type = options.type || \"GET\",\n\t\turl = options.url,\n\t\tuseDefaultHeaders = options.useDefaultHeaders !== false ? true : false,\n\t\theaders = options.headers || (useDefaultHeaders ? {accept: \"application/json\"} : {}),\n\t\thasHeader = function(targetHeader) {\n\t\t\ttargetHeader = targetHeader.toLowerCase();\n\t\t\tvar result = false;\n\t\t\t$tw.utils.each(headers,function(header,headerTitle,object) {\n\t\t\t\tif(headerTitle.toLowerCase() === targetHeader) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn result;\n\t\t},\n\t\tgetHeader = function(targetHeader) {\n\t\t\treturn headers[targetHeader] || headers[targetHeader.toLowerCase()];\n\t\t},\n\t\tisSimpleRequest = function(type,headers) {\n\t\t\tif([\"GET\",\"HEAD\",\"POST\"].indexOf(type) === -1) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tfor(var header in headers) {\n\t\t\t\tif([\"accept\",\"accept-language\",\"content-language\",\"content-type\"].indexOf(header.toLowerCase()) === -1) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(hasHeader(\"Content-Type\") && [\"application/x-www-form-urlencoded\",\"multipart/form-data\",\"text/plain\"].indexOf(getHeader[\"Content-Type\"]) === -1) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\t\treturnProp = options.returnProp || \"responseText\",\n\t\trequest = new XMLHttpRequest(),\n\t\tdata = \"\",\n\t\tf,results;\n\t// Massage the data hashmap into a string\n\tif(options.data) {\n\t\tif(typeof options.data === \"string\") { // Already a string\n\t\t\tdata = options.data;\n\t\t} else { // A hashmap of strings\n\t\t\tresults = [];\n\t\t\t$tw.utils.each(options.data,function(dataItem,dataItemTitle) {\n\t\t\t\tresults.push(dataItemTitle + \"=\" + encodeURIComponent(dataItem));\n\t\t\t});\n\t\t\tif(type === \"GET\" || type === \"HEAD\") {\n\t\t\t\turl += \"?\" + results.join(\"&\");\n\t\t\t} else {\n\t\t\t\tdata = results.join(\"&\");\n\t\t\t}\n\t\t}\n\t}\n\trequest.responseType = options.responseType || \"text\";\n\t// Set up the state change handler\n\trequest.onreadystatechange = function() {\n\t\tif(this.readyState === 4) {\n\t\t\tif(this.status >= 200 && this.status < 300) {\n\t\t\t\t// Success!\n\t\t\t\toptions.callback(null,this[returnProp],this);\n\t\t\t\treturn;\n\t\t\t}\n\t\t// Something went wrong\n\t\toptions.callback($tw.language.getString(\"Error/XMLHttpRequest\") + \": \" + this.status,this[returnProp],this);\n\t\t}\n\t};\n\t// Handle progress\n\tif(options.progress) {\n\t\trequest.onprogress = function(event) {\n\t\t\tconsole.log(\"Progress event\",event)\n\t\t\toptions.progress(event.lengthComputable,event.loaded,event.total);\n\t\t};\n\t}\n\t// Make the request\n\trequest.open(type,url,true);\n\t// Headers\n\tif(headers) {\n\t\t$tw.utils.each(headers,function(header,headerTitle,object) {\n\t\t\trequest.setRequestHeader(headerTitle,header);\n\t\t});\n\t}\n\tif(data && !hasHeader(\"Content-Type\") && useDefaultHeaders) {\n\t\trequest.setRequestHeader(\"Content-Type\",\"application/x-www-form-urlencoded; charset=UTF-8\");\n\t}\n\tif(!hasHeader(\"X-Requested-With\") && !isSimpleRequest(type,headers) && useDefaultHeaders) {\n\t\trequest.setRequestHeader(\"X-Requested-With\",\"TiddlyWiki\");\n\t}\n\t// Send data\n\ttry {\n\t\trequest.send(data);\n\t} catch(e) {\n\t\toptions.callback(e,null,this);\n\t}\n\treturn request;\n};\n\nexports.setQueryStringParameter = function(url,paramName,paramValue) {\n\tvar URL = $tw.browser ? window.URL : require(\"url\").URL,\n\t\tnewUrl;\n\ttry {\n\t\tnewUrl = new URL(url);\n\t} catch(e) {\n\t}\n\tif(newUrl && paramName) {\n\t\tnewUrl.searchParams.set(paramName,paramValue || \"\");\n\t\treturn newUrl.toString();\n\t} else {\n\t\treturn url;\n\t}\n};\n\n})();\n","type":"application/javascript","module-type":"utils"},"$:/core/modules/utils/dom/keyboard.js":{"title":"$:/core/modules/utils/dom/keyboard.js","text":"/*\\\ntitle: $:/core/modules/utils/dom/keyboard.js\ntype: application/javascript\nmodule-type: utils\n\nKeyboard utilities; now deprecated. Instead, use $tw.keyboardManager\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n[\"parseKeyDescriptor\",\"checkKeyDescriptor\"].forEach(function(method) {\n\texports[method] = function() {\n\t\tif($tw.keyboardManager) {\n\t\t\treturn $tw.keyboardManager[method].apply($tw.keyboardManager,Array.prototype.slice.call(arguments,0));\n\t\t} else {\n\t\t\treturn null\n\t\t}\n\t};\n});\n\n})();\n","type":"application/javascript","module-type":"utils"},"$:/core/modules/utils/dom/modal.js":{"title":"$:/core/modules/utils/dom/modal.js","text":"/*\\\ntitle: $:/core/modules/utils/dom/modal.js\ntype: application/javascript\nmodule-type: utils\n\nModal message mechanism\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\nvar navigator = require(\"$:/core/modules/widgets/navigator.js\");\n\nvar Modal = function(wiki) {\n\tthis.wiki = wiki;\n\tthis.modalCount = 0;\n};\n\n/*\nDisplay a modal dialogue\n\ttitle: Title of tiddler to display\n\toptions: see below\nOptions include:\n\tdownloadLink: Text of a big download link to include\n\tevent: widget event\n\tvariables: from event.paramObject\n*/\nModal.prototype.display = function(title,options) {\n\toptions = options || {};\n\tthis.srcDocument = options.variables && (options.variables.rootwindow === \"true\" ||\n\t\t\t\toptions.variables.rootwindow === \"yes\") ? document :\n\t\t\t\t(options.event && options.event.event && options.event.event.target ? options.event.event.target.ownerDocument : document);\n\tthis.srcWindow = this.srcDocument.defaultView;\n\tvar self = this,\n\t\trefreshHandler,\n\t\tduration = $tw.utils.getAnimationDuration(),\n\t\ttiddler = this.wiki.getTiddler(title);\n\t// Don't do anything if the tiddler doesn't exist\n\tif(!tiddler) {\n\t\treturn;\n\t}\n\t// Create the variables\n\tvar variables = $tw.utils.extend({\n\t\t\tcurrentTiddler: title,\n\t\t\t\"tv-story-list\": (options.event && options.event.widget ? options.event.widget.getVariable(\"tv-story-list\") : \"\"),\n\t\t\t\"tv-history-list\": (options.event && options.event.widget ? options.event.widget.getVariable(\"tv-history-list\") : \"\")\n\t\t},options.variables);\n\n\t// Create the wrapper divs\n\tvar wrapper = this.srcDocument.createElement(\"div\"),\n\t\tmodalBackdrop = this.srcDocument.createElement(\"div\"),\n\t\tmodalWrapper = this.srcDocument.createElement(\"div\"),\n\t\tmodalHeader = this.srcDocument.createElement(\"div\"),\n\t\theaderTitle = this.srcDocument.createElement(\"h3\"),\n\t\tmodalBody = this.srcDocument.createElement(\"div\"),\n\t\tmodalLink = this.srcDocument.createElement(\"a\"),\n\t\tmodalFooter = this.srcDocument.createElement(\"div\"),\n\t\tmodalFooterHelp = this.srcDocument.createElement(\"span\"),\n\t\tmodalFooterButtons = this.srcDocument.createElement(\"span\");\n\t// Up the modal count and adjust the body class\n\tthis.modalCount++;\n\tthis.adjustPageClass();\n\t// Add classes\n\t$tw.utils.addClass(wrapper,\"tc-modal-wrapper\");\n\tif(tiddler.fields && tiddler.fields.class) {\n\t\t$tw.utils.addClass(wrapper,tiddler.fields.class);\n\t}\n\t$tw.utils.addClass(modalBackdrop,\"tc-modal-backdrop\");\n\t$tw.utils.addClass(modalWrapper,\"tc-modal\");\n\t$tw.utils.addClass(modalHeader,\"tc-modal-header\");\n\t$tw.utils.addClass(modalBody,\"tc-modal-body\");\n\t$tw.utils.addClass(modalFooter,\"tc-modal-footer\");\n\t// Join them together\n\twrapper.appendChild(modalBackdrop);\n\twrapper.appendChild(modalWrapper);\n\tmodalHeader.appendChild(headerTitle);\n\tmodalWrapper.appendChild(modalHeader);\n\tmodalWrapper.appendChild(modalBody);\n\tmodalFooter.appendChild(modalFooterHelp);\n\tmodalFooter.appendChild(modalFooterButtons);\n\tmodalWrapper.appendChild(modalFooter);\n\tvar navigatorTree = {\n\t\t\"type\": \"navigator\",\n\t\t\"attributes\": {\n\t\t\t\"story\": {\n\t\t\t\t\"name\": \"story\",\n\t\t\t\t\"type\": \"string\",\n\t\t\t\t\"value\": variables[\"tv-story-list\"]\n\t\t\t},\n\t\t\t\"history\": {\n\t\t\t\t\"name\": \"history\",\n\t\t\t\t\"type\": \"string\",\n\t\t\t\t\"value\": variables[\"tv-history-list\"]\n\t\t\t}\n\t\t},\n\t\t\"tag\": \"$navigator\",\n\t\t\"isBlock\": true,\n\t\t\"children\": []\n\t};\n\tvar navigatorWidgetNode = new navigator.navigator(navigatorTree, {\n\t\twiki: this.wiki,\n\t\tdocument : this.srcDocument,\n\t\tparentWidget: $tw.rootWidget\n\t});\n\tnavigatorWidgetNode.render(modalBody,null);\n\n\t// Render the title of the message\n\tvar headerWidgetNode = this.wiki.makeTranscludeWidget(title,{\n\t\tfield: \"subtitle\",\n\t\tmode: \"inline\",\n\t\tchildren: [{\n\t\t\ttype: \"text\",\n\t\t\tattributes: {\n\t\t\t\ttext: {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tvalue: title\n\t\t}}}],\n\t\tparentWidget: navigatorWidgetNode,\n\t\tdocument: this.srcDocument,\n\t\tvariables: variables,\n\t\timportPageMacros: true\n\t});\n\theaderWidgetNode.render(headerTitle,null);\n\t// Render the body of the message\n\tvar bodyWidgetNode = this.wiki.makeTranscludeWidget(title,{\n\t\tparentWidget: navigatorWidgetNode,\n\t\tdocument: this.srcDocument,\n\t\tvariables: variables,\n\t\timportPageMacros: true\n\t});\n\n\tbodyWidgetNode.render(modalBody,null);\n\t// Setup the link if present\n\tif(options.downloadLink) {\n\t\tmodalLink.href = options.downloadLink;\n\t\tmodalLink.appendChild(this.srcDocument.createTextNode(\"Right-click to save changes\"));\n\t\tmodalBody.appendChild(modalLink);\n\t}\n\t// Render the footer of the message\n\tif(tiddler.fields && tiddler.fields.help) {\n\t\tvar link = this.srcDocument.createElement(\"a\");\n\t\tlink.setAttribute(\"href\",tiddler.fields.help);\n\t\tlink.setAttribute(\"target\",\"_blank\");\n\t\tlink.setAttribute(\"rel\",\"noopener noreferrer\");\n\t\tlink.appendChild(this.srcDocument.createTextNode(\"Help\"));\n\t\tmodalFooterHelp.appendChild(link);\n\t\tmodalFooterHelp.style.float = \"left\";\n\t}\n\tvar footerWidgetNode = this.wiki.makeTranscludeWidget(title,{\n\t\tfield: \"footer\",\n\t\tmode: \"inline\",\n\t\tchildren: [{\n\t\t\ttype: \"button\",\n\t\t\tattributes: {\n\t\t\t\tmessage: {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tvalue: \"tm-close-tiddler\"\n\t\t\t\t}\n\t\t\t},\n\t\t\tchildren: [{\n\t\t\t\ttype: \"text\",\n\t\t\t\tattributes: {\n\t\t\t\t\ttext: {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tvalue: $tw.language.getString(\"Buttons/Close/Caption\")\n\t\t\t}}}\n\t\t]}],\n\t\tparentWidget: navigatorWidgetNode,\n\t\tdocument: this.srcDocument,\n\t\tvariables: variables,\n\t\timportPageMacros: true\n\t});\n\tfooterWidgetNode.render(modalFooterButtons,null);\n\t// Set up the refresh handler\n\trefreshHandler = function(changes) {\n\t\theaderWidgetNode.refresh(changes,modalHeader,null);\n\t\tbodyWidgetNode.refresh(changes,modalBody,null);\n\t\tfooterWidgetNode.refresh(changes,modalFooterButtons,null);\n\t};\n\tthis.wiki.addEventListener(\"change\",refreshHandler);\n\t// Add the close event handler\n\tvar closeHandler = function(event) {\n\t\t// Remove our refresh handler\n\t\tself.wiki.removeEventListener(\"change\",refreshHandler);\n\t\t// Decrease the modal count and adjust the body class\n\t\tself.modalCount--;\n\t\tself.adjustPageClass();\n\t\t// Force layout and animate the modal message away\n\t\t$tw.utils.forceLayout(modalBackdrop);\n\t\t$tw.utils.forceLayout(modalWrapper);\n\t\t$tw.utils.setStyle(modalBackdrop,[\n\t\t\t{opacity: \"0\"}\n\t\t]);\n\t\t$tw.utils.setStyle(modalWrapper,[\n\t\t\t{transform: \"translateY(\" + self.srcWindow.innerHeight + \"px)\"}\n\t\t]);\n\t\t// Set up an event for the transition end\n\t\tself.srcWindow.setTimeout(function() {\n\t\t\tif(wrapper.parentNode) {\n\t\t\t\t// Remove the modal message from the DOM\n\t\t\t\tself.srcDocument.body.removeChild(wrapper);\n\t\t\t}\n\t\t},duration);\n\t\t// Don't let anyone else handle the tm-close-tiddler message\n\t\treturn false;\n\t};\n\theaderWidgetNode.addEventListener(\"tm-close-tiddler\",closeHandler,false);\n\tbodyWidgetNode.addEventListener(\"tm-close-tiddler\",closeHandler,false);\n\tfooterWidgetNode.addEventListener(\"tm-close-tiddler\",closeHandler,false);\n\t// Whether to close the modal dialog when the mask (area outside the modal) is clicked\n\tif(tiddler.fields && (tiddler.fields[\"mask-closable\"] === \"yes\" || tiddler.fields[\"mask-closable\"] === \"true\")) {\n\t\tmodalBackdrop.addEventListener(\"click\",closeHandler,false);\n\t}\n\t// Set the initial styles for the message\n\t$tw.utils.setStyle(modalBackdrop,[\n\t\t{opacity: \"0\"}\n\t]);\n\t$tw.utils.setStyle(modalWrapper,[\n\t\t{transformOrigin: \"0% 0%\"},\n\t\t{transform: \"translateY(\" + (-this.srcWindow.innerHeight) + \"px)\"}\n\t]);\n\t// Put the message into the document\n\tthis.srcDocument.body.appendChild(wrapper);\n\t// Set up animation for the styles\n\t$tw.utils.setStyle(modalBackdrop,[\n\t\t{transition: \"opacity \" + duration + \"ms ease-out\"}\n\t]);\n\t$tw.utils.setStyle(modalWrapper,[\n\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms ease-in-out\"}\n\t]);\n\t// Force layout\n\t$tw.utils.forceLayout(modalBackdrop);\n\t$tw.utils.forceLayout(modalWrapper);\n\t// Set final animated styles\n\t$tw.utils.setStyle(modalBackdrop,[\n\t\t{opacity: \"0.7\"}\n\t]);\n\t$tw.utils.setStyle(modalWrapper,[\n\t\t{transform: \"translateY(0px)\"}\n\t]);\n};\n\nModal.prototype.adjustPageClass = function() {\n\tvar windowContainer = $tw.pageContainer ? ($tw.pageContainer === this.srcDocument.body.firstChild ? $tw.pageContainer : this.srcDocument.body.firstChild) : null;\n\tif(windowContainer) {\n\t\t$tw.utils.toggleClass(windowContainer,\"tc-modal-displayed\",this.modalCount > 0);\n\t}\n\t$tw.utils.toggleClass(this.srcDocument.body,\"tc-modal-prevent-scroll\",this.modalCount > 0);\n};\n\nexports.Modal = Modal;\n\n})();\n","type":"application/javascript","module-type":"utils"},"$:/core/modules/utils/dom/notifier.js":{"title":"$:/core/modules/utils/dom/notifier.js","text":"/*\\\ntitle: $:/core/modules/utils/dom/notifier.js\ntype: application/javascript\nmodule-type: utils\n\nNotifier mechanism\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nvar Notifier = function(wiki) {\n\tthis.wiki = wiki;\n};\n\n/*\nDisplay a notification\n\ttitle: Title of tiddler containing the notification text\n\toptions: see below\nOptions include:\n*/\nNotifier.prototype.display = function(title,options) {\n\toptions = options || {};\n\t// Create the wrapper divs\n\tvar self = this,\n\t\tnotification = document.createElement(\"div\"),\n\t\ttiddler = this.wiki.getTiddler(title),\n\t\tduration = $tw.utils.getAnimationDuration(),\n\t\trefreshHandler;\n\t// Don't do anything if the tiddler doesn't exist\n\tif(!tiddler) {\n\t\treturn;\n\t}\n\t// Add classes and roles\n\t$tw.utils.addClass(notification,\"tc-notification\");\n\tnotification.setAttribute(\"role\",\"alert\");\n\t// Create the variables\n\tvar variables = $tw.utils.extend({currentTiddler: title},options.variables);\n\t// Render the body of the notification\n\tvar widgetNode = this.wiki.makeTranscludeWidget(title,{\n\t\tparentWidget: $tw.rootWidget,\n\t\tdocument: document,\n\t\tvariables: variables,\n\t\timportPageMacros: true});\n\twidgetNode.render(notification,null);\n\trefreshHandler = function(changes) {\n\t\twidgetNode.refresh(changes,notification,null);\n\t};\n\tthis.wiki.addEventListener(\"change\",refreshHandler);\n\t// Set the initial styles for the notification\n\t$tw.utils.setStyle(notification,[\n\t\t{opacity: \"0\"},\n\t\t{transformOrigin: \"0% 0%\"},\n\t\t{transform: \"translateY(\" + (-window.innerHeight) + \"px)\"},\n\t\t{transition: \"opacity \" + duration + \"ms ease-out, \" + $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms ease-in-out\"}\n\t]);\n\t// Add the notification to the DOM\n\tdocument.body.appendChild(notification);\n\t// Force layout\n\t$tw.utils.forceLayout(notification);\n\t// Set final animated styles\n\t$tw.utils.setStyle(notification,[\n\t\t{opacity: \"1.0\"},\n\t\t{transform: \"translateY(0px)\"}\n\t]);\n\t// Set a timer to remove the notification\n\twindow.setTimeout(function() {\n\t\t// Remove our change event handler\n\t\tself.wiki.removeEventListener(\"change\",refreshHandler);\n\t\t// Force layout and animate the notification away\n\t\t$tw.utils.forceLayout(notification);\n\t\t$tw.utils.setStyle(notification,[\n\t\t\t{opacity: \"0.0\"},\n\t\t\t{transform: \"translateX(\" + (notification.offsetWidth) + \"px)\"}\n\t\t]);\n\t\t// Remove the modal message from the DOM once the transition ends\n\t\tsetTimeout(function() {\n\t\t\tif(notification.parentNode) {\n\t\t\t\tdocument.body.removeChild(notification);\n\t\t\t}\n\t\t},duration);\n\t},$tw.config.preferences.notificationDuration);\n};\n\nexports.Notifier = Notifier;\n\n})();\n","type":"application/javascript","module-type":"utils"},"$:/core/modules/utils/dom/popup.js":{"title":"$:/core/modules/utils/dom/popup.js","text":"/*\\\ntitle: $:/core/modules/utils/dom/popup.js\ntype: application/javascript\nmodule-type: utils\n\nModule that creates a $tw.utils.Popup object prototype that manages popups in the browser\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nCreates a Popup object with these options:\n\trootElement: the DOM element to which the popup zapper should be attached\n*/\nvar Popup = function(options) {\n\toptions = options || {};\n\tthis.rootElement = options.rootElement || document.documentElement;\n\tthis.popups = []; // Array of {title:,wiki:,domNode:} objects\n};\n\n/*\nGlobal regular expression for parsing the location of a popup.\nThis is also used by the Reveal widget.\n*/\nexports.popupLocationRegExp = /^(@?)\\((-?[0-9\\.E]+),(-?[0-9\\.E]+),(-?[0-9\\.E]+),(-?[0-9\\.E]+)\\)$/\n\n/*\nObjekt containing the available prefixes for coordinates build with the `buildCoordinates` function:\n - csOffsetParent: Uses a coordinate system based on the offset parent (no prefix).\n - csAbsolute: Use an absolute coordinate system (prefix \"@\").\n*/\nexports.coordinatePrefix = { csOffsetParent: \"\", csAbsolute: \"@\" }\n\n/*\nTrigger a popup open or closed. Parameters are in a hashmap:\n\ttitle: title of the tiddler where the popup details are stored\n\tdomNode: dom node to which the popup will be positioned (one of domNode or domNodeRect is required)\n\tdomNodeRect: rectangle to which the popup will be positioned\n\twiki: wiki\n\tforce: if specified, forces the popup state to true or false (instead of toggling it)\n\tfloating: if true, skips registering the popup, meaning that it will need manually clearing\n*/\nPopup.prototype.triggerPopup = function(options) {\n\t// Check if this popup is already active\n\tvar index = this.findPopup(options.title);\n\t// Compute the new state\n\tvar state = index === -1;\n\tif(options.force !== undefined) {\n\t\tstate = options.force;\n\t}\n\t// Show or cancel the popup according to the new state\n\tif(state) {\n\t\tthis.show(options);\n\t} else {\n\t\tthis.cancel(index);\n\t}\n};\n\nPopup.prototype.findPopup = function(title) {\n\tvar index = -1;\n\tfor(var t=0; t<this.popups.length; t++) {\n\t\tif(this.popups[t].title === title) {\n\t\t\tindex = t;\n\t\t}\n\t}\n\treturn index;\n};\n\nPopup.prototype.handleEvent = function(event) {\n\tif(event.type === \"click\") {\n\t\t// Find out what was clicked on\n\t\tvar info = this.popupInfo(event.target),\n\t\t\tcancelLevel = info.popupLevel - 1;\n\t\t// Don't remove the level that was clicked on if we clicked on a handle\n\t\tif(info.isHandle) {\n\t\t\tcancelLevel++;\n\t\t}\n\t\t// Cancel\n\t\tthis.cancel(cancelLevel);\n\t}\n};\n\n/*\nFind the popup level containing a DOM node. Returns:\npopupLevel: count of the number of nested popups containing the specified element\nisHandle: true if the specified element is within a popup handle\n*/\nPopup.prototype.popupInfo = function(domNode) {\n\tvar isHandle = false,\n\t\tpopupCount = 0,\n\t\tnode = domNode;\n\t// First check ancestors to see if we're within a popup handle\n\twhile(node) {\n\t\tif($tw.utils.hasClass(node,\"tc-popup-handle\")) {\n\t\t\tisHandle = true;\n\t\t\tpopupCount++;\n\t\t}\n\t\tif($tw.utils.hasClass(node,\"tc-popup-keep\")) {\n\t\t\tisHandle = true;\n\t\t}\n\t\tnode = node.parentNode;\n\t}\n\t// Then count the number of ancestor popups\n\tnode = domNode;\n\twhile(node) {\n\t\tif($tw.utils.hasClass(node,\"tc-popup\")) {\n\t\t\tpopupCount++;\n\t\t}\n\t\tnode = node.parentNode;\n\t}\n\tvar info = {\n\t\tpopupLevel: popupCount,\n\t\tisHandle: isHandle\n\t};\n\treturn info;\n};\n\n/*\nDisplay a popup by adding it to the stack\n*/\nPopup.prototype.show = function(options) {\n\t// Find out what was clicked on\n\tvar info = this.popupInfo(options.domNode);\n\t// Cancel any higher level popups\n\tthis.cancel(info.popupLevel);\n\n\t// Store the popup details if not already there\n\tif(!options.floating && this.findPopup(options.title) === -1) {\n\t\tthis.popups.push({\n\t\t\ttitle: options.title,\n\t\t\twiki: options.wiki,\n\t\t\tdomNode: options.domNode,\n\t\t\tnoStateReference: options.noStateReference\n\t\t});\n\t}\n\t// Set the state tiddler\n\tvar rect;\n\tif(options.domNodeRect) {\n\t\trect = options.domNodeRect;\n\t} else {\n\t\trect = {\n\t\t\tleft: options.domNode.offsetLeft,\n\t\t\ttop: options.domNode.offsetTop,\n\t\t\twidth: options.domNode.offsetWidth,\n\t\t\theight: options.domNode.offsetHeight\n\t\t};\n\t}\n\tif(options.absolute && options.domNode) {\n\t\t// Walk the offsetParent chain and add the position of the offsetParents to make\n\t\t// the position absolute to the root node of the page.\n\t\tvar currentNode = options.domNode.offsetParent;\n\t\twhile(currentNode) {\n\t\t\trect.left += currentNode.offsetLeft;\n\t\t\trect.top += currentNode.offsetTop;\n\t\t\tcurrentNode = currentNode.offsetParent;\n\t\t}\n\t}\n\tvar popupRect = exports.buildCoordinates(options.absolute?exports.coordinatePrefix.csAbsolute:exports.coordinatePrefix.csOffsetParent,rect);\n\tif(options.noStateReference) {\n\t\toptions.wiki.setText(options.title,\"text\",undefined,popupRect);\n\t} else {\n\t\toptions.wiki.setTextReference(options.title,popupRect);\n\t}\n\t// Add the click handler if we have any popups\n\tif(this.popups.length > 0) {\n\t\tthis.rootElement.addEventListener(\"click\",this,true);\n\t}\n};\n\n/*\nCancel all popups at or above a specified level or DOM node\nlevel: popup level to cancel (0 cancels all popups)\n*/\nPopup.prototype.cancel = function(level) {\n\tvar numPopups = this.popups.length;\n\tlevel = Math.max(0,Math.min(level,numPopups));\n\tfor(var t=level; t<numPopups; t++) {\n\t\tvar popup = this.popups.pop();\n\t\tif(popup.title) {\n\t\t\tif(popup.noStateReference) {\n\t\t\t\tpopup.wiki.deleteTiddler(popup.title);\n\t\t\t} else {\n\t\t\t\tpopup.wiki.deleteTiddler($tw.utils.parseTextReference(popup.title).title);\n        \t\t}\n\t\t}\n\t}\n\tif(this.popups.length === 0) {\n\t\tthis.rootElement.removeEventListener(\"click\",this,false);\n\t}\n};\n\n/*\nReturns true if the specified title and text identifies an active popup.\nThis function is safe to call, even if the popup class was not initialized.\n*/\nexports.readPopupState = function(text) {\n\treturn exports.popupLocationRegExp.test(text);\n};\n\n/*\nParses a coordinate string in the format `(x,y,w,h)` or `@(x,y,z,h)` and returns\nan object containing the position, width and height. The absolute-Mark is boolean\nvalue that indicates the coordinate system of the coordinates. If they start with\nan `@`, `absolute` is set to true and the coordinates are relative to the root\nelement. If the initial `@` is missing, they are relative to the offset parent\nelement and `absoute` is false.\nThis function is safe to call, even if the popup class was not initialized.\n*/\nexports.parseCoordinates = function(coordinates) {\n\tvar match = exports.popupLocationRegExp.exec(coordinates);\n\tif(match) {\n\t\treturn {\n\t\t\tabsolute: (match[1] === \"@\"),\n\t\t\tleft: parseFloat(match[2]),\n\t\t\ttop: parseFloat(match[3]),\n\t\t\twidth: parseFloat(match[4]),\n\t\t\theight: parseFloat(match[5])\n\t\t};\n\t} else {\n\t\treturn false;\n\t}\n}\n\n/*\nBuilds a coordinate string from a coordinate system identifier and an object\ncontaining the left, top, width and height values.\nUse constants defined in coordinatePrefix to specify a coordinate system.\nIf one of the parameters is invalid for building a coordinate string `(0,0,0,0)`\nwill be returned.\nThis function is safe to call, even if the popup class was not initialized.\n*/\nexports.buildCoordinates = function(prefix,position) {\n\tvar coord = prefix + \"(\" + position.left + \",\" + position.top + \",\" + position.width + \",\" + position.height + \")\";\n\tif (exports.popupLocationRegExp.test(coord)) {\n\t\treturn coord;\n\t} else {\n\t\treturn \"(0,0,0,0)\";\n\t}\n}\n\nexports.Popup = Popup;\n\n})();\n","type":"application/javascript","module-type":"utils"},"$:/core/modules/utils/dom/scroller.js":{"title":"$:/core/modules/utils/dom/scroller.js","text":"/*\\\ntitle: $:/core/modules/utils/dom/scroller.js\ntype: application/javascript\nmodule-type: utils\n\nModule that creates a $tw.utils.Scroller object prototype that manages scrolling in the browser\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nEvent handler for when the `tm-scroll` event hits the document body\n*/\nvar PageScroller = function() {\n\tthis.idRequestFrame = null;\n\tthis.requestAnimationFrame = window.requestAnimationFrame ||\n\t\twindow.webkitRequestAnimationFrame ||\n\t\twindow.mozRequestAnimationFrame ||\n\t\tfunction(callback) {\n\t\t\treturn window.setTimeout(callback, 1000/60);\n\t\t};\n\tthis.cancelAnimationFrame = window.cancelAnimationFrame ||\n\t\twindow.webkitCancelAnimationFrame ||\n\t\twindow.webkitCancelRequestAnimationFrame ||\n\t\twindow.mozCancelAnimationFrame ||\n\t\twindow.mozCancelRequestAnimationFrame ||\n\t\tfunction(id) {\n\t\t\twindow.clearTimeout(id);\n\t\t};\n};\n\nPageScroller.prototype.isScrolling = function() {\n\treturn this.idRequestFrame !== null;\n}\n\nPageScroller.prototype.cancelScroll = function(srcWindow) {\n\tif(this.idRequestFrame) {\n\t\tthis.cancelAnimationFrame.call(srcWindow,this.idRequestFrame);\n\t\tthis.idRequestFrame = null;\n\t}\n};\n\n/*\nHandle an event\n*/\nPageScroller.prototype.handleEvent = function(event) {\n\tif(event.type === \"tm-scroll\") {\n\t\tvar options = {};\n\t\tif($tw.utils.hop(event.paramObject,\"animationDuration\")) {\n\t\t\toptions.animationDuration = event.paramObject.animationDuration;\n\t\t}\n\t\tif(event.paramObject && event.paramObject.selector) {\n\t\t\tthis.scrollSelectorIntoView(null,event.paramObject.selector,null,options);\n\t\t} else {\n\t\t\tthis.scrollIntoView(event.target,null,options);\n\t\t}\n\t\treturn false; // Event was handled\n\t}\n\treturn true;\n};\n\n/*\nHandle a scroll event hitting the page document\n*/\nPageScroller.prototype.scrollIntoView = function(element,callback,options) {\n\tvar self = this,\n\t\tduration = $tw.utils.hop(options,\"animationDuration\") ? parseInt(options.animationDuration) : $tw.utils.getAnimationDuration(),\n\t\tsrcWindow = element ? element.ownerDocument.defaultView : window;\n\t// Now get ready to scroll the body\n\tthis.cancelScroll(srcWindow);\n\tthis.startTime = Date.now();\n\t// Get the height of any position:fixed toolbars\n\tvar toolbar = srcWindow.document.querySelector(\".tc-adjust-top-of-scroll\"),\n\t\toffset = 0;\n\tif(toolbar) {\n\t\toffset = toolbar.offsetHeight;\n\t}\n\t// Get the client bounds of the element and adjust by the scroll position\n\tvar getBounds = function() {\n\t\t\tvar clientBounds = typeof callback === 'function' ? callback() : element.getBoundingClientRect(),\n\t\t\t\tscrollPosition = $tw.utils.getScrollPosition(srcWindow);\n\t\t\treturn {\n\t\t\t\tleft: clientBounds.left + scrollPosition.x,\n\t\t\t\ttop: clientBounds.top + scrollPosition.y - offset,\n\t\t\t\twidth: clientBounds.width,\n\t\t\t\theight: clientBounds.height\n\t\t\t};\n\t\t},\n\t\t// We'll consider the horizontal and vertical scroll directions separately via this function\n\t\t// targetPos/targetSize - position and size of the target element\n\t\t// currentPos/currentSize - position and size of the current scroll viewport\n\t\t// returns: new position of the scroll viewport\n\t\tgetEndPos = function(targetPos,targetSize,currentPos,currentSize) {\n\t\t\tvar newPos = targetPos;\n\t\t\t// If we are scrolling within 50 pixels of the top/left then snap to zero\n\t\t\tif(newPos < 50) {\n\t\t\t\tnewPos = 0;\n\t\t\t}\n\t\t\treturn newPos;\n\t\t},\n\t\tdrawFrame = function drawFrame() {\n\t\t\tvar t;\n\t\t\tif(duration <= 0) {\n\t\t\t\tt = 1;\n\t\t\t} else {\n\t\t\t\tt = ((Date.now()) - self.startTime) / duration;\n\t\t\t}\n\t\t\tif(t >= 1) {\n\t\t\t\tself.cancelScroll(srcWindow);\n\t\t\t\tt = 1;\n\t\t\t}\n\t\t\tt = $tw.utils.slowInSlowOut(t);\n\t\t\tvar scrollPosition = $tw.utils.getScrollPosition(srcWindow),\n\t\t\t\tbounds = getBounds(),\n\t\t\t\tendX = getEndPos(bounds.left,bounds.width,scrollPosition.x,srcWindow.innerWidth),\n\t\t\t\tendY = getEndPos(bounds.top,bounds.height,scrollPosition.y,srcWindow.innerHeight);\n\t\t\tsrcWindow.scrollTo(scrollPosition.x + (endX - scrollPosition.x) * t,scrollPosition.y + (endY - scrollPosition.y) * t);\n\t\t\tif(t < 1) {\n\t\t\t\tself.idRequestFrame = self.requestAnimationFrame.call(srcWindow,drawFrame);\n\t\t\t}\n\t\t};\n\tdrawFrame();\n};\n\nPageScroller.prototype.scrollSelectorIntoView = function(baseElement,selector,callback,options) {\n\tbaseElement = baseElement || document;\n\tvar element = $tw.utils.querySelectorSafe(selector,baseElement);\n\tif(element) {\n\t\tthis.scrollIntoView(element,callback,options);\n\t}\n};\n\nexports.PageScroller = PageScroller;\n\n})();\n","type":"application/javascript","module-type":"utils"},"$:/core/modules/utils/edition-info.js":{"title":"$:/core/modules/utils/edition-info.js","text":"/*\\\ntitle: $:/core/modules/utils/edition-info.js\ntype: application/javascript\nmodule-type: utils-node\n\nInformation about the available editions\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar fs = require(\"fs\"),\n\tpath = require(\"path\");\n\nvar editionInfo;\n\nexports.getEditionInfo = function() {\n\tif(!editionInfo) {\n\t\t// Enumerate the edition paths\n\t\tvar editionPaths = $tw.getLibraryItemSearchPaths($tw.config.editionsPath,$tw.config.editionsEnvVar);\n\t\teditionInfo = {};\n\t\tfor(var editionIndex=0; editionIndex<editionPaths.length; editionIndex++) {\n\t\t\tvar editionPath = editionPaths[editionIndex];\n\t\t\t// Enumerate the folders\n\t\t\tvar entries = fs.readdirSync(editionPath);\n\t\t\tfor(var entryIndex=0; entryIndex<entries.length; entryIndex++) {\n\t\t\t\tvar entry = entries[entryIndex];\n\t\t\t\t// Check if directories have a valid tiddlywiki.info\n\t\t\t\t// Check if the entry is a hidden directory\n\t\t\t\tif((entry.charAt(0) !== \".\") && !editionInfo[entry] && $tw.utils.isDirectory(path.resolve(editionPath,entry))) {\n\t\t\t\t\tvar file=path.resolve(editionPath,entry,\"tiddlywiki.info\");\n\t\t\t\t\tif(fs.existsSync(file)) {\n\t\t\t\t\t\tvar info = $tw.utils.parseJSONSafe(fs.readFileSync(file,\"utf8\"),null);\n\t\t\t\t\t\tif(info) {\n\t\t\t\t\t\t\teditionInfo[entry] = info;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn editionInfo;\n};\n\n})();","type":"application/javascript","module-type":"utils-node"},"$:/core/modules/utils/errors.js":{"title":"$:/core/modules/utils/errors.js","text":"/*\\\ntitle: $:/core/modules/utils/errors.js\ntype: application/javascript\nmodule-type: utils\n\nCustom errors for TiddlyWiki.\n\n\\*/\n(function(){\n\nfunction TranscludeRecursionError() {\n\tError.apply(this,arguments);\n\tthis.signatures = Object.create(null);\n};\n\n/* Maximum permitted depth of the widget tree for recursion detection */\nTranscludeRecursionError.MAX_WIDGET_TREE_DEPTH = 1000;\n\nTranscludeRecursionError.prototype = Object.create(Error);\n\nexports.TranscludeRecursionError = TranscludeRecursionError;\n\n})();\n","type":"application/javascript","module-type":"utils"},"$:/core/modules/utils/escapecss.js":{"title":"$:/core/modules/utils/escapecss.js","text":"/*\\\ntitle: $:/core/modules/utils/escapecss.js\ntype: application/javascript\nmodule-type: utils\n\nProvides CSS.escape() functionality.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false, window: false */\n\"use strict\";\n\nexports.escapeCSS = (function() {\n\t// use browser's native CSS.escape() function if available\n\tif ($tw.browser && window.CSS && window.CSS.escape) {\n\t\treturn window.CSS.escape;\n\t}\n\n\t// otherwise, a utility method is provided\n\t// see also https://drafts.csswg.org/cssom/#serialize-an-identifier\n\n\t/*! https://mths.be/cssescape v1.5.1 by @mathias | MIT license */\n\treturn function(value) {\n\t\tif (arguments.length == 0) {\n\t\t\tthrow new TypeError('`CSS.escape` requires an argument.');\n\t\t}\n\t\tvar string = String(value);\n\t\tvar length = string.length;\n\t\tvar index = -1;\n\t\tvar codeUnit;\n\t\tvar result = '';\n\t\tvar firstCodeUnit = string.charCodeAt(0);\n\t\twhile (++index < length) {\n\t\t\tcodeUnit = string.charCodeAt(index);\n\t\t\t// Note: there’s no need to special-case astral symbols, surrogate\n\t\t\t// pairs, or lone surrogates.\n\n\t\t\t// If the character is NULL (U+0000), then the REPLACEMENT CHARACTER\n\t\t\t// (U+FFFD).\n\t\t\tif (codeUnit == 0x0000) {\n\t\t\t\tresult += '\\uFFFD';\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\t// If the character is in the range [\\1-\\1F] (U+0001 to U+001F) or is\n\t\t\t\t// U+007F, […]\n\t\t\t\t(codeUnit >= 0x0001 && codeUnit <= 0x001F) || codeUnit == 0x007F ||\n\t\t\t\t// If the character is the first character and is in the range [0-9]\n\t\t\t\t// (U+0030 to U+0039), […]\n\t\t\t\t(index == 0 && codeUnit >= 0x0030 && codeUnit <= 0x0039) ||\n\t\t\t\t// If the character is the second character and is in the range [0-9]\n\t\t\t\t// (U+0030 to U+0039) and the first character is a `-` (U+002D), […]\n\t\t\t\t(\n\t\t\t\t\tindex == 1 &&\n\t\t\t\t\tcodeUnit >= 0x0030 && codeUnit <= 0x0039 &&\n\t\t\t\t\tfirstCodeUnit == 0x002D\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\t// https://drafts.csswg.org/cssom/#escape-a-character-as-code-point\n\t\t\t\tresult += '\\\\' + codeUnit.toString(16) + ' ';\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\t// If the character is the first character and is a `-` (U+002D), and\n\t\t\t\t// there is no second character, […]\n\t\t\t\tindex == 0 &&\n\t\t\t\tlength == 1 &&\n\t\t\t\tcodeUnit == 0x002D\n\t\t\t) {\n\t\t\t\tresult += '\\\\' + string.charAt(index);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If the character is not handled by one of the above rules and is\n\t\t\t// greater than or equal to U+0080, is `-` (U+002D) or `_` (U+005F), or\n\t\t\t// is in one of the ranges [0-9] (U+0030 to U+0039), [A-Z] (U+0041 to\n\t\t\t// U+005A), or [a-z] (U+0061 to U+007A), […]\n\t\t\tif (\n\t\t\t\tcodeUnit >= 0x0080 ||\n\t\t\t\tcodeUnit == 0x002D ||\n\t\t\t\tcodeUnit == 0x005F ||\n\t\t\t\tcodeUnit >= 0x0030 && codeUnit <= 0x0039 ||\n\t\t\t\tcodeUnit >= 0x0041 && codeUnit <= 0x005A ||\n\t\t\t\tcodeUnit >= 0x0061 && codeUnit <= 0x007A\n\t\t\t) {\n\t\t\t\t// the character itself\n\t\t\t\tresult += string.charAt(index);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Otherwise, the escaped character.\n\t\t\t// https://drafts.csswg.org/cssom/#escape-a-character\n\t\t\tresult += '\\\\' + string.charAt(index);\n\n\t\t}\n\t\treturn result;\n\t};\n})();\n\n})();\n","type":"application/javascript","module-type":"utils"},"$:/core/modules/utils/fakedom.js":{"title":"$:/core/modules/utils/fakedom.js","text":"/*\\\ntitle: $:/core/modules/utils/fakedom.js\ntype: application/javascript\nmodule-type: global\n\nA barebones implementation of DOM interfaces needed by the rendering mechanism.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Sequence number used to enable us to track objects for testing\nvar sequenceNumber = null;\n\nvar bumpSequenceNumber = function(object) {\n\tif(sequenceNumber !== null) {\n\t\tobject.sequenceNumber = sequenceNumber++;\n\t}\n};\n\nvar TW_Node = function (){\n\tthrow TypeError(\"Illegal constructor\");\n};\n\nObject.defineProperty(TW_Node.prototype, 'ELEMENT_NODE', {\n\tget: function() {\n\t\treturn 1;\n\t}\n});\n\nObject.defineProperty(TW_Node.prototype, 'TEXT_NODE', {\n\tget: function() {\n\t\treturn 3;\n\t}\n});\n\nvar TW_TextNode = function(text) {\n\tbumpSequenceNumber(this);\n\tthis.textContent = text + \"\";\n};\n\nObject.setPrototypeOf(TW_TextNode.prototype,TW_Node.prototype);\n\nObject.defineProperty(TW_TextNode.prototype, \"nodeType\", {\n\tget: function() {\n\t\treturn this.TEXT_NODE;\n\t}\n});\n\nObject.defineProperty(TW_TextNode.prototype, \"formattedTextContent\", {\n\tget: function() {\n\t\treturn this.textContent.replace(/(\\r?\\n)/g,\"\");\n\t}\n});\n\nvar TW_Style = function(el) {\n\t// Define the internal style object\n\tvar styleObject = {\n\t\t// Method to get the entire style object\n\t\tget: function() {\n\t\t\treturn el._style;\n\t\t},\n\t\t// Method to set styles using a string (e.g. \"color:red; background-color:blue;\")\n\t\tset: function(str) {\n\t\t\tvar self = this;\n\t\t\tstr = str || \"\";\n\t\t\t$tw.utils.each(str.split(\";\"),function(declaration) {\n\t\t\t\tvar parts = declaration.split(\":\"),\n\t\t\t\t\tname = $tw.utils.trim(parts[0]),\n\t\t\t\t\tvalue = $tw.utils.trim(parts[1]);\n\t\t\t\tif(name && value) {\n\t\t\t\t\tel._style[$tw.utils.convertStyleNameToPropertyName(name)] = value;\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\t\t// Method to set a specific property without transforming the property name, such as a custom property\n\t\tsetProperty: function(name, value) {\n\t\t\tel._style[name] = value;\n\t\t}\n\t};\n\n\t// Return a Proxy to handle direct access to individual style properties\n\treturn new Proxy(styleObject, {\n\t\tget: function(target, property) {\n\t\t\t// If the property exists on styleObject, return it (get, set, setProperty methods)\n\t\t\tif (property in target) {\n\t\t\t\treturn target[property];\n\t\t\t}\n\t\t\t// Otherwise, return the corresponding property from _style\n\t\t\treturn el._style[$tw.utils.convertStyleNameToPropertyName(property)] || \"\";\n\t\t},\n\t\tset: function(target, property, value) {\n\t\t\t// Set the property in _style\n\t\t\tel._style[$tw.utils.convertStyleNameToPropertyName(property)] = value;\n\t\t\treturn true;\n\t\t}\n\t});\n};\n\nvar TW_Element = function(tag, namespace) {\n\tbumpSequenceNumber(this);\n\tthis.isTiddlyWikiFakeDom = true;\n\tthis.tag = tag;\n\tthis.attributes = {};\n\tthis.isRaw = false;\n\tthis.children = [];\n\tthis._style = {}; // Internal style object\n\tthis.style = new TW_Style(this); // Proxy for style management\n\tthis.namespaceURI = namespace || \"http://www.w3.org/1999/xhtml\";\n};\n\n\nObject.setPrototypeOf(TW_Element.prototype,TW_Node.prototype);\n\nObject.defineProperty(TW_Element.prototype, \"nodeType\", {\n\tget: function() {\n\t\treturn this.ELEMENT_NODE;\n\t}\n});\n\nTW_Element.prototype.getAttribute = function(name) {\n\tif(this.isRaw) {\n\t\tthrow \"Cannot getAttribute on a raw TW_Element\";\n\t}\n\treturn this.attributes[name];\n};\n\nTW_Element.prototype.setAttribute = function(name,value) {\n\tif(this.isRaw) {\n\t\tthrow \"Cannot setAttribute on a raw TW_Element\";\n\t}\n\tif(name === \"style\") {\n\t\tthis.style.set(value);\n\t} else {\n\t\tthis.attributes[name] = value + \"\";\n\t}\n};\n\nTW_Element.prototype.setAttributeNS = function(namespace,name,value) {\n\tthis.setAttribute(name,value);\n};\n\nTW_Element.prototype.removeAttribute = function(name) {\n\tif(this.isRaw) {\n\t\tthrow \"Cannot removeAttribute on a raw TW_Element\";\n\t}\n\tif($tw.utils.hop(this.attributes,name)) {\n\t\tdelete this.attributes[name];\n\t}\n};\n\nTW_Element.prototype.appendChild = function(node) {\n\tthis.children.push(node);\n\tnode.parentNode = this;\n};\n\nTW_Element.prototype.insertBefore = function(node,nextSibling) {\n\tif(nextSibling) {\n\t\tvar p = this.children.indexOf(nextSibling);\n\t\tif(p !== -1) {\n\t\t\tthis.children.splice(p,0,node);\n\t\t\tnode.parentNode = this;\n\t\t} else {\n\t\t\tthis.appendChild(node);\n\t\t}\n\t} else {\n\t\tthis.appendChild(node);\n\t}\n};\n\nTW_Element.prototype.removeChild = function(node) {\n\tvar p = this.children.indexOf(node);\n\tif(p !== -1) {\n\t\tthis.children.splice(p,1);\n\t}\n};\n\nTW_Element.prototype.hasChildNodes = function() {\n\treturn !!this.children.length;\n};\n\nObject.defineProperty(TW_Element.prototype, \"childNodes\", {\n\tget: function() {\n\t\treturn this.children;\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"firstChild\", {\n\tget: function() {\n\t\treturn this.children[0];\n\t}\n});\n\nTW_Element.prototype.addEventListener = function(type,listener,useCapture) {\n\t// Do nothing\n};\n\nObject.defineProperty(TW_Element.prototype, \"tagName\", {\n\tget: function() {\n\t\treturn this.tag || \"\";\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"className\", {\n\tget: function() {\n\t\treturn this.attributes[\"class\"] || \"\";\n\t},\n\tset: function(value) {\n\t\tthis.attributes[\"class\"] = value + \"\";\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"value\", {\n\tget: function() {\n\t\treturn this.attributes.value || \"\";\n\t},\n\tset: function(value) {\n\t\tthis.attributes.value = value + \"\";\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"outerHTML\", {\n\tget: function() {\n\t\tvar output = [],attr,a,v;\n\t\toutput.push(\"<\",this.tag);\n\t\tif(this.attributes) {\n\t\t\tattr = [];\n\t\t\tfor(a in this.attributes) {\n\t\t\t\tattr.push(a);\n\t\t\t}\n\t\t\tattr.sort();\n\t\t\tfor(a=0; a<attr.length; a++) {\n\t\t\t\tv = this.attributes[attr[a]];\n\t\t\t\tif(v !== undefined) {\n\t\t\t\t\toutput.push(\" \",attr[a],\"=\\\"\",$tw.utils.htmlEncode(v),\"\\\"\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif(this._style) {\n\t\t\tvar style = [];\n\t\t\tfor(var s in this._style) {\n\t\t\t\tstyle.push($tw.utils.convertPropertyNameToStyleName(s) + \":\" + this._style[s] + \";\");\n\t\t\t}\n\t\t\tif(style.length > 0) {\n\t\t\t\toutput.push(\" style=\\\"\",style.join(\"\"),\"\\\"\");\n\t\t\t}\n\t\t}\n\t\toutput.push(\">\");\n\t\tif($tw.config.htmlVoidElements.indexOf(this.tag) === -1) {\n\t\t\toutput.push(this.innerHTML);\n\t\t\toutput.push(\"</\",this.tag,\">\");\n\t\t}\n\t\treturn output.join(\"\");\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"innerHTML\", {\n\tget: function() {\n\t\tif(this.isRaw) {\n\t\t\treturn this.rawHTML;\n\t\t} else {\n\t\t\tvar b = [];\n\t\t\t$tw.utils.each(this.children,function(node) {\n\t\t\t\tif(node instanceof TW_Element) {\n\t\t\t\t\tb.push(node.outerHTML);\n\t\t\t\t} else if(node instanceof TW_TextNode) {\n\t\t\t\t\tb.push($tw.utils.htmlTextEncode(node.textContent));\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn b.join(\"\");\n\t\t}\n\t},\n\tset: function(value) {\n\t\tthis.isRaw = true;\n\t\tthis.rawHTML = value;\n\t\tthis.rawTextContent = null;\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"textInnerHTML\", {\n\tset: function(value) {\n\t\tif(this.isRaw) {\n\t\t\tthis.rawTextContent = value;\n\t\t} else {\n\t\t\tthrow \"Cannot set textInnerHTML of a non-raw TW_Element\";\n\t\t}\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"textContent\", {\n\tget: function() {\n\t\tif(this.isRaw) {\n\t\t\tif(this.rawTextContent === null) {\n\t\t\t\treturn \"\";\n\t\t\t} else {\n\t\t\t\treturn this.rawTextContent;\n\t\t\t}\n\t\t} else {\n\t\t\tvar b = [];\n\t\t\t$tw.utils.each(this.children,function(node) {\n\t\t\t\tb.push(node.textContent);\n\t\t\t});\n\t\t\treturn b.join(\"\");\n\t\t}\n\t},\n\tset: function(value) {\n\t\tthis.children = [new TW_TextNode(value)];\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"formattedTextContent\", {\n\tget: function() {\n\t\tif(this.isRaw) {\n\t\t\treturn \"\";\n\t\t} else {\n\t\t\tvar b = [],\n\t\t\t\tisBlock = $tw.config.htmlBlockElements.indexOf(this.tag) !== -1;\n\t\t\tif(isBlock) {\n\t\t\t\tb.push(\"\\n\");\n\t\t\t}\n\t\t\tif(this.tag === \"li\") {\n\t\t\t\tb.push(\"* \");\n\t\t\t}\n\t\t\t$tw.utils.each(this.children,function(node) {\n\t\t\t\tb.push(node.formattedTextContent);\n\t\t\t});\n\t\t\tif(isBlock) {\n\t\t\t\tb.push(\"\\n\");\n\t\t\t}\n\t\t\treturn b.join(\"\");\n\t\t}\n\t}\n});\n\nvar document = {\n\tsetSequenceNumber: function(value) {\n\t\tsequenceNumber = value;\n\t},\n\tcreateElementNS: function(namespace,tag) {\n\t\treturn new TW_Element(tag,namespace);\n\t},\n\tcreateElement: function(tag) {\n\t\treturn new TW_Element(tag);\n\t},\n\tcreateTextNode: function(text) {\n\t\treturn new TW_TextNode(text);\n\t},\n\tcompatMode: \"CSS1Compat\", // For KaTeX to know that we're not a browser in quirks mode\n\tisTiddlyWikiFakeDom: true\n};\n\nexports.fakeDocument = document;\n\n})();\n","type":"application/javascript","module-type":"global"},"$:/core/modules/utils/filesystem.js":{"title":"$:/core/modules/utils/filesystem.js","text":"/*\\\ntitle: $:/core/modules/utils/filesystem.js\ntype: application/javascript\nmodule-type: utils-node\n\nFile system utilities\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar fs = require(\"fs\"),\n\tpath = require(\"path\");\n\n/*\nReturn the subdirectories of a path\n*/\nexports.getSubdirectories = function(dirPath) {\n\tif(!$tw.utils.isDirectory(dirPath)) {\n\t\treturn null;\n\t}\n\tvar subdirs = [];\n\t$tw.utils.each(fs.readdirSync(dirPath),function(item) {\n\t\tif($tw.utils.isDirectory(path.resolve(dirPath,item))) {\n\t\t\tsubdirs.push(item);\n\t\t}\n\t});\n\treturn subdirs;\n}\n\n/*\nRecursively (and synchronously) copy a directory and all its content\n*/\nexports.copyDirectory = function(srcPath,dstPath) {\n\t// Remove any trailing path separators\n\tsrcPath = path.resolve($tw.utils.removeTrailingSeparator(srcPath));\n\tdstPath = path.resolve($tw.utils.removeTrailingSeparator(dstPath));\n\t// Check that neither director is within the other\n\tif(srcPath.substring(0,dstPath.length) === dstPath || dstPath.substring(0,srcPath.length) === srcPath) {\n\t\treturn \"Cannot copy nested directories\";\n\t}\n\t// Create the destination directory\n\tvar err = $tw.utils.createDirectory(dstPath);\n\tif(err) {\n\t\treturn err;\n\t}\n\t// Function to copy a folder full of files\n\tvar copy = function(srcPath,dstPath) {\n\t\tvar srcStats = fs.lstatSync(srcPath),\n\t\t\tdstExists = fs.existsSync(dstPath);\n\t\tif(srcStats.isFile()) {\n\t\t\t$tw.utils.copyFile(srcPath,dstPath);\n\t\t} else if(srcStats.isDirectory()) {\n\t\t\tvar items = fs.readdirSync(srcPath);\n\t\t\tfor(var t=0; t<items.length; t++) {\n\t\t\t\tvar item = items[t],\n\t\t\t\t\terr = copy(srcPath + path.sep + item,dstPath + path.sep + item);\n\t\t\t\tif(err) {\n\t\t\t\t\treturn err;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\tcopy(srcPath,dstPath);\n\treturn null;\n};\n\n/*\nCopy a file\n*/\nvar FILE_BUFFER_LENGTH = 64 * 1024,\n\tfileBuffer;\n\nexports.copyFile = function(srcPath,dstPath) {\n\t// Create buffer if required\n\tif(!fileBuffer) {\n\t\tfileBuffer = Buffer.alloc(FILE_BUFFER_LENGTH);\n\t}\n\t// Create any directories in the destination\n\t$tw.utils.createDirectory(path.dirname(dstPath));\n\t// Copy the file\n\tvar srcFile = fs.openSync(srcPath,\"r\"),\n\t\tdstFile = fs.openSync(dstPath,\"w\"),\n\t\tbytesRead = 1,\n\t\tpos = 0;\n\twhile (bytesRead > 0) {\n\t\tbytesRead = fs.readSync(srcFile,fileBuffer,0,FILE_BUFFER_LENGTH,pos);\n\t\tfs.writeSync(dstFile,fileBuffer,0,bytesRead);\n\t\tpos += bytesRead;\n\t}\n\tfs.closeSync(srcFile);\n\tfs.closeSync(dstFile);\n\treturn null;\n};\n\n/*\nRemove trailing path separator\n*/\nexports.removeTrailingSeparator = function(dirPath) {\n\tvar len = dirPath.length;\n\tif(dirPath.charAt(len-1) === path.sep) {\n\t\tdirPath = dirPath.substr(0,len-1);\n\t}\n\treturn dirPath;\n};\n\n/*\nRecursively create a directory\n*/\nexports.createDirectory = function(dirPath) {\n\tif(dirPath.substr(dirPath.length-1,1) !== path.sep) {\n\t\tdirPath = dirPath + path.sep;\n\t}\n\tvar pos = 1;\n\tpos = dirPath.indexOf(path.sep,pos);\n\twhile(pos !== -1) {\n\t\tvar subDirPath = dirPath.substr(0,pos);\n\t\tif(!$tw.utils.isDirectory(subDirPath)) {\n\t\t\ttry {\n\t\t\t\tfs.mkdirSync(subDirPath);\n\t\t\t} catch(e) {\n\t\t\t\treturn \"Error creating directory '\" + subDirPath + \"'\";\n\t\t\t}\n\t\t}\n\t\tpos = dirPath.indexOf(path.sep,pos + 1);\n\t}\n\treturn null;\n};\n\n/*\nRecursively create directories needed to contain a specified file\n*/\nexports.createFileDirectories = function(filePath) {\n\treturn $tw.utils.createDirectory(path.dirname(filePath));\n};\n\n/*\nRecursively delete a directory\n*/\nexports.deleteDirectory = function(dirPath) {\n\tif(fs.existsSync(dirPath)) {\n\t\tvar entries = fs.readdirSync(dirPath);\n\t\tfor(var entryIndex=0; entryIndex<entries.length; entryIndex++) {\n\t\t\tvar currPath = dirPath + path.sep + entries[entryIndex];\n\t\t\tif(fs.lstatSync(currPath).isDirectory()) {\n\t\t\t\t$tw.utils.deleteDirectory(currPath);\n\t\t\t} else {\n\t\t\t\tfs.unlinkSync(currPath);\n\t\t\t}\n\t\t}\n\tfs.rmdirSync(dirPath);\n\t}\n\treturn null;\n};\n\n/*\nCheck if a path identifies a directory\n*/\nexports.isDirectory = function(dirPath) {\n\treturn fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory();\n};\n\n/*\nCheck if a path identifies a directory that is empty\n*/\nexports.isDirectoryEmpty = function(dirPath) {\n\tif(!$tw.utils.isDirectory(dirPath)) {\n\t\treturn false;\n\t}\n\tvar files = fs.readdirSync(dirPath),\n\t\tempty = true;\n\t$tw.utils.each(files,function(file,index) {\n\t\tif(file.charAt(0) !== \".\") {\n\t\t\tempty = false;\n\t\t}\n\t});\n\treturn empty;\n};\n\n/*\nRecursively delete a tree of empty directories\n*/\nexports.deleteEmptyDirs = function(dirpath,callback) {\n\tvar self = this;\n\tfs.readdir(dirpath,function(err,files) {\n\t\tif(err) {\n\t\t\treturn callback(err);\n\t\t}\n\t\tif(files.length > 0) {\n\t\t\treturn callback(null);\n\t\t}\n\t\tfs.rmdir(dirpath,function(err) {\n\t\t\tif(err) {\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\tself.deleteEmptyDirs(path.dirname(dirpath),callback);\n\t\t});\n\t});\n};\n\n/*\nCreate a fileInfo object for saving a tiddler:\n\tfilepath: the absolute path to the file containing the tiddler\n\ttype: the type of the tiddler file on disk (NOT the type of the tiddler)\n\thasMetaFile: true if the file also has a companion .meta file\n\tisEditableFile: true if the tiddler was loaded via non-standard options & marked editable\nOptions include:\n\tdirectory: absolute path of root directory to which we are saving\n\tpathFilters: optional array of filters to be used to generate the base path\n\textFilters: optional array of filters to be used to generate the base path\n\twiki: optional wiki for evaluating the pathFilters,\n\tfileInfo: an existing fileInfo to check against\n*/\nexports.generateTiddlerFileInfo = function(tiddler,options) {\n\tvar fileInfo = {}, metaExt;\n\t// Propagate the isEditableFile flag\n\tif(options.fileInfo && !!options.fileInfo.isEditableFile) {\n\t\tfileInfo.isEditableFile = true;\n\t\tfileInfo.originalpath = options.fileInfo.originalpath;\n\t}\n\t// Check if the tiddler has any unsafe fields that can't be expressed in a .tid or .meta file: containing control characters, or leading/trailing whitespace\n\tvar hasUnsafeFields = false;\n\t$tw.utils.each(tiddler.getFieldStrings(),function(value,fieldName) {\n\t\tif(fieldName !== \"text\") {\n\t\t\thasUnsafeFields = hasUnsafeFields || /[\\x00-\\x1F]/mg.test(value);\n\t\t\thasUnsafeFields = hasUnsafeFields || ($tw.utils.trim(value) !== value);\n\t\t}\n\t\thasUnsafeFields = hasUnsafeFields || /:|#/mg.test(fieldName);\n\t});\n\t// Check for field values \n\tif(hasUnsafeFields) {\n\t\t// Save as a JSON file\n\t\tfileInfo.type = \"application/json\";\n\t\tfileInfo.hasMetaFile = false;\n\t} else {\n\t\t// Save as a .tid or a text/binary file plus a .meta file\n\t\tvar tiddlerType = tiddler.fields.type || \"text/vnd.tiddlywiki\";\n\t\tif(tiddlerType === \"text/vnd.tiddlywiki\" || tiddlerType === \"text/vnd.tiddlywiki-multiple\" || tiddler.hasField(\"_canonical_uri\")) {\n\t\t\t// Save as a .tid file\n\t\t\tfileInfo.type = \"application/x-tiddler\";\n\t\t\tfileInfo.hasMetaFile = false;\n\t\t} else {\n\t\t\t// Save as a text/binary file and a .meta file\n\t\t\tfileInfo.type = tiddlerType;\n\t\t\tfileInfo.hasMetaFile = true;\n\t\t}\n\t\tif(options.extFilters) {\n\t\t\t// Check for extension overrides\n\t\t\tmetaExt = $tw.utils.generateTiddlerExtension(tiddler.fields.title,{\n\t\t\t\textFilters: options.extFilters,\n\t\t\t\twiki: options.wiki\n\t\t\t});\n\t\t\tif(metaExt) {\n\t\t\t\tif(metaExt === \".tid\") {\n\t\t\t\t\t// Overriding to the .tid extension needs special handling\n\t\t\t\t\tfileInfo.type = \"application/x-tiddler\";\n\t\t\t\t\tfileInfo.hasMetaFile = false;\n\t\t\t\t} else if (metaExt === \".json\") {\n\t\t\t\t\t// Overriding to the .json extension needs special handling\n\t\t\t\t\tfileInfo.type = \"application/json\";\n\t\t\t\t\tfileInfo.hasMetaFile = false;\n\t\t\t\t} else {\n\t\t\t\t\t//If the new type matches a known extention, use that MIME type's encoding\n\t\t\t\t\tvar extInfo = $tw.utils.getFileExtensionInfo(metaExt);\n\t\t\t\t\tfileInfo.type = extInfo ? extInfo.type : null;\n\t\t\t\t\tfileInfo.encoding = $tw.utils.getTypeEncoding(metaExt);\n\t\t\t\t\tfileInfo.hasMetaFile = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t// Take the file extension from the tiddler content type or metaExt\n\tvar contentTypeInfo = $tw.config.contentTypeInfo[fileInfo.type] || {extension: \"\"};\n\t// Generate the filepath\n\tfileInfo.filepath = $tw.utils.generateTiddlerFilepath(tiddler.fields.title,{\n\t\textension: metaExt || contentTypeInfo.extension,\n\t\tdirectory: options.directory,\n\t\tpathFilters: options.pathFilters,\n\t\twiki: options.wiki,\n\t\tfileInfo: options.fileInfo\n\t});\n\treturn fileInfo;\n};\n\n/*\nGenerate the file extension for saving a tiddler\nOptions include:\n\textFilters: optional array of filters to be used to generate the extention\n\twiki: optional wiki for evaluating the extFilters\n*/\nexports.generateTiddlerExtension = function(title,options) {\n\tvar extension;\n\t// Check if any of the extFilters applies\n\tif(options.extFilters && options.wiki) { \n\t\t$tw.utils.each(options.extFilters,function(filter) {\n\t\t\tif(!extension) {\n\t\t\t\tvar source = options.wiki.makeTiddlerIterator([title]),\n\t\t\t\t\tresult = options.wiki.filterTiddlers(filter,null,source);\n\t\t\t\tif(result.length > 0) {\n\t\t\t\t\textension = result[0];\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\treturn extension;\n};\n\n/*\nGenerate the filepath for saving a tiddler\nOptions include:\n\textension: file extension to be added the finished filepath\n\tdirectory: absolute path of root directory to which we are saving\n\tpathFilters: optional array of filters to be used to generate the base path\n\twiki: optional wiki for evaluating the pathFilters\n\tfileInfo: an existing fileInfo object to check against\n\tfileInfo.overwrite: if true, turns off filename clash numbers (defaults to false)\n*/\nexports.generateTiddlerFilepath = function(title,options) {\n\tvar directory = options.directory || \"\",\n\t\textension = options.extension || \"\",\n\t\toriginalpath = (options.fileInfo && options.fileInfo.originalpath) ? options.fileInfo.originalpath : \"\",\n\t\toverwrite = options.fileInfo && options.fileInfo.overwrite || false,\n\t\tfilepath;\n\t// Check if any of the pathFilters applies\n\tif(options.pathFilters && options.wiki) {\n\t\t$tw.utils.each(options.pathFilters,function(filter) {\n\t\t\tif(!filepath) {\n\t\t\t\tvar source = options.wiki.makeTiddlerIterator([title]),\n\t\t\t\t\tresult = options.wiki.filterTiddlers(filter,null,source);\n\t\t\t\tif(result.length > 0) {\n\t\t\t\t\tfilepath = result[0];\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\tif(!filepath && !!originalpath) {\n\t\t//Use the originalpath without the extension\n\t\tvar ext = path.extname(originalpath);\n\t\tfilepath = originalpath.substring(0,originalpath.length - ext.length);\n\t} else if(!filepath) {\n\t\tfilepath = title;\n\t\t// Remove any forward or backward slashes so we don't create directories\n\t\tfilepath = filepath.replace(/\\/|\\\\/g,\"_\");\n\t}\n\t// Replace any Windows control codes\n\tfilepath = filepath.replace(/^(con|prn|aux|nul|com[0-9]|lpt[0-9])$/i,\"_$1_\");\n\t// Replace any leading spaces with the same number of underscores\n\tfilepath = filepath.replace(/^ +/,function (u) { return u.replace(/ /g, \"_\")});\n\t//If the path does not start with \".\" or \"..\" && a path seperator, then\n\tif(!/^\\.{1,2}[/\\\\]/g.test(filepath)) {\n\t\t// Don't let the filename start with any dots because such files are invisible on *nix\n\t\tfilepath = filepath.replace(/^\\.+/g,function (u) { return u.replace(/\\./g, \"_\")});\n\t}\n\t// Replace any Unicode control codes\n\tfilepath = filepath.replace(/[\\x00-\\x1f\\x80-\\x9f]/g,\"_\");\n\t// Replace any characters that can't be used in cross-platform filenames\n\tfilepath = $tw.utils.transliterate(filepath.replace(/<|>|~|\\:|\\\"|\\||\\?|\\*|\\^/g,\"_\"));\n\t// Replace any dots or spaces at the end of the extension with the same number of underscores\n\textension = extension.replace(/[\\. ]+$/, function (u) { return u.replace(/[\\. ]/g, \"_\")});\n\t// Truncate the extension if it is too long\n\tif(extension.length > 32) {\n\t\textension = extension.substr(0,32);\n\t}\n\t// If the filepath already ends in the extension then remove it\n\tif(filepath.substring(filepath.length - extension.length) === extension) {\n\t\tfilepath = filepath.substring(0,filepath.length - extension.length);\n\t}\n\t// Truncate the filename if it is too long\n\tif(filepath.length > 200) {\n\t\tfilepath = filepath.substr(0,200);\n\t}\n\t// If the resulting filename is blank (eg because the title is just punctuation)\n\tif(!filepath || /^_+$/g.test(filepath)) {\n\t\t// ...then just use the character codes of the title\n\t\tfilepath = \"\";\n\t\t$tw.utils.each(title.split(\"\"),function(char) {\n\t\t\tif(filepath) {\n\t\t\t\tfilepath += \"-\";\n\t\t\t}\n\t\t\tfilepath += char.charCodeAt(0).toString();\n\t\t});\n\t}\n\t// Add a uniquifier if the file already exists (default)\n\tvar fullPath = path.resolve(directory, filepath + extension);\n\tif (!overwrite) {\n\t\tvar oldPath = (options.fileInfo) ? options.fileInfo.filepath : undefined,\n\t\tcount = 0;\n\t\tdo {\n\t\t\tfullPath = path.resolve(directory,filepath + (count ? \"_\" + count : \"\") + extension);\n\t\t\tif(oldPath && oldPath == fullPath) break;\n\t\t\tcount++;\n\t\t} while(fs.existsSync(fullPath));\n\t}\n\t// If the last write failed with an error, or if path does not start with:\n\t//\tthe resolved options.directory, the resolved wikiPath directory, the wikiTiddlersPath directory, \n\t//\tor the 'originalpath' directory, then $tw.utils.encodeURIComponentExtended() and resolve to options.directory.\n\tvar writePath = $tw.hooks.invokeHook(\"th-make-tiddler-path\",fullPath,fullPath),\n\t\tencode = (options.fileInfo || {writeError: false}).writeError == true;\n\tif(!encode) {\n\t\tencode = !(writePath.indexOf($tw.boot.wikiTiddlersPath) == 0 ||\n\t\t\twritePath.indexOf(path.resolve(directory)) == 0 ||\n\t\t\twritePath.indexOf(path.resolve($tw.boot.wikiPath)) == 0 ||\n\t\t\twritePath.indexOf(path.resolve($tw.boot.wikiTiddlersPath,originalpath)) == 0 );\n\t\t}\n\tif(encode) {\n\t\twritePath = path.resolve(directory,$tw.utils.encodeURIComponentExtended(fullPath));\n\t}\n\t// Return the full path to the file\n\treturn writePath;\n};\n\n/*\nSave a tiddler to a file described by the fileInfo:\n\tfilepath: the absolute path to the file containing the tiddler\n\ttype: the type of the tiddler file (NOT the type of the tiddler)\n\thasMetaFile: true if the file also has a companion .meta file\n*/\nexports.saveTiddlerToFile = function(tiddler,fileInfo,callback) {\n\t$tw.utils.createDirectory(path.dirname(fileInfo.filepath));\n\tif(fileInfo.hasMetaFile) {\n\t\t// Save the tiddler as a separate body and meta file\n\t\tvar typeInfo = $tw.config.contentTypeInfo[tiddler.fields.type || \"text/plain\"] || {encoding: \"utf8\"};\n\t\tfs.writeFile(fileInfo.filepath,tiddler.fields.text || \"\",typeInfo.encoding,function(err) {\n\t\t\tif(err) {\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\tfs.writeFile(fileInfo.filepath + \".meta\",tiddler.getFieldStringBlock({exclude: [\"text\",\"bag\"]}),\"utf8\",function(err) {\n\t\t\t\tif(err) {\n\t\t\t\t\treturn callback(err);\n\t\t\t\t}\n\t\t\t\treturn callback(null,fileInfo);\n\t\t\t});\n\t\t});\n\t} else {\n\t\t// Save the tiddler as a self contained templated file\n\t\tif(fileInfo.type === \"application/x-tiddler\") {\n\t\t\tfs.writeFile(fileInfo.filepath,tiddler.getFieldStringBlock({exclude: [\"text\",\"bag\"]}) + (!!tiddler.fields.text ? \"\\n\\n\" + tiddler.fields.text : \"\"),\"utf8\",function(err) {\n\t\t\t\tif(err) {\n\t\t\t\t\treturn callback(err);\n\t\t\t\t}\n\t\t\t\treturn callback(null,fileInfo);\n\t\t\t});\n\t\t} else {\n\t\t\tfs.writeFile(fileInfo.filepath,JSON.stringify([tiddler.getFieldStrings({exclude: [\"bag\"]})],null,$tw.config.preferences.jsonSpaces),\"utf8\",function(err) {\n\t\t\t\tif(err) {\n\t\t\t\t\treturn callback(err);\n\t\t\t\t}\n\t\t\t\treturn callback(null,fileInfo);\n\t\t\t});\n\t\t}\n\t}\n};\n\n/*\nSave a tiddler to a file described by the fileInfo:\n\tfilepath: the absolute path to the file containing the tiddler\n\ttype: the type of the tiddler file (NOT the type of the tiddler)\n\thasMetaFile: true if the file also has a companion .meta file\n*/\nexports.saveTiddlerToFileSync = function(tiddler,fileInfo) {\n\t$tw.utils.createDirectory(path.dirname(fileInfo.filepath));\n\tif(fileInfo.hasMetaFile) {\n\t\t// Save the tiddler as a separate body and meta file\n\t\tvar typeInfo = $tw.config.contentTypeInfo[tiddler.fields.type || \"text/plain\"] || {encoding: \"utf8\"};\n\t\tfs.writeFileSync(fileInfo.filepath,tiddler.fields.text || \"\",typeInfo.encoding);\n\t\tfs.writeFileSync(fileInfo.filepath + \".meta\",tiddler.getFieldStringBlock({exclude: [\"text\",\"bag\"]}),\"utf8\");\n\t} else {\n\t\t// Save the tiddler as a self contained templated file\n\t\tif(fileInfo.type === \"application/x-tiddler\") {\n\t\t\tfs.writeFileSync(fileInfo.filepath,tiddler.getFieldStringBlock({exclude: [\"text\",\"bag\"]}) + (!!tiddler.fields.text ? \"\\n\\n\" + tiddler.fields.text : \"\"),\"utf8\");\n\t\t} else {\n\t\t\tfs.writeFileSync(fileInfo.filepath,JSON.stringify([tiddler.getFieldStrings({exclude: [\"bag\"]})],null,$tw.config.preferences.jsonSpaces),\"utf8\");\n\t\t}\n\t}\n\treturn fileInfo;\n};\n\n/*\nDelete a file described by the fileInfo if it exits\n*/\nexports.deleteTiddlerFile = function(fileInfo,callback) {\n\t//Only attempt to delete files that exist on disk\n\tif(!fileInfo.filepath || !fs.existsSync(fileInfo.filepath)) {\n\t\t//For some reason, the tiddler is only in memory or we can't modify the file at this path\n\t\t$tw.syncer.displayError(\"Server deleteTiddlerFile task failed for filepath: \"+fileInfo.filepath);\n\t\treturn callback(null,fileInfo);\n\t}\n\t// Delete the file\n\tfs.unlink(fileInfo.filepath,function(err) {\n\t\tif(err) {\n\t\t\treturn callback(err);\n\t\t}\n\t\t// Delete the metafile if present\n\t\tif(fileInfo.hasMetaFile && fs.existsSync(fileInfo.filepath + \".meta\")) {\n\t\t\tfs.unlink(fileInfo.filepath + \".meta\",function(err) {\n\t\t\t\tif(err) {\n\t\t\t\t\treturn callback(err);\n\t\t\t\t}\n\t\t\t\treturn $tw.utils.deleteEmptyDirs(path.dirname(fileInfo.filepath),function(err) {\n\t\t\t\t\tif(err) {\n\t\t\t\t\t\treturn callback(err);\n\t\t\t\t\t}\n\t\t\t\t\treturn callback(null,fileInfo);\n\t\t\t\t});\n\t\t\t});\n\t\t} else {\n\t\t\treturn $tw.utils.deleteEmptyDirs(path.dirname(fileInfo.filepath),function(err) {\n\t\t\t\tif(err) {\n\t\t\t\t\treturn callback(err);\n\t\t\t\t}\n\t\t\t\treturn callback(null,fileInfo);\n\t\t\t});\n\t\t}\n\t});\n};\n\n/*\nCleanup old files on disk, by comparing the options values:\n\tadaptorInfo from $tw.syncer.tiddlerInfo\n\tbootInfo from $tw.boot.files\n*/\nexports.cleanupTiddlerFiles = function(options,callback) {\n\tvar adaptorInfo = options.adaptorInfo || {},\n\tbootInfo = options.bootInfo || {},\n\ttitle = options.title || \"undefined\";\n\tif(adaptorInfo.filepath && bootInfo.filepath && adaptorInfo.filepath !== bootInfo.filepath) {\n\t\t$tw.utils.deleteTiddlerFile(adaptorInfo,function(err) {\n\t\t\tif(err) {\n\t\t\t\tif ((err.code == \"EPERM\" || err.code == \"EACCES\") && err.syscall == \"unlink\") {\n\t\t\t\t\t// Error deleting the previous file on disk, should fail gracefully\n\t\t\t\t\t$tw.syncer.displayError(\"Server desynchronized. Error cleaning up previous file for tiddler: \\\"\"+title+\"\\\"\",err);\n\t\t\t\t\treturn callback(null,bootInfo);\n\t\t\t\t} else {\n\t\t\t\t\treturn callback(err);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn callback(null,bootInfo);\n\t\t});\n\t} else {\n\t\treturn callback(null,bootInfo);\n\t}\n};\n\n})();\n","type":"application/javascript","module-type":"utils-node"},"$:/core/modules/utils/linkedlist.js":{"title":"$:/core/modules/utils/linkedlist.js","text":"/*\\\nmodule-type: utils\ntitle: $:/core/modules/utils/linkedlist.js\ntype: application/javascript\n\nThis is a doubly-linked indexed list intended for manipulation, particularly\npushTop, which it does with significantly better performance than an array.\n\n\\*/\n(function(){\n\nfunction LinkedList() {\n\tthis.clear();\n};\n\nLinkedList.prototype.clear = function() {\n\t// LinkedList performs the duty of both the head and tail node\n\tthis.next = new LLMap();\n\tthis.prev = new LLMap();\n\t// Linked list head initially points to itself\n\tthis.next.set(null, null);\n\tthis.prev.set(null, null);\n\tthis.length = 0;\n};\n\nLinkedList.prototype.remove = function(value) {\n\tif($tw.utils.isArray(value)) {\n\t\tfor(var t=0; t<value.length; t++) {\n\t\t\t_assertString(value[t]);\n\t\t}\n\t\tfor(var t=0; t<value.length; t++) {\n\t\t\t_removeOne(this,value[t]);\n\t\t}\n\t} else {\n\t\t_assertString(value);\n\t\t_removeOne(this,value);\n\t}\n};\n\n/*\nPush behaves like array.push and accepts multiple string arguments. But it also\naccepts a single array argument too, to be consistent with its other methods.\n*/\nLinkedList.prototype.push = function(/* values */) {\n\tvar i, values = arguments;\n\tif($tw.utils.isArray(values[0])) {\n\t\tvalues = values[0];\n\t}\n\tfor(i = 0; i < values.length; i++) {\n\t\t_assertString(values[i]);\n\t}\n\tfor(i = 0; i < values.length; i++) {\n\t\t_linkToEnd(this,values[i]);\n\t}\n\treturn this.length;\n};\n\nLinkedList.prototype.pushTop = function(value) {\n\tvar t;\n\tif($tw.utils.isArray(value)) {\n\t\tfor (t=0; t<value.length; t++) {\n\t\t\t_assertString(value[t]);\n\t\t}\n\t\tfor(t=0; t<value.length; t++) {\n\t\t\t_removeOne(this,value[t]);\n\t\t}\n\t\tfor(t=0; t<value.length; t++) {\n\t\t\t_linkToEnd(this,value[t]);\n\t\t}\n\t} else {\n\t\t_assertString(value);\n\t\t_removeOne(this,value);\n\t\t_linkToEnd(this,value);\n\t}\n};\n\nLinkedList.prototype.each = function(callback) {\n\tvar visits = Object.create(null),\n\t\tvalue = this.next.get(null);\n\twhile(value !== null) {\n\t\tcallback(value);\n\t\tvar next = this.next.get(value);\n\t\tif(Array.isArray(next)) {\n\t\t\tvar i = visits[value] || 0;\n\t\t\tvisits[value] = i+1;\n\t\t\tvalue = next[i];\n\t\t} else {\n\t\t\tvalue = next;\n\t\t}\n\t}\n};\n\nLinkedList.prototype.toArray = function() {\n\tvar output = new Array(this.length),\n\t\tindex = 0;\n\tthis.each(function(value) { output[index++] = value; });\n\treturn output;\n};\n\nLinkedList.prototype.makeTiddlerIterator = function(wiki) {\n\tvar self = this;\n\treturn function(callback) {\n\t\tself.each(function(title) {\n\t\t\tcallback(wiki.getTiddler(title),title);\n\t\t});\n\t};\n};\n\nfunction _removeOne(list,value) {\n\tvar nextEntry = list.next.get(value);\n\tif(nextEntry === undefined) {\n\t\treturn;\n\t}\n\tvar prevEntry = list.prev.get(value),\n\t\tprev = prevEntry,\n\t\tnext = nextEntry,\n\t\tref;\n\tif(Array.isArray(nextEntry)) {\n\t\tnext = nextEntry[0];\n\t\tprev = prevEntry[0];\n\t}\n\t// Relink preceding element.\n\tref = list.next.get(prev);\n\tif(Array.isArray(ref)) {\n\t\tvar i = ref.indexOf(value);\n\t\tref[i] = next;\n\t} else {\n\t\tlist.next.set(prev,next);\n\t}\n\n\t// Now relink following element\n\tref = list.prev.get(next);\n\tif(Array.isArray(ref)) {\n\t\tvar i = ref.indexOf(value);\n\t\tref[i] = prev;\n\t} else {\n\t\tlist.prev.set(next,prev);\n\t}\n\n\t// Delink actual value. If it uses arrays, just remove first entries.\n\tif(Array.isArray(nextEntry) && nextEntry.length > 1) {\n\t\tnextEntry.shift();\n\t\tprevEntry.shift();\n\t} else {\n\t\tlist.next.set(value,undefined);\n\t\tlist.prev.set(value,undefined);\n\t}\n\tlist.length -= 1;\n};\n\n// Sticks the given node onto the end of the list.\nfunction _linkToEnd(list,value) {\n\tvar old = list.next.get(value);\n\tvar last = list.prev.get(null);\n\t// Does it already exists?\n\tif(old !== undefined) {\n\t\tif(!Array.isArray(old)) {\n\t\t\told = [old];\n\t\t\tlist.next.set(value,old);\n\t\t\tlist.prev.set(value,[list.prev.get(value)]);\n\t\t}\n\t\told.push(null);\n\t\tlist.prev.get(value).push(last);\n\t} else {\n\t\tlist.next.set(value,null);\n\t\tlist.prev.set(value,last);\n\t}\n\t// Make the old last point to this new one.\n\tif(value !== last) {\n\t\tvar array = list.next.get(last);\n\t\tif(Array.isArray(array)) {\n\t\t\tarray[array.length-1] = value;\n\t\t} else {\n\t\t\tlist.next.set(last,value);\n\t\t}\n\t\tlist.prev.set(null,value);\n\t} else {\n\t\t// Edge case, the pushed value was already the last value.\n\t\t// The second-to-last nextPtr for that value must point to itself now.\n\t\tvar array = list.next.get(last);\n\t\tarray[array.length-2] = value;\n\t}\n\tlist.length += 1;\n};\n\nfunction _assertString(value) {\n\tif(typeof value !== \"string\") {\n\t\tthrow \"Linked List only accepts string values, not \" + value;\n\t}\n};\n\nvar LLMap = function() {\n\tthis.map = Object.create(null);\n};\n\n// Just a wrapper so our object map can also accept null.\nLLMap.prototype = {\n\tset: function(key,val) {\n\t\t(key === null) ? (this.null = val) : (this.map[key] = val);\n\t},\n\tget: function(key) {\n\t\treturn (key === null) ? this.null : this.map[key];\n\t}\n};\n\nexports.LinkedList = LinkedList;\n\n})();\n","module-type":"utils","type":"application/javascript"},"$:/core/modules/utils/logger.js":{"title":"$:/core/modules/utils/logger.js","text":"/*\\\ntitle: $:/core/modules/utils/logger.js\ntype: application/javascript\nmodule-type: utils\n\nA basic logging implementation\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar ALERT_TAG = \"$:/tags/Alert\";\n\n/*\nMake a new logger\n*/\nfunction Logger(componentName,options) {\n\toptions = options || {};\n\tthis.componentName = componentName || \"\";\n\tthis.colour = options.colour || \"white\";\n\tthis.enable = \"enable\" in options ? options.enable : true;\n\tthis.save = \"save\" in options ? options.save : true;\n\tthis.saveLimit = options.saveLimit || 100 * 1024;\n\tthis.saveBufferLogger = this;\n\tthis.buffer = \"\";\n\tthis.alertCount = 0;\n}\n\nLogger.prototype.setSaveBuffer = function(logger) {\n\tthis.saveBufferLogger = logger;\n};\n\n/*\nLog a message\n*/\nLogger.prototype.log = function(/* args */) {\n\tvar self = this;\n\tif(this.enable) {\n\t\tif(this.saveBufferLogger.save) {\n\t\t\tthis.saveBufferLogger.buffer += $tw.utils.formatDateString(new Date(),\"YYYY MM DD 0hh:0mm:0ss.0XXX\") + \":\";\n\t\t\t$tw.utils.each(Array.prototype.slice.call(arguments,0),function(arg,index) {\n\t\t\t\tself.saveBufferLogger.buffer += \" \" + arg;\n\t\t\t});\n\t\t\tthis.saveBufferLogger.buffer += \"\\n\";\n\t\t\tthis.saveBufferLogger.buffer = this.saveBufferLogger.buffer.slice(-this.saveBufferLogger.saveLimit);\n\t\t}\n\t\tif(console !== undefined && console.log !== undefined) {\n\t\t\tvar logMessage = [$tw.utils.terminalColour(this.colour) + this.componentName + \":\"].concat(Array.prototype.slice.call(arguments,0));\n\t\t\tlogMessage[logMessage.length-1] += $tw.utils.terminalColour();\n\t\t\treturn Function.apply.call(console.log, console, logMessage);\n\t\t}\n\t} \n};\n\n/*\nRead the message buffer\n*/\nLogger.prototype.getBuffer = function() {\n\treturn this.saveBufferLogger.buffer;\n};\n\n/*\nLog a structure as a table\n*/\nLogger.prototype.table = function(value) {\n\t(console.table || console.log)(value);\n};\n\n/*\nAlert a message\n*/\nLogger.prototype.alert = function(/* args */) {\n\tif(this.enable) {\n\t\t// Prepare the text of the alert\n\t\tvar text = Array.prototype.join.call(arguments,\" \");\n\t\t// Create alert tiddlers in the browser\n\t\tif($tw.browser) {\n\t\t\t// Check if there is an existing alert with the same text and the same component\n\t\t\tvar existingAlerts = $tw.wiki.getTiddlersWithTag(ALERT_TAG),\n\t\t\t\talertFields,\n\t\t\t\texistingCount,\n\t\t\t\tself = this;\n\t\t\t$tw.utils.each(existingAlerts,function(title) {\n\t\t\t\tvar tiddler = $tw.wiki.getTiddler(title);\n\t\t\t\tif(tiddler.fields.text === text && tiddler.fields.component === self.componentName && tiddler.fields.modified && (!alertFields || tiddler.fields.modified < alertFields.modified)) {\n\t\t\t\t\t\talertFields = $tw.utils.extend({},tiddler.fields);\n\t\t\t\t}\n\t\t\t});\n\t\t\tif(alertFields) {\n\t\t\t\texistingCount = alertFields.count || 1;\n\t\t\t} else {\n\t\t\t\talertFields = {\n\t\t\t\t\ttitle: $tw.wiki.generateNewTitle(\"$:/temp/alerts/alert\",{prefix: \"\"}),\n\t\t\t\t\ttext: text,\n\t\t\t\t\ttags: [ALERT_TAG],\n\t\t\t\t\tcomponent: this.componentName\n\t\t\t\t};\n\t\t\t\texistingCount = 0;\n\t\t\t\tthis.alertCount += 1;\n\t\t\t}\n\t\t\talertFields.modified = new Date();\n\t\t\tif(++existingCount > 1) {\n\t\t\t\talertFields.count = existingCount;\n\t\t\t} else {\n\t\t\t\talertFields.count = undefined;\n\t\t\t}\n\t\t\t$tw.wiki.addTiddler(new $tw.Tiddler(alertFields));\n\t\t\t// Log the alert as well\n\t\t\tthis.log.apply(this,Array.prototype.slice.call(arguments,0));\n\t\t} else {\n\t\t\t// Print an orange message to the console if not in the browser\n\t\t\tconsole.error(\"\\x1b[1;33m\" + text + \"\\x1b[0m\");\n\t\t}\n\t}\n};\n\n/*\nClear outstanding alerts\n*/\nLogger.prototype.clearAlerts = function() {\n\tvar self = this;\n\tif($tw.browser && this.alertCount > 0) {\n\t\t$tw.utils.each($tw.wiki.getTiddlersWithTag(ALERT_TAG),function(title) {\n\t\t\tvar tiddler = $tw.wiki.getTiddler(title);\n\t\t\tif(tiddler.fields.component === self.componentName) {\n\t\t\t\t$tw.wiki.deleteTiddler(title);\n\t\t\t}\n\t\t});\n\t\tthis.alertCount = 0;\n\t}\n};\n\nexports.Logger = Logger;\n\n})();\n","type":"application/javascript","module-type":"utils"},"$:/core/modules/utils/parsetree.js":{"title":"$:/core/modules/utils/parsetree.js","text":"/*\\\ntitle: $:/core/modules/utils/parsetree.js\ntype: application/javascript\nmodule-type: utils\n\nParse tree utility functions.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nAdd attribute to parse tree node\nCan be invoked as (node,name,value) or (node,attr)\n*/\nexports.addAttributeToParseTreeNode = function(node,name,value) {\n\tvar attribute = typeof name === \"object\" ? name : {name: name, type: \"string\", value: value};\n\tname = attribute.name;\n\tnode.attributes = node.attributes || {};\n\tnode.orderedAttributes = node.orderedAttributes || [];\n\tnode.attributes[name] = attribute;\n\tvar foundIndex = -1;\n\t$tw.utils.each(node.orderedAttributes,function(attr,index) {\n\t\tif(attr.name === name) {\n\t\t\tfoundIndex = index;\n\t\t}\n\t});\n\tif(foundIndex === -1) {\n\t\tnode.orderedAttributes.push(attribute);\n\t} else {\n\t\tnode.orderedAttributes[foundIndex] = attribute;\n\t}\n};\n\nexports.getOrderedAttributesFromParseTreeNode = function(node) {\n\tif(node.orderedAttributes) {\n\t\treturn node.orderedAttributes;\n\t} else {\n\t\tvar attributes = [];\n\t\t$tw.utils.each(node.attributes,function(attribute) {\n\t\t\tattributes.push(attribute);\n\t\t});\n\t\treturn attributes.sort(function(a,b) {\n\t\t\treturn a.name < b.name ? -1 : (a.name > b.name ? 1 : 0);\n\t\t});\n\t}\n};\n\nexports.getAttributeValueFromParseTreeNode = function(node,name,defaultValue) {\n\tif(node.attributes && node.attributes[name] && node.attributes[name].value !== undefined) {\n\t\treturn node.attributes[name].value;\n\t}\n\treturn defaultValue;\n};\n\nexports.addClassToParseTreeNode = function(node,classString) {\n\tvar classes = [],\n\t\tattribute;\n\tnode.attributes = node.attributes || {};\n\tattribute = node.attributes[\"class\"];\n\tif(!attribute) {\n\t\t// If the class attribute does not exist, we must create it first.\n\t\tattribute = {name: \"class\", type: \"string\", value: \"\"};\n\t\tnode.attributes[\"class\"] = attribute;\n\t\tnode.orderedAttributes = node.orderedAttributes || [];\n\t\tnode.orderedAttributes.push(attribute);\n\t}\n\tif(attribute.type === \"string\") {\n\t\tif(attribute.value !== \"\") {\n\t\t\tclasses = attribute.value.split(\" \");\n\t\t}\n\t\tif(classString !== \"\") {\n\t\t\t$tw.utils.pushTop(classes,classString.split(\" \"));\n\t\t}\n\t\tattribute.value = classes.join(\" \");\n\t}\n};\n\nexports.addStyleToParseTreeNode = function(node,name,value) {\n\tvar attribute;\n\tnode.attributes = node.attributes || {};\n\tattribute = node.attributes.style;\n\tif(!attribute) {\n\t\tattribute = {name: \"style\", type: \"string\", value: \"\"};\n\t\tnode.attributes.style = attribute;\n\t\tnode.orderedAttributes = node.orderedAttributes || [];\n\t\tnode.orderedAttributes.push(attribute);\n\t}\n\tif(attribute.type === \"string\") {\n\t\tattribute.value += name + \":\" + value + \";\";\n\t}\n};\n\nexports.findParseTreeNode = function(nodeArray,search) {\n\tfor(var t=0; t<nodeArray.length; t++) {\n\t\tif(nodeArray[t].type === search.type && nodeArray[t].tag === search.tag) {\n\t\t\treturn nodeArray[t];\n\t\t}\n\t}\n\treturn undefined;\n};\n\n/*\nHelper to get the text of a parse tree node or array of nodes\n*/\nexports.getParseTreeText = function getParseTreeText(tree) {\n\tvar output = [];\n\tif($tw.utils.isArray(tree)) {\n\t\t$tw.utils.each(tree,function(node) {\n\t\t\toutput.push(getParseTreeText(node));\n\t\t});\n\t} else {\n\t\tif(tree.type === \"text\") {\n\t\t\toutput.push(tree.text);\n\t\t}\n\t\tif(tree.children) {\n\t\t\treturn getParseTreeText(tree.children);\n\t\t}\n\t}\n\treturn output.join(\"\");\n};\n\n})();\n","type":"application/javascript","module-type":"utils"},"$:/core/modules/utils/performance.js":{"title":"$:/core/modules/utils/performance.js","text":"/*\\\ntitle: $:/core/modules/utils/performance.js\ntype: application/javascript\nmodule-type: global\n\nPerformance measurement.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nfunction Performance(enabled) {\n\tthis.enabled = !!enabled;\n\tthis.measures = {}; // Hashmap by measurement name of {time:, invocations:}\n\tthis.logger = new $tw.utils.Logger(\"performance\");\n\tthis.showGreeting();\n}\n\nPerformance.prototype.showGreeting = function() {\n\tif($tw.browser) {\n\t\tthis.logger.log(\"Execute $tw.perf.log(); to see filter execution timings\");\n\t}\n};\n\n/*\nWrap performance reporting around a top level function\n*/\nPerformance.prototype.report = function(name,fn) {\n\tvar self = this;\n\tif(this.enabled) {\n\t\treturn function() {\n\t\t\tvar startTime = $tw.utils.timer(),\n\t\t\t\tresult = fn.apply(this,arguments);\n\t\t\tself.logger.log(name + \": \" + $tw.utils.timer(startTime).toFixed(2) + \"ms\");\n\t\t\treturn result;\n\t\t};\n\t} else {\n\t\treturn fn;\n\t}\n};\n\nPerformance.prototype.log = function() {\n\tvar self = this,\n\t\ttotalTime = 0,\n\t\torderedMeasures = Object.keys(this.measures).sort(function(a,b) {\n\t\t\tif(self.measures[a].time > self.measures[b].time) {\n\t\t\t\treturn -1;\n\t\t\t} else if (self.measures[a].time < self.measures[b].time) {\n\t\t\t\treturn + 1;\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t});\n\t$tw.utils.each(orderedMeasures,function(name) {\n\t\ttotalTime += self.measures[name].time;\n\t});\n\tvar results = []\n\t$tw.utils.each(orderedMeasures,function(name) {\n\t\tvar measure = self.measures[name];\n\t\tresults.push({name: name,invocations: measure.invocations, avgTime: measure.time / measure.invocations, totalTime: measure.time, percentTime: (measure.time / totalTime) * 100})\n\t});\n\tself.logger.table(results);\n};\n\n/*\nWrap performance measurements around a subfunction\n*/\nPerformance.prototype.measure = function(name,fn) {\n\tvar self = this;\n\tif(this.enabled) {\n\t\treturn function() {\n\t\t\tvar startTime = $tw.utils.timer(),\n\t\t\t\tresult = fn.apply(this,arguments);\n\t\t\tif(!(name in self.measures)) {\n\t\t\t\tself.measures[name] = {time: 0, invocations: 0};\n\t\t\t}\n\t\t\tself.measures[name].time += $tw.utils.timer(startTime);\n\t\t\tself.measures[name].invocations++;\n\t\t\treturn result;\n\t\t};\n\t} else {\n\t\treturn fn;\n\t}\n};\n\nexports.Performance = Performance;\n\n})();\n","type":"application/javascript","module-type":"global"},"$:/core/modules/utils/pluginmaker.js":{"title":"$:/core/modules/utils/pluginmaker.js","text":"/*\\\ntitle: $:/core/modules/utils/pluginmaker.js\ntype: application/javascript\nmodule-type: utils\n\nA quick and dirty way to pack up plugins within the browser.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nRepack a plugin, and then delete any non-shadow payload tiddlers\n*/\nexports.repackPlugin = function(title,additionalTiddlers,excludeTiddlers) {\n\tadditionalTiddlers = additionalTiddlers || [];\n\texcludeTiddlers = excludeTiddlers || [];\n\t// Get the plugin tiddler\n\tvar pluginTiddler = $tw.wiki.getTiddler(title);\n\tif(!pluginTiddler) {\n\t\tthrow \"No such tiddler as \" + title;\n\t}\n\t// Extract the JSON\n\tvar jsonPluginTiddler = $tw.utils.parseJSONSafe(pluginTiddler.fields.text,null);\n\tif(!jsonPluginTiddler) {\n\t\tthrow \"Cannot parse plugin tiddler \" + title + \"\\n\" + $tw.language.getString(\"Error/Caption\") + \": \" + e;\n\t}\n\t// Get the list of tiddlers\n\tvar tiddlers = Object.keys(jsonPluginTiddler.tiddlers);\n\t// Add the additional tiddlers\n\t$tw.utils.pushTop(tiddlers,additionalTiddlers);\n\t// Remove any excluded tiddlers\n\tfor(var t=tiddlers.length-1; t>=0; t--) {\n\t\tif(excludeTiddlers.indexOf(tiddlers[t]) !== -1) {\n\t\t\ttiddlers.splice(t,1);\n\t\t}\n\t}\n\t// Pack up the tiddlers into a block of JSON\n\tvar plugins = {};\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tvar tiddler = $tw.wiki.getTiddler(title),\n\t\t\tfields = {};\n\t\t$tw.utils.each(tiddler.fields,function (value,name) {\n\t\t\tfields[name] = tiddler.getFieldString(name);\n\t\t});\n\t\tplugins[title] = fields;\n\t});\n\t// Retrieve and bump the version number\n\tvar pluginVersion = $tw.utils.parseVersion(pluginTiddler.getFieldString(\"version\") || \"0.0.0\") || {\n\t\t\tmajor: \"0\",\n\t\t\tminor: \"0\",\n\t\t\tpatch: \"0\"\n\t\t};\n\tpluginVersion.patch++;\n\tvar version = pluginVersion.major + \".\" + pluginVersion.minor + \".\" + pluginVersion.patch;\n\tif(pluginVersion.prerelease) {\n\t\tversion += \"-\" + pluginVersion.prerelease;\n\t}\n\tif(pluginVersion.build) {\n\t\tversion += \"+\" + pluginVersion.build;\n\t}\n\t// Save the tiddler\n\t$tw.wiki.addTiddler(new $tw.Tiddler(pluginTiddler,{text: JSON.stringify({tiddlers: plugins},null,4), version: version}));\n\t// Delete any non-shadow constituent tiddlers\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tif($tw.wiki.tiddlerExists(title)) {\n\t\t\t$tw.wiki.deleteTiddler(title);\n\t\t}\n\t});\n\t// Trigger an autosave\n\t$tw.rootWidget.dispatchEvent({type: \"tm-auto-save-wiki\"});\n\t// Return a heartwarming confirmation\n\treturn \"Plugin \" + title + \" successfully saved\";\n};\n\n})();\n","type":"application/javascript","module-type":"utils"},"$:/core/modules/utils/repository.js":{"title":"$:/core/modules/utils/repository.js","text":"/*\\\ntitle: $:/core/modules/utils/repository.js\ntype: application/javascript\nmodule-type: utils\n\nUtilities for working with the TiddlyWiki repository file structure\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nGet an object containing all the plugins as a hashmap by title of the JSON representation of the plugin\nOptions:\n\nignoreEnvironmentVariables: defaults to false\n*/\nexports.getAllPlugins = function(options) {\n\toptions = options || {};\n\tvar fs = require(\"fs\"),\n\t\tpath = require(\"path\"),\n\t\ttiddlers = {};\n\t// Collect up the library plugins\n\tvar collectPlugins = function(folder) {\n\t\t\tvar pluginFolders = $tw.utils.getSubdirectories(folder) || [];\n\t\t\tfor(var p=0; p<pluginFolders.length; p++) {\n\t\t\t\tif(!$tw.boot.excludeRegExp.test(pluginFolders[p])) {\n\t\t\t\t\tvar pluginFields = $tw.loadPluginFolder(path.resolve(folder,\"./\" + pluginFolders[p]));\n\t\t\t\t\tif(pluginFields && pluginFields.title) {\n\t\t\t\t\t\ttiddlers[pluginFields.title] = pluginFields;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tcollectPublisherPlugins = function(folder) {\n\t\t\tvar publisherFolders = $tw.utils.getSubdirectories(folder) || [];\n\t\t\tfor(var t=0; t<publisherFolders.length; t++) {\n\t\t\t\tif(!$tw.boot.excludeRegExp.test(publisherFolders[t])) {\n\t\t\t\t\tcollectPlugins(path.resolve(folder,\"./\" + publisherFolders[t]));\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t$tw.utils.each($tw.getLibraryItemSearchPaths($tw.config.pluginsPath,options.ignoreEnvironmentVariables ? undefined : $tw.config.pluginsEnvVar),collectPublisherPlugins);\n\t$tw.utils.each($tw.getLibraryItemSearchPaths($tw.config.themesPath,options.ignoreEnvironmentVariables ? undefined : $tw.config.themesEnvVar),collectPublisherPlugins);\n\t$tw.utils.each($tw.getLibraryItemSearchPaths($tw.config.languagesPath,options.ignoreEnvironmentVariables ? undefined : $tw.config.languagesEnvVar),collectPlugins);\n\treturn tiddlers;\n};\n\n})();\n","type":"application/javascript","module-type":"utils"},"$:/core/modules/utils/transliterate.js":{"title":"$:/core/modules/utils/transliterate.js","text":"/*\\\ntitle: $:/core/modules/utils/transliterate.js\ntype: application/javascript\nmodule-type: utils\n\nTransliteration static utility functions.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nTransliterate string to ASCII\n\n(Some pairs taken from http://semplicewebsites.com/removing-accents-javascript)\n*/\nexports.transliterationPairs = {\n\t\"Á\":\"A\",\n\t\"Ă\":\"A\",\n\t\"Ắ\":\"A\",\n\t\"Ặ\":\"A\",\n\t\"Ằ\":\"A\",\n\t\"Ẳ\":\"A\",\n\t\"Ẵ\":\"A\",\n\t\"Ǎ\":\"A\",\n\t\"Â\":\"A\",\n\t\"Ấ\":\"A\",\n\t\"Ậ\":\"A\",\n\t\"Ầ\":\"A\",\n\t\"Ẩ\":\"A\",\n\t\"Ẫ\":\"A\",\n\t\"Ä\":\"A\",\n\t\"Ǟ\":\"A\",\n\t\"Ȧ\":\"A\",\n\t\"Ǡ\":\"A\",\n\t\"Ạ\":\"A\",\n\t\"Ȁ\":\"A\",\n\t\"À\":\"A\",\n\t\"Ả\":\"A\",\n\t\"Ȃ\":\"A\",\n\t\"Ā\":\"A\",\n\t\"Ą\":\"A\",\n\t\"Å\":\"A\",\n\t\"Ǻ\":\"A\",\n\t\"Ḁ\":\"A\",\n\t\"Ⱥ\":\"A\",\n\t\"Ã\":\"A\",\n\t\"Ꜳ\":\"AA\",\n\t\"Æ\":\"AE\",\n\t\"Ǽ\":\"AE\",\n\t\"Ǣ\":\"AE\",\n\t\"Ꜵ\":\"AO\",\n\t\"Ꜷ\":\"AU\",\n\t\"Ꜹ\":\"AV\",\n\t\"Ꜻ\":\"AV\",\n\t\"Ꜽ\":\"AY\",\n\t\"Ḃ\":\"B\",\n\t\"Ḅ\":\"B\",\n\t\"Ɓ\":\"B\",\n\t\"Ḇ\":\"B\",\n\t\"Ƀ\":\"B\",\n\t\"Ƃ\":\"B\",\n\t\"Ć\":\"C\",\n\t\"Č\":\"C\",\n\t\"Ç\":\"C\",\n\t\"Ḉ\":\"C\",\n\t\"Ĉ\":\"C\",\n\t\"Ċ\":\"C\",\n\t\"Ƈ\":\"C\",\n\t\"Ȼ\":\"C\",\n\t\"Ď\":\"D\",\n\t\"Ḑ\":\"D\",\n\t\"Ḓ\":\"D\",\n\t\"Ḋ\":\"D\",\n\t\"Ḍ\":\"D\",\n\t\"Ɗ\":\"D\",\n\t\"Ḏ\":\"D\",\n\t\"Dz\":\"D\",\n\t\"Dž\":\"D\",\n\t\"Đ\":\"D\",\n\t\"Ƌ\":\"D\",\n\t\"DZ\":\"DZ\",\n\t\"DŽ\":\"DZ\",\n\t\"É\":\"E\",\n\t\"Ĕ\":\"E\",\n\t\"Ě\":\"E\",\n\t\"Ȩ\":\"E\",\n\t\"Ḝ\":\"E\",\n\t\"Ê\":\"E\",\n\t\"Ế\":\"E\",\n\t\"Ệ\":\"E\",\n\t\"Ề\":\"E\",\n\t\"Ể\":\"E\",\n\t\"Ễ\":\"E\",\n\t\"Ḙ\":\"E\",\n\t\"Ë\":\"E\",\n\t\"Ė\":\"E\",\n\t\"Ẹ\":\"E\",\n\t\"Ȅ\":\"E\",\n\t\"È\":\"E\",\n\t\"Ẻ\":\"E\",\n\t\"Ȇ\":\"E\",\n\t\"Ē\":\"E\",\n\t\"Ḗ\":\"E\",\n\t\"Ḕ\":\"E\",\n\t\"Ę\":\"E\",\n\t\"Ɇ\":\"E\",\n\t\"Ẽ\":\"E\",\n\t\"Ḛ\":\"E\",\n\t\"Ꝫ\":\"ET\",\n\t\"Ḟ\":\"F\",\n\t\"Ƒ\":\"F\",\n\t\"Ǵ\":\"G\",\n\t\"Ğ\":\"G\",\n\t\"Ǧ\":\"G\",\n\t\"Ģ\":\"G\",\n\t\"Ĝ\":\"G\",\n\t\"Ġ\":\"G\",\n\t\"Ɠ\":\"G\",\n\t\"Ḡ\":\"G\",\n\t\"Ǥ\":\"G\",\n\t\"Ḫ\":\"H\",\n\t\"Ȟ\":\"H\",\n\t\"Ḩ\":\"H\",\n\t\"Ĥ\":\"H\",\n\t\"Ⱨ\":\"H\",\n\t\"Ḧ\":\"H\",\n\t\"Ḣ\":\"H\",\n\t\"Ḥ\":\"H\",\n\t\"Ħ\":\"H\",\n\t\"Í\":\"I\",\n\t\"Ĭ\":\"I\",\n\t\"Ǐ\":\"I\",\n\t\"Î\":\"I\",\n\t\"Ï\":\"I\",\n\t\"Ḯ\":\"I\",\n\t\"İ\":\"I\",\n\t\"Ị\":\"I\",\n\t\"Ȉ\":\"I\",\n\t\"Ì\":\"I\",\n\t\"Ỉ\":\"I\",\n\t\"Ȋ\":\"I\",\n\t\"Ī\":\"I\",\n\t\"Į\":\"I\",\n\t\"Ɨ\":\"I\",\n\t\"Ĩ\":\"I\",\n\t\"Ḭ\":\"I\",\n\t\"Ꝺ\":\"D\",\n\t\"Ꝼ\":\"F\",\n\t\"Ᵹ\":\"G\",\n\t\"Ꞃ\":\"R\",\n\t\"Ꞅ\":\"S\",\n\t\"Ꞇ\":\"T\",\n\t\"Ꝭ\":\"IS\",\n\t\"Ĵ\":\"J\",\n\t\"Ɉ\":\"J\",\n\t\"Ḱ\":\"K\",\n\t\"Ǩ\":\"K\",\n\t\"Ķ\":\"K\",\n\t\"Ⱪ\":\"K\",\n\t\"Ꝃ\":\"K\",\n\t\"Ḳ\":\"K\",\n\t\"Ƙ\":\"K\",\n\t\"Ḵ\":\"K\",\n\t\"Ꝁ\":\"K\",\n\t\"Ꝅ\":\"K\",\n\t\"Ĺ\":\"L\",\n\t\"Ƚ\":\"L\",\n\t\"Ľ\":\"L\",\n\t\"Ļ\":\"L\",\n\t\"Ḽ\":\"L\",\n\t\"Ḷ\":\"L\",\n\t\"Ḹ\":\"L\",\n\t\"Ⱡ\":\"L\",\n\t\"Ꝉ\":\"L\",\n\t\"Ḻ\":\"L\",\n\t\"Ŀ\":\"L\",\n\t\"Ɫ\":\"L\",\n\t\"Lj\":\"L\",\n\t\"Ł\":\"L\",\n\t\"LJ\":\"LJ\",\n\t\"Ḿ\":\"M\",\n\t\"Ṁ\":\"M\",\n\t\"Ṃ\":\"M\",\n\t\"Ɱ\":\"M\",\n\t\"Ń\":\"N\",\n\t\"Ň\":\"N\",\n\t\"Ņ\":\"N\",\n\t\"Ṋ\":\"N\",\n\t\"Ṅ\":\"N\",\n\t\"Ṇ\":\"N\",\n\t\"Ǹ\":\"N\",\n\t\"Ɲ\":\"N\",\n\t\"Ṉ\":\"N\",\n\t\"Ƞ\":\"N\",\n\t\"Nj\":\"N\",\n\t\"Ñ\":\"N\",\n\t\"NJ\":\"NJ\",\n\t\"ð\":\"d\",\n\t\"Ð\":\"D\",\n\t\"Ó\":\"O\",\n\t\"Ŏ\":\"O\",\n\t\"Ǒ\":\"O\",\n\t\"Ô\":\"O\",\n\t\"Ố\":\"O\",\n\t\"Ộ\":\"O\",\n\t\"Ồ\":\"O\",\n\t\"Ổ\":\"O\",\n\t\"Ỗ\":\"O\",\n\t\"Ö\":\"O\",\n\t\"Ȫ\":\"O\",\n\t\"Ȯ\":\"O\",\n\t\"Ȱ\":\"O\",\n\t\"Ọ\":\"O\",\n\t\"Ő\":\"O\",\n\t\"Ȍ\":\"O\",\n\t\"Ò\":\"O\",\n\t\"Ỏ\":\"O\",\n\t\"Ơ\":\"O\",\n\t\"Ớ\":\"O\",\n\t\"Ợ\":\"O\",\n\t\"Ờ\":\"O\",\n\t\"Ở\":\"O\",\n\t\"Ỡ\":\"O\",\n\t\"Ȏ\":\"O\",\n\t\"Ꝋ\":\"O\",\n\t\"Ꝍ\":\"O\",\n\t\"Ō\":\"O\",\n\t\"Ṓ\":\"O\",\n\t\"Ṑ\":\"O\",\n\t\"Ɵ\":\"O\",\n\t\"Ǫ\":\"O\",\n\t\"Ǭ\":\"O\",\n\t\"Ø\":\"O\",\n\t\"Ǿ\":\"O\",\n\t\"Õ\":\"O\",\n\t\"Ṍ\":\"O\",\n\t\"Ṏ\":\"O\",\n\t\"Ȭ\":\"O\",\n\t\"Ƣ\":\"OI\",\n\t\"Ꝏ\":\"OO\",\n\t\"Ɛ\":\"E\",\n\t\"Ɔ\":\"O\",\n\t\"Ȣ\":\"OU\",\n\t\"Ṕ\":\"P\",\n\t\"Ṗ\":\"P\",\n\t\"Ꝓ\":\"P\",\n\t\"Ƥ\":\"P\",\n\t\"Ꝕ\":\"P\",\n\t\"Ᵽ\":\"P\",\n\t\"Ꝑ\":\"P\",\n\t\"Ꝙ\":\"Q\",\n\t\"Ꝗ\":\"Q\",\n\t\"Ŕ\":\"R\",\n\t\"Ř\":\"R\",\n\t\"Ŗ\":\"R\",\n\t\"Ṙ\":\"R\",\n\t\"Ṛ\":\"R\",\n\t\"Ṝ\":\"R\",\n\t\"Ȑ\":\"R\",\n\t\"Ȓ\":\"R\",\n\t\"Ṟ\":\"R\",\n\t\"Ɍ\":\"R\",\n\t\"Ɽ\":\"R\",\n\t\"Ꜿ\":\"C\",\n\t\"Ǝ\":\"E\",\n\t\"ß\":\"ss\",\n\t\"ẞ\":\"SS\",\n\t\"Ś\":\"S\",\n\t\"Ṥ\":\"S\",\n\t\"Š\":\"S\",\n\t\"Ṧ\":\"S\",\n\t\"Ş\":\"S\",\n\t\"Ŝ\":\"S\",\n\t\"Ș\":\"S\",\n\t\"Ṡ\":\"S\",\n\t\"Ṣ\":\"S\",\n\t\"Ṩ\":\"S\",\n\t\"þ\": \"th\",\n\t\"Þ\": \"TH\",\n\t\"Ť\":\"T\",\n\t\"Ţ\":\"T\",\n\t\"Ṱ\":\"T\",\n\t\"Ț\":\"T\",\n\t\"Ⱦ\":\"T\",\n\t\"Ṫ\":\"T\",\n\t\"Ṭ\":\"T\",\n\t\"Ƭ\":\"T\",\n\t\"Ṯ\":\"T\",\n\t\"Ʈ\":\"T\",\n\t\"Ŧ\":\"T\",\n\t\"Ɐ\":\"A\",\n\t\"Ꞁ\":\"L\",\n\t\"Ɯ\":\"M\",\n\t\"Ʌ\":\"V\",\n\t\"Ꜩ\":\"TZ\",\n\t\"Ú\":\"U\",\n\t\"Ŭ\":\"U\",\n\t\"Ǔ\":\"U\",\n\t\"Û\":\"U\",\n\t\"Ṷ\":\"U\",\n\t\"Ü\":\"U\",\n\t\"Ǘ\":\"U\",\n\t\"Ǚ\":\"U\",\n\t\"Ǜ\":\"U\",\n\t\"Ǖ\":\"U\",\n\t\"Ṳ\":\"U\",\n\t\"Ụ\":\"U\",\n\t\"Ű\":\"U\",\n\t\"Ȕ\":\"U\",\n\t\"Ù\":\"U\",\n\t\"Ủ\":\"U\",\n\t\"Ư\":\"U\",\n\t\"Ứ\":\"U\",\n\t\"Ự\":\"U\",\n\t\"Ừ\":\"U\",\n\t\"Ử\":\"U\",\n\t\"Ữ\":\"U\",\n\t\"Ȗ\":\"U\",\n\t\"Ū\":\"U\",\n\t\"Ṻ\":\"U\",\n\t\"Ų\":\"U\",\n\t\"Ů\":\"U\",\n\t\"Ũ\":\"U\",\n\t\"Ṹ\":\"U\",\n\t\"Ṵ\":\"U\",\n\t\"Ꝟ\":\"V\",\n\t\"Ṿ\":\"V\",\n\t\"Ʋ\":\"V\",\n\t\"Ṽ\":\"V\",\n\t\"Ꝡ\":\"VY\",\n\t\"Ẃ\":\"W\",\n\t\"Ŵ\":\"W\",\n\t\"Ẅ\":\"W\",\n\t\"Ẇ\":\"W\",\n\t\"Ẉ\":\"W\",\n\t\"Ẁ\":\"W\",\n\t\"Ⱳ\":\"W\",\n\t\"Ẍ\":\"X\",\n\t\"Ẋ\":\"X\",\n\t\"Ý\":\"Y\",\n\t\"Ŷ\":\"Y\",\n\t\"Ÿ\":\"Y\",\n\t\"Ẏ\":\"Y\",\n\t\"Ỵ\":\"Y\",\n\t\"Ỳ\":\"Y\",\n\t\"Ƴ\":\"Y\",\n\t\"Ỷ\":\"Y\",\n\t\"Ỿ\":\"Y\",\n\t\"Ȳ\":\"Y\",\n\t\"Ɏ\":\"Y\",\n\t\"Ỹ\":\"Y\",\n\t\"Ź\":\"Z\",\n\t\"Ž\":\"Z\",\n\t\"Ẑ\":\"Z\",\n\t\"Ⱬ\":\"Z\",\n\t\"Ż\":\"Z\",\n\t\"Ẓ\":\"Z\",\n\t\"Ȥ\":\"Z\",\n\t\"Ẕ\":\"Z\",\n\t\"Ƶ\":\"Z\",\n\t\"IJ\":\"IJ\",\n\t\"Œ\":\"OE\",\n\t\"ᴀ\":\"A\",\n\t\"ᴁ\":\"AE\",\n\t\"ʙ\":\"B\",\n\t\"ᴃ\":\"B\",\n\t\"ᴄ\":\"C\",\n\t\"ᴅ\":\"D\",\n\t\"ᴇ\":\"E\",\n\t\"ꜰ\":\"F\",\n\t\"ɢ\":\"G\",\n\t\"ʛ\":\"G\",\n\t\"ʜ\":\"H\",\n\t\"ɪ\":\"I\",\n\t\"ʁ\":\"R\",\n\t\"ᴊ\":\"J\",\n\t\"ᴋ\":\"K\",\n\t\"ʟ\":\"L\",\n\t\"ᴌ\":\"L\",\n\t\"ᴍ\":\"M\",\n\t\"ɴ\":\"N\",\n\t\"ᴏ\":\"O\",\n\t\"ɶ\":\"OE\",\n\t\"ᴐ\":\"O\",\n\t\"ᴕ\":\"OU\",\n\t\"ᴘ\":\"P\",\n\t\"ʀ\":\"R\",\n\t\"ᴎ\":\"N\",\n\t\"ᴙ\":\"R\",\n\t\"ꜱ\":\"S\",\n\t\"ᴛ\":\"T\",\n\t\"ⱻ\":\"E\",\n\t\"ᴚ\":\"R\",\n\t\"ᴜ\":\"U\",\n\t\"ᴠ\":\"V\",\n\t\"ᴡ\":\"W\",\n\t\"ʏ\":\"Y\",\n\t\"ᴢ\":\"Z\",\n\t\"á\":\"a\",\n\t\"ă\":\"a\",\n\t\"ắ\":\"a\",\n\t\"ặ\":\"a\",\n\t\"ằ\":\"a\",\n\t\"ẳ\":\"a\",\n\t\"ẵ\":\"a\",\n\t\"ǎ\":\"a\",\n\t\"â\":\"a\",\n\t\"ấ\":\"a\",\n\t\"ậ\":\"a\",\n\t\"ầ\":\"a\",\n\t\"ẩ\":\"a\",\n\t\"ẫ\":\"a\",\n\t\"ä\":\"a\",\n\t\"ǟ\":\"a\",\n\t\"ȧ\":\"a\",\n\t\"ǡ\":\"a\",\n\t\"ạ\":\"a\",\n\t\"ȁ\":\"a\",\n\t\"à\":\"a\",\n\t\"ả\":\"a\",\n\t\"ȃ\":\"a\",\n\t\"ā\":\"a\",\n\t\"ą\":\"a\",\n\t\"ᶏ\":\"a\",\n\t\"ẚ\":\"a\",\n\t\"å\":\"a\",\n\t\"ǻ\":\"a\",\n\t\"ḁ\":\"a\",\n\t\"ⱥ\":\"a\",\n\t\"ã\":\"a\",\n\t\"ꜳ\":\"aa\",\n\t\"æ\":\"ae\",\n\t\"ǽ\":\"ae\",\n\t\"ǣ\":\"ae\",\n\t\"ꜵ\":\"ao\",\n\t\"ꜷ\":\"au\",\n\t\"ꜹ\":\"av\",\n\t\"ꜻ\":\"av\",\n\t\"ꜽ\":\"ay\",\n\t\"ḃ\":\"b\",\n\t\"ḅ\":\"b\",\n\t\"ɓ\":\"b\",\n\t\"ḇ\":\"b\",\n\t\"ᵬ\":\"b\",\n\t\"ᶀ\":\"b\",\n\t\"ƀ\":\"b\",\n\t\"ƃ\":\"b\",\n\t\"ɵ\":\"o\",\n\t\"ć\":\"c\",\n\t\"č\":\"c\",\n\t\"ç\":\"c\",\n\t\"ḉ\":\"c\",\n\t\"ĉ\":\"c\",\n\t\"ɕ\":\"c\",\n\t\"ċ\":\"c\",\n\t\"ƈ\":\"c\",\n\t\"ȼ\":\"c\",\n\t\"ď\":\"d\",\n\t\"ḑ\":\"d\",\n\t\"ḓ\":\"d\",\n\t\"ȡ\":\"d\",\n\t\"ḋ\":\"d\",\n\t\"ḍ\":\"d\",\n\t\"ɗ\":\"d\",\n\t\"ᶑ\":\"d\",\n\t\"ḏ\":\"d\",\n\t\"ᵭ\":\"d\",\n\t\"ᶁ\":\"d\",\n\t\"đ\":\"d\",\n\t\"ɖ\":\"d\",\n\t\"ƌ\":\"d\",\n\t\"ı\":\"i\",\n\t\"ȷ\":\"j\",\n\t\"ɟ\":\"j\",\n\t\"ʄ\":\"j\",\n\t\"dz\":\"dz\",\n\t\"dž\":\"dz\",\n\t\"é\":\"e\",\n\t\"ĕ\":\"e\",\n\t\"ě\":\"e\",\n\t\"ȩ\":\"e\",\n\t\"ḝ\":\"e\",\n\t\"ê\":\"e\",\n\t\"ế\":\"e\",\n\t\"ệ\":\"e\",\n\t\"ề\":\"e\",\n\t\"ể\":\"e\",\n\t\"ễ\":\"e\",\n\t\"ḙ\":\"e\",\n\t\"ë\":\"e\",\n\t\"ė\":\"e\",\n\t\"ẹ\":\"e\",\n\t\"ȅ\":\"e\",\n\t\"è\":\"e\",\n\t\"ẻ\":\"e\",\n\t\"ȇ\":\"e\",\n\t\"ē\":\"e\",\n\t\"ḗ\":\"e\",\n\t\"ḕ\":\"e\",\n\t\"ⱸ\":\"e\",\n\t\"ę\":\"e\",\n\t\"ᶒ\":\"e\",\n\t\"ɇ\":\"e\",\n\t\"ẽ\":\"e\",\n\t\"ḛ\":\"e\",\n\t\"ꝫ\":\"et\",\n\t\"ḟ\":\"f\",\n\t\"ƒ\":\"f\",\n\t\"ᵮ\":\"f\",\n\t\"ᶂ\":\"f\",\n\t\"ǵ\":\"g\",\n\t\"ğ\":\"g\",\n\t\"ǧ\":\"g\",\n\t\"ģ\":\"g\",\n\t\"ĝ\":\"g\",\n\t\"ġ\":\"g\",\n\t\"ɠ\":\"g\",\n\t\"ḡ\":\"g\",\n\t\"ᶃ\":\"g\",\n\t\"ǥ\":\"g\",\n\t\"ḫ\":\"h\",\n\t\"ȟ\":\"h\",\n\t\"ḩ\":\"h\",\n\t\"ĥ\":\"h\",\n\t\"ⱨ\":\"h\",\n\t\"ḧ\":\"h\",\n\t\"ḣ\":\"h\",\n\t\"ḥ\":\"h\",\n\t\"ɦ\":\"h\",\n\t\"ẖ\":\"h\",\n\t\"ħ\":\"h\",\n\t\"ƕ\":\"hv\",\n\t\"í\":\"i\",\n\t\"ĭ\":\"i\",\n\t\"ǐ\":\"i\",\n\t\"î\":\"i\",\n\t\"ï\":\"i\",\n\t\"ḯ\":\"i\",\n\t\"ị\":\"i\",\n\t\"ȉ\":\"i\",\n\t\"ì\":\"i\",\n\t\"ỉ\":\"i\",\n\t\"ȋ\":\"i\",\n\t\"ī\":\"i\",\n\t\"į\":\"i\",\n\t\"ᶖ\":\"i\",\n\t\"ɨ\":\"i\",\n\t\"ĩ\":\"i\",\n\t\"ḭ\":\"i\",\n\t\"ꝺ\":\"d\",\n\t\"ꝼ\":\"f\",\n\t\"ᵹ\":\"g\",\n\t\"ꞃ\":\"r\",\n\t\"ꞅ\":\"s\",\n\t\"ꞇ\":\"t\",\n\t\"ꝭ\":\"is\",\n\t\"ǰ\":\"j\",\n\t\"ĵ\":\"j\",\n\t\"ʝ\":\"j\",\n\t\"ɉ\":\"j\",\n\t\"ḱ\":\"k\",\n\t\"ǩ\":\"k\",\n\t\"ķ\":\"k\",\n\t\"ⱪ\":\"k\",\n\t\"ꝃ\":\"k\",\n\t\"ḳ\":\"k\",\n\t\"ƙ\":\"k\",\n\t\"ḵ\":\"k\",\n\t\"ᶄ\":\"k\",\n\t\"ꝁ\":\"k\",\n\t\"ꝅ\":\"k\",\n\t\"ĺ\":\"l\",\n\t\"ƚ\":\"l\",\n\t\"ɬ\":\"l\",\n\t\"ľ\":\"l\",\n\t\"ļ\":\"l\",\n\t\"ḽ\":\"l\",\n\t\"ȴ\":\"l\",\n\t\"ḷ\":\"l\",\n\t\"ḹ\":\"l\",\n\t\"ⱡ\":\"l\",\n\t\"ꝉ\":\"l\",\n\t\"ḻ\":\"l\",\n\t\"ŀ\":\"l\",\n\t\"ɫ\":\"l\",\n\t\"ᶅ\":\"l\",\n\t\"ɭ\":\"l\",\n\t\"ł\":\"l\",\n\t\"lj\":\"lj\",\n\t\"ſ\":\"s\",\n\t\"ẜ\":\"s\",\n\t\"ẛ\":\"s\",\n\t\"ẝ\":\"s\",\n\t\"ḿ\":\"m\",\n\t\"ṁ\":\"m\",\n\t\"ṃ\":\"m\",\n\t\"ɱ\":\"m\",\n\t\"ᵯ\":\"m\",\n\t\"ᶆ\":\"m\",\n\t\"ń\":\"n\",\n\t\"ň\":\"n\",\n\t\"ņ\":\"n\",\n\t\"ṋ\":\"n\",\n\t\"ȵ\":\"n\",\n\t\"ṅ\":\"n\",\n\t\"ṇ\":\"n\",\n\t\"ǹ\":\"n\",\n\t\"ɲ\":\"n\",\n\t\"ṉ\":\"n\",\n\t\"ƞ\":\"n\",\n\t\"ᵰ\":\"n\",\n\t\"ᶇ\":\"n\",\n\t\"ɳ\":\"n\",\n\t\"ñ\":\"n\",\n\t\"nj\":\"nj\",\n\t\"ó\":\"o\",\n\t\"ŏ\":\"o\",\n\t\"ǒ\":\"o\",\n\t\"ô\":\"o\",\n\t\"ố\":\"o\",\n\t\"ộ\":\"o\",\n\t\"ồ\":\"o\",\n\t\"ổ\":\"o\",\n\t\"ỗ\":\"o\",\n\t\"ö\":\"o\",\n\t\"ȫ\":\"o\",\n\t\"ȯ\":\"o\",\n\t\"ȱ\":\"o\",\n\t\"ọ\":\"o\",\n\t\"ő\":\"o\",\n\t\"ȍ\":\"o\",\n\t\"ò\":\"o\",\n\t\"ỏ\":\"o\",\n\t\"ơ\":\"o\",\n\t\"ớ\":\"o\",\n\t\"ợ\":\"o\",\n\t\"ờ\":\"o\",\n\t\"ở\":\"o\",\n\t\"ỡ\":\"o\",\n\t\"ȏ\":\"o\",\n\t\"ꝋ\":\"o\",\n\t\"ꝍ\":\"o\",\n\t\"ⱺ\":\"o\",\n\t\"ō\":\"o\",\n\t\"ṓ\":\"o\",\n\t\"ṑ\":\"o\",\n\t\"ǫ\":\"o\",\n\t\"ǭ\":\"o\",\n\t\"ø\":\"o\",\n\t\"ǿ\":\"o\",\n\t\"õ\":\"o\",\n\t\"ṍ\":\"o\",\n\t\"ṏ\":\"o\",\n\t\"ȭ\":\"o\",\n\t\"ƣ\":\"oi\",\n\t\"ꝏ\":\"oo\",\n\t\"ɛ\":\"e\",\n\t\"ᶓ\":\"e\",\n\t\"ɔ\":\"o\",\n\t\"ᶗ\":\"o\",\n\t\"ȣ\":\"ou\",\n\t\"ṕ\":\"p\",\n\t\"ṗ\":\"p\",\n\t\"ꝓ\":\"p\",\n\t\"ƥ\":\"p\",\n\t\"ᵱ\":\"p\",\n\t\"ᶈ\":\"p\",\n\t\"ꝕ\":\"p\",\n\t\"ᵽ\":\"p\",\n\t\"ꝑ\":\"p\",\n\t\"ꝙ\":\"q\",\n\t\"ʠ\":\"q\",\n\t\"ɋ\":\"q\",\n\t\"ꝗ\":\"q\",\n\t\"ŕ\":\"r\",\n\t\"ř\":\"r\",\n\t\"ŗ\":\"r\",\n\t\"ṙ\":\"r\",\n\t\"ṛ\":\"r\",\n\t\"ṝ\":\"r\",\n\t\"ȑ\":\"r\",\n\t\"ɾ\":\"r\",\n\t\"ᵳ\":\"r\",\n\t\"ȓ\":\"r\",\n\t\"ṟ\":\"r\",\n\t\"ɼ\":\"r\",\n\t\"ᵲ\":\"r\",\n\t\"ᶉ\":\"r\",\n\t\"ɍ\":\"r\",\n\t\"ɽ\":\"r\",\n\t\"ↄ\":\"c\",\n\t\"ꜿ\":\"c\",\n\t\"ɘ\":\"e\",\n\t\"ɿ\":\"r\",\n\t\"ś\":\"s\",\n\t\"ṥ\":\"s\",\n\t\"š\":\"s\",\n\t\"ṧ\":\"s\",\n\t\"ş\":\"s\",\n\t\"ŝ\":\"s\",\n\t\"ș\":\"s\",\n\t\"ṡ\":\"s\",\n\t\"ṣ\":\"s\",\n\t\"ṩ\":\"s\",\n\t\"ʂ\":\"s\",\n\t\"ᵴ\":\"s\",\n\t\"ᶊ\":\"s\",\n\t\"ȿ\":\"s\",\n\t\"ɡ\":\"g\",\n\t\"ᴑ\":\"o\",\n\t\"ᴓ\":\"o\",\n\t\"ᴝ\":\"u\",\n\t\"ť\":\"t\",\n\t\"ţ\":\"t\",\n\t\"ṱ\":\"t\",\n\t\"ț\":\"t\",\n\t\"ȶ\":\"t\",\n\t\"ẗ\":\"t\",\n\t\"ⱦ\":\"t\",\n\t\"ṫ\":\"t\",\n\t\"ṭ\":\"t\",\n\t\"ƭ\":\"t\",\n\t\"ṯ\":\"t\",\n\t\"ᵵ\":\"t\",\n\t\"ƫ\":\"t\",\n\t\"ʈ\":\"t\",\n\t\"ŧ\":\"t\",\n\t\"ᵺ\":\"th\",\n\t\"ɐ\":\"a\",\n\t\"ᴂ\":\"ae\",\n\t\"ǝ\":\"e\",\n\t\"ᵷ\":\"g\",\n\t\"ɥ\":\"h\",\n\t\"ʮ\":\"h\",\n\t\"ʯ\":\"h\",\n\t\"ᴉ\":\"i\",\n\t\"ʞ\":\"k\",\n\t\"ꞁ\":\"l\",\n\t\"ɯ\":\"m\",\n\t\"ɰ\":\"m\",\n\t\"ᴔ\":\"oe\",\n\t\"ɹ\":\"r\",\n\t\"ɻ\":\"r\",\n\t\"ɺ\":\"r\",\n\t\"ⱹ\":\"r\",\n\t\"ʇ\":\"t\",\n\t\"ʌ\":\"v\",\n\t\"ʍ\":\"w\",\n\t\"ʎ\":\"y\",\n\t\"ꜩ\":\"tz\",\n\t\"ú\":\"u\",\n\t\"ŭ\":\"u\",\n\t\"ǔ\":\"u\",\n\t\"û\":\"u\",\n\t\"ṷ\":\"u\",\n\t\"ü\":\"u\",\n\t\"ǘ\":\"u\",\n\t\"ǚ\":\"u\",\n\t\"ǜ\":\"u\",\n\t\"ǖ\":\"u\",\n\t\"ṳ\":\"u\",\n\t\"ụ\":\"u\",\n\t\"ű\":\"u\",\n\t\"ȕ\":\"u\",\n\t\"ù\":\"u\",\n\t\"ủ\":\"u\",\n\t\"ư\":\"u\",\n\t\"ứ\":\"u\",\n\t\"ự\":\"u\",\n\t\"ừ\":\"u\",\n\t\"ử\":\"u\",\n\t\"ữ\":\"u\",\n\t\"ȗ\":\"u\",\n\t\"ū\":\"u\",\n\t\"ṻ\":\"u\",\n\t\"ų\":\"u\",\n\t\"ᶙ\":\"u\",\n\t\"ů\":\"u\",\n\t\"ũ\":\"u\",\n\t\"ṹ\":\"u\",\n\t\"ṵ\":\"u\",\n\t\"ᵫ\":\"ue\",\n\t\"ꝸ\":\"um\",\n\t\"ⱴ\":\"v\",\n\t\"ꝟ\":\"v\",\n\t\"ṿ\":\"v\",\n\t\"ʋ\":\"v\",\n\t\"ᶌ\":\"v\",\n\t\"ⱱ\":\"v\",\n\t\"ṽ\":\"v\",\n\t\"ꝡ\":\"vy\",\n\t\"ẃ\":\"w\",\n\t\"ŵ\":\"w\",\n\t\"ẅ\":\"w\",\n\t\"ẇ\":\"w\",\n\t\"ẉ\":\"w\",\n\t\"ẁ\":\"w\",\n\t\"ⱳ\":\"w\",\n\t\"ẘ\":\"w\",\n\t\"ẍ\":\"x\",\n\t\"ẋ\":\"x\",\n\t\"ᶍ\":\"x\",\n\t\"ý\":\"y\",\n\t\"ŷ\":\"y\",\n\t\"ÿ\":\"y\",\n\t\"ẏ\":\"y\",\n\t\"ỵ\":\"y\",\n\t\"ỳ\":\"y\",\n\t\"ƴ\":\"y\",\n\t\"ỷ\":\"y\",\n\t\"ỿ\":\"y\",\n\t\"ȳ\":\"y\",\n\t\"ẙ\":\"y\",\n\t\"ɏ\":\"y\",\n\t\"ỹ\":\"y\",\n\t\"ź\":\"z\",\n\t\"ž\":\"z\",\n\t\"ẑ\":\"z\",\n\t\"ʑ\":\"z\",\n\t\"ⱬ\":\"z\",\n\t\"ż\":\"z\",\n\t\"ẓ\":\"z\",\n\t\"ȥ\":\"z\",\n\t\"ẕ\":\"z\",\n\t\"ᵶ\":\"z\",\n\t\"ᶎ\":\"z\",\n\t\"ʐ\":\"z\",\n\t\"ƶ\":\"z\",\n\t\"ɀ\":\"z\",\n\t\"ff\":\"ff\",\n\t\"ffi\":\"ffi\",\n\t\"ffl\":\"ffl\",\n\t\"fi\":\"fi\",\n\t\"fl\":\"fl\",\n\t\"ij\":\"ij\",\n\t\"œ\":\"oe\",\n\t\"st\":\"st\",\n\t\"ₐ\":\"a\",\n\t\"ₑ\":\"e\",\n\t\"ᵢ\":\"i\",\n\t\"ⱼ\":\"j\",\n\t\"ₒ\":\"o\",\n\t\"ᵣ\":\"r\",\n\t\"ᵤ\":\"u\",\n\t\"ᵥ\":\"v\",\n\t\"ₓ\":\"x\",\n\t\"Ё\":\"YO\",\n\t\"Й\":\"I\",\n\t\"Ц\":\"TS\",\n\t\"У\":\"U\",\n\t\"К\":\"K\",\n\t\"Е\":\"E\",\n\t\"Н\":\"N\",\n\t\"Г\":\"G\",\n\t\"Ш\":\"SH\",\n\t\"Щ\":\"SCH\",\n\t\"З\":\"Z\",\n\t\"Х\":\"H\",\n\t\"Ъ\":\"'\",\n\t\"ё\":\"yo\",\n\t\"й\":\"i\",\n\t\"ц\":\"ts\",\n\t\"у\":\"u\",\n\t\"к\":\"k\",\n\t\"е\":\"e\",\n\t\"н\":\"n\",\n\t\"г\":\"g\",\n\t\"ш\":\"sh\",\n\t\"щ\":\"sch\",\n\t\"з\":\"z\",\n\t\"х\":\"h\",\n\t\"ъ\":\"'\",\n\t\"Ф\":\"F\",\n\t\"Ы\":\"I\",\n\t\"В\":\"V\",\n\t\"А\":\"a\",\n\t\"П\":\"P\",\n\t\"Р\":\"R\",\n\t\"О\":\"O\",\n\t\"Л\":\"L\",\n\t\"Д\":\"D\",\n\t\"Ж\":\"ZH\",\n\t\"Э\":\"E\",\n\t\"ф\":\"f\",\n\t\"ы\":\"i\",\n\t\"в\":\"v\",\n\t\"а\":\"a\",\n\t\"п\":\"p\",\n\t\"р\":\"r\",\n\t\"о\":\"o\",\n\t\"л\":\"l\",\n\t\"д\":\"d\",\n\t\"ж\":\"zh\",\n\t\"э\":\"e\",\n\t\"Я\":\"Ya\",\n\t\"Ч\":\"CH\",\n\t\"С\":\"S\",\n\t\"М\":\"M\",\n\t\"И\":\"I\",\n\t\"Т\":\"T\",\n\t\"Ь\":\"'\",\n\t\"Б\":\"B\",\n\t\"Ю\":\"YU\",\n\t\"я\":\"ya\",\n\t\"ч\":\"ch\",\n\t\"с\":\"s\",\n\t\"м\":\"m\",\n\t\"и\":\"i\",\n\t\"т\":\"t\",\n\t\"ь\":\"'\",\n\t\"б\":\"b\",\n\t\"ю\":\"yu\",\n\t\"…\":\"...\"\n};\n\nexports.transliterate = function(str) {\n\treturn str.replace(/[^A-Za-z0-9\\[\\] ]/g,function(ch) {\n\t\treturn exports.transliterationPairs[ch] || ch\n\t});\n};\n\nexports.transliterateToSafeASCII = function(str) {\n\treturn str.replace(/[^\\x20-\\x7F]/g,function(ch) {\n\t\treturn exports.transliterationPairs[ch] || \"\"\n\t});\n};\n\n})();\n","type":"application/javascript","module-type":"utils"},"$:/core/modules/utils/utils.js":{"title":"$:/core/modules/utils/utils.js","text":"/*\\\ntitle: $:/core/modules/utils/utils.js\ntype: application/javascript\nmodule-type: utils\n\nVarious static utility functions.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar base64utf8 = require(\"$:/core/modules/utils/base64-utf8/base64-utf8.module.js\");\n\n/*\nDisplay a message, in colour if we're on a terminal\n*/\nexports.log = function(text,colour) {\n\tconsole.log($tw.node ? exports.terminalColour(colour) + text + exports.terminalColour() : text);\n};\n\nexports.terminalColour = function(colour) {\n\tif(!$tw.browser && $tw.node && process.stdout.isTTY) {\n\t\tif(colour) {\n\t\t\tvar code = exports.terminalColourLookup[colour];\n\t\t\tif(code) {\n\t\t\t\treturn \"\\x1b[\" + code + \"m\";\n\t\t\t}\n\t\t} else {\n\t\t\treturn \"\\x1b[0m\"; // Cancel colour\n\t\t}\n\t}\n\treturn \"\";\n};\n\nexports.terminalColourLookup = {\n\t\"black\": \"0;30\",\n\t\"red\": \"0;31\",\n\t\"green\": \"0;32\",\n\t\"brown/orange\": \"0;33\",\n\t\"blue\": \"0;34\",\n\t\"purple\": \"0;35\",\n\t\"cyan\": \"0;36\",\n\t\"light gray\": \"0;37\"\n};\n\n/*\nDisplay a warning, in colour if we're on a terminal\n*/\nexports.warning = function(text) {\n\texports.log(text,\"brown/orange\");\n};\n\n/*\nLog a table of name: value pairs\n*/\nexports.logTable = function(data) {\n\tif(console.table) {\n\t\tconsole.table(data);\n\t} else {\n\t\t$tw.utils.each(data,function(value,name) {\n\t\t\tconsole.log(name + \": \" + value);\n\t\t});\n\t}\n}\n\n/*\nReturn the integer represented by the str (string).\nReturn the dflt (default) parameter if str is not a base-10 number.\n*/\nexports.getInt = function(str,deflt) {\n\tvar i = parseInt(str,10);\n\treturn isNaN(i) ? deflt : i;\n}\n\n/*\nRepeatedly replaces a substring within a string. Like String.prototype.replace, but without any of the default special handling of $ sequences in the replace string\n*/\nexports.replaceString = function(text,search,replace) {\n\treturn text.replace(search,function() {\n\t\treturn replace;\n\t});\n};\n\n/*\nRepeats a string\n*/\nexports.repeat = function(str,count) {\n\tvar result = \"\";\n\tfor(var t=0;t<count;t++) {\n\t\tresult += str;\n\t}\n\treturn result;\n};\n\n/*\nCheck if a string starts with another string\n*/\nexports.startsWith = function(str,search) {\n\treturn str.substring(0, search.length) === search;\n};\n\n/*\nCheck if a string ends with another string\n*/\nexports.endsWith = function(str,search) {\n\treturn str.substring(str.length - search.length) === search;\n};\n\n/*\nTrim whitespace from the start and end of a string\nThanks to Steven Levithan, http://blog.stevenlevithan.com/archives/faster-trim-javascript\n*/\nexports.trim = function(str) {\n\tif(typeof str === \"string\") {\n\t\treturn str.replace(/^\\s\\s*/, '').replace(/\\s\\s*$/, '');\n\t} else {\n\t\treturn str;\n\t}\n};\n\nexports.trimPrefix = function(str,unwanted) {\n\tif(typeof str === \"string\" && typeof unwanted === \"string\") {\n\t\tif(unwanted === \"\") {\n\t\t\treturn str.replace(/^\\s\\s*/, '');\n\t\t} else {\n\t\t\t// Safely regexp-escape the unwanted text\n\t\t\tunwanted = unwanted.replace(/[\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n\t\t\tvar regex = new RegExp('^(' + unwanted + ')+');\n\t\t\treturn str.replace(regex, '');\n\t\t}\n\t} else {\n\t\treturn str;\n\t}\n};\n\nexports.trimSuffix = function(str,unwanted) {\n\tif(typeof str === \"string\" && typeof unwanted === \"string\") {\n\t\tif(unwanted === \"\") {\n\t\t\treturn str.replace(/\\s\\s*$/, '');\n\t\t} else {\n\t\t\t// Safely regexp-escape the unwanted text\n\t\t\tunwanted = unwanted.replace(/[\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n\t\t\tvar regex = new RegExp('(' + unwanted + ')+$');\n\t\t\treturn str.replace(regex, '');\n\t\t}\n\t} else {\n\t\treturn str;\n\t}\n};\n\n/*\nConvert a string to sentence case (ie capitalise first letter)\n*/\nexports.toSentenceCase = function(str) {\n\treturn (str || \"\").replace(/^\\S/, function(c) {return c.toUpperCase();});\n}\n\n/*\nConvert a string to title case (ie capitalise each initial letter)\n*/\nexports.toTitleCase = function(str) {\n\treturn (str || \"\").replace(/(^|\\s)\\S/g, function(c) {return c.toUpperCase();});\n}\n\n/*\nFind the line break preceding a given position in a string\nReturns position immediately after that line break, or the start of the string\n*/\nexports.findPrecedingLineBreak = function(text,pos) {\n\tvar result = text.lastIndexOf(\"\\n\",pos - 1);\n\tif(result === -1) {\n\t\tresult = 0;\n\t} else {\n\t\tresult++;\n\t\tif(text.charAt(result) === \"\\r\") {\n\t\t\tresult++;\n\t\t}\n\t}\n\treturn result;\n};\n\n/*\nFind the line break following a given position in a string\n*/\nexports.findFollowingLineBreak = function(text,pos) {\n\t// Cut to just past the following line break, or to the end of the text\n\tvar result = text.indexOf(\"\\n\",pos);\n\tif(result === -1) {\n\t\tresult = text.length;\n\t} else {\n\t\tif(text.charAt(result) === \"\\r\") {\n\t\t\tresult++;\n\t\t}\n\t}\n\treturn result;\n};\n\n/*\nReturn the number of keys in an object\n*/\nexports.count = function(object) {\n\treturn Object.keys(object || {}).length;\n};\n\n/*\nDetermine whether an array-item is an object-property\n*/\nexports.hopArray = function(object,array) {\n\tfor(var i=0; i<array.length; i++) {\n\t\tif($tw.utils.hop(object,array[i])) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n};\n\n/*\nRemove entries from an array\n\tarray: array to modify\n\tvalue: a single value to remove, or an array of values to remove\n*/\nexports.removeArrayEntries = function(array,value) {\n\tvar t,p;\n\tif($tw.utils.isArray(value)) {\n\t\tfor(t=0; t<value.length; t++) {\n\t\t\tp = array.indexOf(value[t]);\n\t\t\tif(p !== -1) {\n\t\t\t\tarray.splice(p,1);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tp = array.indexOf(value);\n\t\tif(p !== -1) {\n\t\t\tarray.splice(p,1);\n\t\t}\n\t}\n\treturn array;\n};\n\n/*\nCheck whether any members of a hashmap are present in another hashmap\n*/\nexports.checkDependencies = function(dependencies,changes) {\n\tvar hit = false;\n\t$tw.utils.each(changes,function(change,title) {\n\t\tif($tw.utils.hop(dependencies,title)) {\n\t\t\thit = true;\n\t\t}\n\t});\n\treturn hit;\n};\n\nexports.extend = function(object /* [, src] */) {\n\t$tw.utils.each(Array.prototype.slice.call(arguments, 1), function(source) {\n\t\tif(source) {\n\t\t\tfor(var property in source) {\n\t\t\t\tobject[property] = source[property];\n\t\t\t}\n\t\t}\n\t});\n\treturn object;\n};\n\nexports.deepCopy = function(object) {\n\tvar result,t;\n\tif($tw.utils.isArray(object)) {\n\t\t// Copy arrays\n\t\tresult = object.slice(0);\n\t} else if(typeof object === \"object\") {\n\t\tresult = {};\n\t\tfor(t in object) {\n\t\t\tif(object[t] !== undefined) {\n\t\t\t\tresult[t] = $tw.utils.deepCopy(object[t]);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tresult = object;\n\t}\n\treturn result;\n};\n\nexports.extendDeepCopy = function(object,extendedProperties) {\n\tvar result = $tw.utils.deepCopy(object),t;\n\tfor(t in extendedProperties) {\n\t\tif(extendedProperties[t] !== undefined) {\n\t\t\tresult[t] = $tw.utils.deepCopy(extendedProperties[t]);\n\t\t}\n\t}\n\treturn result;\n};\n\nexports.deepFreeze = function deepFreeze(object) {\n\tvar property, key;\n\tif(object) {\n\t\tObject.freeze(object);\n\t\tfor(key in object) {\n\t\t\tproperty = object[key];\n\t\t\tif($tw.utils.hop(object,key) && (typeof property === \"object\") && !Object.isFrozen(property)) {\n\t\t\t\tdeepFreeze(property);\n\t\t\t}\n\t\t}\n\t}\n};\n\nexports.slowInSlowOut = function(t) {\n\treturn (1 - ((Math.cos(t * Math.PI) + 1) / 2));\n};\n\nexports.formatTitleString = function(template,options) {\n\tvar base = options.base || \"\",\n\t\tseparator = options.separator || \"\",\n\t\tcounter = options.counter || \"\";\n\tvar result = \"\",\n\t\tt = template,\n\t\tmatches = [\n\t\t\t[/^\\$basename\\$/i, function() {\n\t\t\t\treturn base;\n\t\t\t}],\n\t\t\t[/^\\$count:(\\d+)\\$/i, function(match) {\n\t\t\t\treturn $tw.utils.pad(counter,match[1]);\n\t\t\t}],\n\t\t\t[/^\\$separator\\$/i, function() {\n\t\t\t\treturn separator;\n\t\t\t}],\n\t\t\t[/^\\$count\\$/i, function() {\n\t\t\t\treturn counter + \"\";\n\t\t\t}]\n\t\t];\n\twhile(t.length){\n\t\tvar matchString = \"\",\n\t\t\tfound = false;\n\t\t$tw.utils.each(matches, function(m) {\n\t\t\tvar match = m[0].exec(t);\n\t\t\tif(match) {\n\t\t\t\tfound = true;\n\t\t\t\tmatchString = m[1].call(null,match);\n\t\t\t\tt = t.substr(match[0].length);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\t\tif(found) {\n\t\t\tresult += matchString;\n\t\t} else {\n\t\t\tresult += t.charAt(0);\n\t\t\tt = t.substr(1);\n\t\t}\n\t}\n\tresult = result.replace(/\\\\(.)/g,\"$1\");\n\treturn result;\n};\n\nexports.formatDateString = function(date,template) {\n\tvar result = \"\",\n\t\tt = template,\n\t\tmatches = [\n\t\t\t[/^TIMESTAMP/, function() {\n\t\t\t\treturn date.getTime();\n\t\t\t}],\n\t\t\t[/^0hh12/, function() {\n\t\t\t\treturn $tw.utils.pad($tw.utils.getHours12(date));\n\t\t\t}],\n\t\t\t[/^wYYYY/, function() {\n\t\t\t\treturn $tw.utils.pad($tw.utils.getYearForWeekNo(date),4);\n\t\t\t}],\n\t\t\t[/^hh12/, function() {\n\t\t\t\treturn $tw.utils.getHours12(date);\n\t\t\t}],\n\t\t\t[/^DDth/, function() {\n\t\t\t\treturn date.getDate() + $tw.utils.getDaySuffix(date);\n\t\t\t}],\n\t\t\t[/^YYYY/, function() {\n\t\t\t\treturn $tw.utils.pad(date.getFullYear(),4);\n\t\t\t}],\n\t\t\t[/^aYYYY/, function() {\n\t\t\t\treturn $tw.utils.pad(Math.abs(date.getFullYear()),4);\n\t\t\t}],\n\t\t\t[/^\\{era:([^,\\|}]*)\\|([^}\\|]*)\\|([^}]*)\\}/, function(match) {\n\t\t\t\tvar year = date.getFullYear();\n\t\t\t\treturn year === 0 ? match[2] : (year < 0 ? match[1] : match[3]);\n\t\t\t}],\n\t\t\t[/^0hh/, function() {\n\t\t\t\treturn $tw.utils.pad(date.getHours());\n\t\t\t}],\n\t\t\t[/^0mm/, function() {\n\t\t\t\treturn $tw.utils.pad(date.getMinutes());\n\t\t\t}],\n\t\t\t[/^0ss/, function() {\n\t\t\t\treturn $tw.utils.pad(date.getSeconds());\n\t\t\t}],\n\t\t\t[/^0XXX/, function() {\n\t\t\t\treturn $tw.utils.pad(date.getMilliseconds(),3);\n\t\t\t}],\n\t\t\t[/^0DD/, function() {\n\t\t\t\treturn $tw.utils.pad(date.getDate());\n\t\t\t}],\n\t\t\t[/^0MM/, function() {\n\t\t\t\treturn $tw.utils.pad(date.getMonth()+1);\n\t\t\t}],\n\t\t\t[/^0WW/, function() {\n\t\t\t\treturn $tw.utils.pad($tw.utils.getWeek(date));\n\t\t\t}],\n\t\t\t[/^0ddddd/, function() {\n\t\t\t\treturn $tw.utils.pad(Math.floor((date - new Date(date.getFullYear(), 0, 0)) / 1000 / 60 / 60 / 24),3);\n\t\t\t}],\n\t\t\t[/^ddddd/, function() {\n\t\t\t\treturn Math.floor((date - new Date(date.getFullYear(), 0, 0)) / 1000 / 60 / 60 / 24);\n\t\t\t}],\n\t\t\t[/^dddd/, function() {\n\t\t\t\treturn [7,1,2,3,4,5,6][date.getDay()];\n\t\t\t}],\n\t\t\t[/^ddd/, function() {\n\t\t\t\treturn $tw.language.getString(\"Date/Short/Day/\" + date.getDay());\n\t\t\t}],\n\t\t\t[/^mmm/, function() {\n\t\t\t\treturn $tw.language.getString(\"Date/Short/Month/\" + (date.getMonth() + 1));\n\t\t\t}],\n\t\t\t[/^DDD/, function() {\n\t\t\t\treturn $tw.language.getString(\"Date/Long/Day/\" + date.getDay());\n\t\t\t}],\n\t\t\t[/^MMM/, function() {\n\t\t\t\treturn $tw.language.getString(\"Date/Long/Month/\" + (date.getMonth() + 1));\n\t\t\t}],\n\t\t\t[/^TZD/, function() {\n\t\t\t\tvar tz = date.getTimezoneOffset(),\n\t\t\t\tatz = Math.abs(tz);\n\t\t\t\treturn (tz < 0 ? '+' : '-') + $tw.utils.pad(Math.floor(atz / 60)) + ':' + $tw.utils.pad(atz % 60);\n\t\t\t}],\n\t\t\t[/^wYY/, function() {\n\t\t\t\treturn $tw.utils.pad($tw.utils.getYearForWeekNo(date) - 2000);\n\t\t\t}],\n\t\t\t[/^[ap]m/, function() {\n\t\t\t\treturn $tw.utils.getAmPm(date).toLowerCase();\n\t\t\t}],\n\t\t\t[/^hh/, function() {\n\t\t\t\treturn date.getHours();\n\t\t\t}],\n\t\t\t[/^mm/, function() {\n\t\t\t\treturn date.getMinutes();\n\t\t\t}],\n\t\t\t[/^ss/, function() {\n\t\t\t\treturn date.getSeconds();\n\t\t\t}],\n\t\t\t[/^XXX/, function() {\n\t\t\t\treturn date.getMilliseconds();\n\t\t\t}],\n\t\t\t[/^[AP]M/, function() {\n\t\t\t\treturn $tw.utils.getAmPm(date).toUpperCase();\n\t\t\t}],\n\t\t\t[/^DD/, function() {\n\t\t\t\treturn date.getDate();\n\t\t\t}],\n\t\t\t[/^MM/, function() {\n\t\t\t\treturn date.getMonth() + 1;\n\t\t\t}],\n\t\t\t[/^WW/, function() {\n\t\t\t\treturn $tw.utils.getWeek(date);\n\t\t\t}],\n\t\t\t[/^YY/, function() {\n\t\t\t\treturn $tw.utils.pad(date.getFullYear() - 2000);\n\t\t\t}]\n\t\t];\n\t// If the user wants everything in UTC, shift the datestamp\n\t// Optimize for format string that essentially means\n\t// 'return raw UTC (tiddlywiki style) date string.'\n\tif(t.indexOf(\"[UTC]\") == 0 ) {\n\t\tif(t == \"[UTC]YYYY0MM0DD0hh0mm0ssXXX\")\n\t\t\treturn $tw.utils.stringifyDate(date || new Date());\n\t\tvar offset = date.getTimezoneOffset() ; // in minutes\n\t\tdate = new Date(date.getTime()+offset*60*1000) ;\n\t\tt = t.substr(5) ;\n\t}\n\twhile(t.length){\n\t\tvar matchString = \"\";\n\t\t$tw.utils.each(matches, function(m) {\n\t\t\tvar match = m[0].exec(t);\n\t\t\tif(match) {\n\t\t\t\tmatchString = m[1].call(null,match);\n\t\t\t\tt = t.substr(match[0].length);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\t\tif(matchString) {\n\t\t\tresult += matchString;\n\t\t} else {\n\t\t\tresult += t.charAt(0);\n\t\t\tt = t.substr(1);\n\t\t}\n\t}\n\tresult = result.replace(/\\\\(.)/g,\"$1\");\n\treturn result;\n};\n\nexports.getAmPm = function(date) {\n\treturn $tw.language.getString(\"Date/Period/\" + (date.getHours() >= 12 ? \"pm\" : \"am\"));\n};\n\nexports.getDaySuffix = function(date) {\n\treturn $tw.language.getString(\"Date/DaySuffix/\" + date.getDate());\n};\n\nexports.getWeek = function(date) {\n\tvar dt = new Date(date.getTime());\n\tvar d = dt.getDay();\n\tif(d === 0) {\n\t\td = 7; // JavaScript Sun=0, ISO Sun=7\n\t}\n\tdt.setTime(dt.getTime() + (4 - d) * 86400000);// shift day to Thurs of same week to calculate weekNo\n\tvar x = new Date(dt.getFullYear(),0,1);\n\tvar n = Math.floor((dt.getTime() - x.getTime()) / 86400000);\n\treturn Math.floor(n / 7) + 1;\n};\n\nexports.getYearForWeekNo = function(date) {\n\tvar dt = new Date(date.getTime());\n\tvar d = dt.getDay();\n\tif(d === 0) {\n\t\td = 7; // JavaScript Sun=0, ISO Sun=7\n\t}\n\tdt.setTime(dt.getTime() + (4 - d) * 86400000);// shift day to Thurs of same week\n\treturn dt.getFullYear();\n};\n\nexports.getHours12 = function(date) {\n\tvar h = date.getHours();\n\treturn h > 12 ? h-12 : ( h > 0 ? h : 12 );\n};\n\n/*\nConvert a date delta in milliseconds into a string representation of \"23 seconds ago\", \"27 minutes ago\" etc.\n\tdelta: delta in milliseconds\nReturns an object with these members:\n\tdescription: string describing the delta period\n\tupdatePeriod: time in millisecond until the string will be inaccurate\n*/\nexports.getRelativeDate = function(delta) {\n\tvar futurep = false;\n\tif(delta < 0) {\n\t\tdelta = -1 * delta;\n\t\tfuturep = true;\n\t}\n\tvar units = [\n\t\t{name: \"Years\",   duration:      365 * 24 * 60 * 60 * 1000},\n\t\t{name: \"Months\",  duration: (365/12) * 24 * 60 * 60 * 1000},\n\t\t{name: \"Days\",    duration:            24 * 60 * 60 * 1000},\n\t\t{name: \"Hours\",   duration:                 60 * 60 * 1000},\n\t\t{name: \"Minutes\", duration:                      60 * 1000},\n\t\t{name: \"Seconds\", duration:                           1000}\n\t];\n\tfor(var t=0; t<units.length; t++) {\n\t\tvar result = Math.floor(delta / units[t].duration);\n\t\tif(result >= 2) {\n\t\t\treturn {\n\t\t\t\tdelta: delta,\n\t\t\t\tdescription: $tw.language.getString(\n\t\t\t\t\t\"RelativeDate/\" + (futurep ? \"Future\" : \"Past\") + \"/\" + units[t].name,\n\t\t\t\t\t{variables:\n\t\t\t\t\t\t{period: result.toString()}\n\t\t\t\t\t}\n\t\t\t\t),\n\t\t\t\tupdatePeriod: units[t].duration\n\t\t\t};\n\t\t}\n\t}\n\treturn {\n\t\tdelta: delta,\n\t\tdescription: $tw.language.getString(\n\t\t\t\"RelativeDate/\" + (futurep ? \"Future\" : \"Past\") + \"/Second\",\n\t\t\t{variables:\n\t\t\t\t{period: \"1\"}\n\t\t\t}\n\t\t),\n\t\tupdatePeriod: 1000\n\t};\n};\n\n// Convert & to \"&amp;\", < to \"&lt;\", > to \"&gt;\", \" to \"&quot;\"\nexports.htmlEncode = function(s) {\n\tif(s) {\n\t\treturn s.toString().replace(/&/mg,\"&amp;\").replace(/</mg,\"&lt;\").replace(/>/mg,\"&gt;\").replace(/\\\"/mg,\"&quot;\");\n\t} else {\n\t\treturn \"\";\n\t}\n};\n\n// Converts like htmlEncode, but forgets the double quote for brevity\nexports.htmlTextEncode = function(s) {\n\tif(s) {\n\t\treturn s.toString().replace(/&/mg,\"&amp;\").replace(/</mg,\"&lt;\").replace(/>/mg,\"&gt;\");\n\t} else {\n\t\treturn \"\";\n\t}\n};\n\n// Converts all HTML entities to their character equivalents\nexports.entityDecode = function(s) {\n\tvar converter = String.fromCodePoint || String.fromCharCode,\n\t\te = s.substr(1,s.length-2), // Strip the & and the ;\n\t\tc;\n\tif(e.charAt(0) === \"#\") {\n\t\tif(e.charAt(1) === \"x\" || e.charAt(1) === \"X\") {\n\t\t\tc = parseInt(e.substr(2),16);\n\t\t} else {\n\t\t\tc = parseInt(e.substr(1),10);\n\t\t}\n\t\tif(isNaN(c)) {\n\t\t\treturn s;\n\t\t} else {\n\t\t\treturn converter(c);\n\t\t}\n\t} else {\n\t\tc = $tw.config.htmlEntities[e];\n\t\tif(c) {\n\t\t\treturn converter(c);\n\t\t} else {\n\t\t\treturn s; // Couldn't convert it as an entity, just return it raw\n\t\t}\n\t}\n};\n\nexports.unescapeLineBreaks = function(s) {\n\treturn s.replace(/\\\\n/mg,\"\\n\").replace(/\\\\b/mg,\" \").replace(/\\\\s/mg,\"\\\\\").replace(/\\r/mg,\"\");\n};\n\n/*\n * Returns an escape sequence for given character. Uses \\x for characters <=\n * 0xFF to save space, \\u for the rest.\n *\n * The code needs to be in sync with th code template in the compilation\n * function for \"action\" nodes.\n */\n// Copied from peg.js, thanks to David Majda\nexports.escape = function(ch) {\n\tvar charCode = ch.charCodeAt(0);\n\tif(charCode <= 0xFF) {\n\t\treturn '\\\\x' + $tw.utils.pad(charCode.toString(16).toUpperCase());\n\t} else {\n\t\treturn '\\\\u' + $tw.utils.pad(charCode.toString(16).toUpperCase(),4);\n\t}\n};\n\n// Turns a string into a legal JavaScript string\n// Copied from peg.js, thanks to David Majda\nexports.stringify = function(s, rawUnicode) {\n\t/*\n\t* ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a string\n\t* literal except for the closing quote character, backslash, carriage return,\n\t* line separator, paragraph separator, and line feed. Any character may\n\t* appear in the form of an escape sequence.\n\t*\n\t* For portability, we also escape all non-ASCII characters.\n\t*/\n\tvar regex = rawUnicode ? /[\\x00-\\x1f]/g : /[\\x00-\\x1f\\x80-\\uFFFF]/g;\n\treturn (s || \"\")\n\t\t.replace(/\\\\/g, '\\\\\\\\')            // backslash\n\t\t.replace(/\"/g, '\\\\\"')              // double quote character\n\t\t.replace(/'/g, \"\\\\'\")              // single quote character\n\t\t.replace(/\\r/g, '\\\\r')             // carriage return\n\t\t.replace(/\\n/g, '\\\\n')             // line feed\n\t\t.replace(regex, exports.escape);   // non-ASCII characters\n};\n\n// Turns a string into a legal JSON string\n// Derived from peg.js, thanks to David Majda\nexports.jsonStringify = function(s, rawUnicode) {\n\t// See http://www.json.org/\n\tvar regex = rawUnicode ? /[\\x00-\\x1f]/g : /[\\x00-\\x1f\\x80-\\uFFFF]/g;\n\treturn (s || \"\")\n\t\t.replace(/\\\\/g, '\\\\\\\\')            // backslash\n\t\t.replace(/\"/g, '\\\\\"')              // double quote character\n\t\t.replace(/\\r/g, '\\\\r')             // carriage return\n\t\t.replace(/\\n/g, '\\\\n')             // line feed\n\t\t.replace(/\\x08/g, '\\\\b')           // backspace\n\t\t.replace(/\\x0c/g, '\\\\f')           // formfeed\n\t\t.replace(/\\t/g, '\\\\t')             // tab\n\t\t.replace(regex,function(s) {\n\t\t\treturn '\\\\u' + $tw.utils.pad(s.charCodeAt(0).toString(16).toUpperCase(),4);\n\t\t}); // non-ASCII characters\n};\n\n/*\nEscape the RegExp special characters with a preceding backslash\n*/\nexports.escapeRegExp = function(s) {\n    return s.replace(/[\\-\\/\\\\\\^\\$\\*\\+\\?\\.\\(\\)\\|\\[\\]\\{\\}]/g, '\\\\$&');\n};\n\n/*\nExtended version of encodeURIComponent that encodes additional characters including\nthose that are illegal within filepaths on various platforms including Windows\n*/\nexports.encodeURIComponentExtended = function(s) {\n\treturn encodeURIComponent(s).replace(/[!'()*]/g,function(c) {\n\t\treturn \"%\" + c.charCodeAt(0).toString(16).toUpperCase();\n\t});\n};\n\n// Checks whether a link target is external, i.e. not a tiddler title\nexports.isLinkExternal = function(to) {\n\tvar externalRegExp = /^(?:file|http|https|mailto|ftp|irc|news|obsidian|data|skype):[^\\s<>{}\\[\\]`|\"\\\\^]+(?:\\/|\\b)/i;\n\treturn externalRegExp.test(to);\n};\n\nexports.nextTick = function(fn) {\n/*global window: false */\n\tif(typeof process === \"undefined\") {\n\t\t// Apparently it would be faster to use postMessage - http://dbaron.org/log/20100309-faster-timeouts\n\t\twindow.setTimeout(fn,0);\n\t} else {\n\t\tprocess.nextTick(fn);\n\t}\n};\n\n/*\nConvert a hyphenated CSS property name into a camel case one\n*/\nexports.unHyphenateCss = function(propName) {\n\treturn propName.replace(/-([a-z])/gi, function(match0,match1) {\n\t\treturn match1.toUpperCase();\n\t});\n};\n\n/*\nConvert a camelcase CSS property name into a dashed one (\"backgroundColor\" --> \"background-color\")\n*/\nexports.hyphenateCss = function(propName) {\n\treturn propName.replace(/([A-Z])/g, function(match0,match1) {\n\t\treturn \"-\" + match1.toLowerCase();\n\t});\n};\n\n/*\nParse a text reference of one of these forms:\n* title\n* !!field\n* title!!field\n* title##index\n* etc\nReturns an object with the following fields, all optional:\n* title: tiddler title\n* field: tiddler field name\n* index: JSON property index\n*/\nexports.parseTextReference = function(textRef) {\n\t// Separate out the title, field name and/or JSON indices\n\tvar reTextRef = /(?:(.*?)!!(.+))|(?:(.*?)##(.+))|(.*)/mg,\n\t\tmatch = reTextRef.exec(textRef),\n\t\tresult = {};\n\tif(match && reTextRef.lastIndex === textRef.length) {\n\t\t// Return the parts\n\t\tif(match[1]) {\n\t\t\tresult.title = match[1];\n\t\t}\n\t\tif(match[2]) {\n\t\t\tresult.field = match[2];\n\t\t}\n\t\tif(match[3]) {\n\t\t\tresult.title = match[3];\n\t\t}\n\t\tif(match[4]) {\n\t\t\tresult.index = match[4];\n\t\t}\n\t\tif(match[5]) {\n\t\t\tresult.title = match[5];\n\t\t}\n\t} else {\n\t\t// If we couldn't parse it\n\t\tresult.title = textRef\n\t}\n\treturn result;\n};\n\n/*\nChecks whether a string is a valid fieldname\n*/\nexports.isValidFieldName = function(name) {\n\tif(!name || typeof name !== \"string\") {\n\t\treturn false;\n\t}\n\t// Since v5.2.x, there are no restrictions on characters in field names\n\treturn name;\n};\n\n/*\nExtract the version number from the meta tag or from the boot file\n*/\n\n// Browser version\nexports.extractVersionInfo = function() {\n\tif($tw.packageInfo) {\n\t\treturn $tw.packageInfo.version;\n\t} else {\n\t\tvar metatags = document.getElementsByTagName(\"meta\");\n\t\tfor(var t=0; t<metatags.length; t++) {\n\t\t\tvar m = metatags[t];\n\t\t\tif(m.name === \"tiddlywiki-version\") {\n\t\t\t\treturn m.content;\n\t\t\t}\n\t\t}\n\t}\n\treturn null;\n};\n\n/*\nGet the animation duration in ms\n*/\nexports.getAnimationDuration = function() {\n\treturn parseInt($tw.wiki.getTiddlerText(\"$:/config/AnimationDuration\",\"400\"),10) || 0;\n};\n\n/*\nHash a string to a number\nDerived from http://stackoverflow.com/a/15710692\n*/\nexports.hashString = function(str) {\n\treturn str.split(\"\").reduce(function(a,b) {\n\t\ta = ((a << 5) - a) + b.charCodeAt(0);\n\t\treturn a & a;\n\t},0);\n};\n\n/*\nCryptographic hash function as used by sha256 filter operator\noptions.length .. number of characters returned defaults to 64\n*/\nexports.sha256 = function(str, options) {\n\toptions = options || {}\n\treturn $tw.sjcl.codec.hex.fromBits($tw.sjcl.hash.sha256.hash(str)).substr(0,options.length || 64);\n}\n\n/*\nBase64 utility functions that work in either browser or Node.js\n*/\nif(typeof window !== 'undefined') {\n\texports.btoa = function(binstr) { return window.btoa(binstr); }\n\texports.atob = function(b64) { return window.atob(b64); }\n} else {\n\texports.btoa = function(binstr) {\n\t\treturn Buffer.from(binstr, 'binary').toString('base64');\n\t}\n\texports.atob = function(b64) {\n\t\treturn Buffer.from(b64, 'base64').toString('binary');\n\t}\n}\n\n/*\nDecode a base64 string\n*/\nexports.base64Decode = function(string64,binary,urlsafe) {\n\tvar encoded = urlsafe ? string64.replace(/_/g,'/').replace(/-/g,'+') : string64;\n\tif(binary) return exports.atob(encoded)\n\telse return base64utf8.base64.decode.call(base64utf8,encoded);\n};\n\n/*\nEncode a string to base64\n*/\nexports.base64Encode = function(string64,binary,urlsafe) {\n\tvar encoded;\n\tif(binary) encoded = exports.btoa(string64);\n\telse encoded = base64utf8.base64.encode.call(base64utf8,string64);\n\tif(urlsafe) {\n\t\tencoded = encoded.replace(/\\+/g,'-').replace(/\\//g,'_');\n\t}\n\treturn encoded;\n};\n\n/*\nConvert a hashmap into a tiddler dictionary format sequence of name:value pairs\n*/\nexports.makeTiddlerDictionary = function(data) {\n\tvar output = [];\n\tfor(var name in data) {\n\t\toutput.push(name + \": \" + data[name]);\n\t}\n\treturn output.join(\"\\n\");\n};\n\n/*\nHigh resolution microsecond timer for profiling\n*/\nexports.timer = function(base) {\n\tvar m;\n\tif($tw.node) {\n\t\tvar r = process.hrtime();\n\t\tm =  r[0] * 1e3 + (r[1] / 1e6);\n\t} else if(window.performance) {\n\t\tm = performance.now();\n\t} else {\n\t\tm = Date.now();\n\t}\n\tif(typeof base !== \"undefined\") {\n\t\tm = m - base;\n\t}\n\treturn m;\n};\n\n/*\nConvert text and content type to a data URI\n*/\nexports.makeDataUri = function(text,type,_canonical_uri) {\n\ttype = type || \"text/vnd.tiddlywiki\";\n\tvar typeInfo = $tw.config.contentTypeInfo[type] || $tw.config.contentTypeInfo[\"text/plain\"],\n\t\tisBase64 = typeInfo.encoding === \"base64\",\n\t\tparts = [];\n\tif(_canonical_uri) {\n\t\tparts.push(_canonical_uri);\n\t} else {\n\t\tparts.push(\"data:\");\n\t\tparts.push(type);\n\t\tparts.push(isBase64 ? \";base64\" : \"\");\n\t\tparts.push(\",\");\n\t\tparts.push(isBase64 ? text : encodeURIComponent(text));\n\t}\n\treturn parts.join(\"\");\n};\n\n/*\nUseful for finding out the fully escaped CSS selector equivalent to a given tag. For example:\n\n$tw.utils.tagToCssSelector(\"$:/tags/Stylesheet\") --> tc-tagged-\\%24\\%3A\\%2Ftags\\%2FStylesheet\n*/\nexports.tagToCssSelector = function(tagName) {\n\treturn \"tc-tagged-\" + encodeURIComponent(tagName).replace(/[!\"#$%&'()*+,\\-./:;<=>?@[\\\\\\]^`{\\|}~,]/mg,function(c) {\n\t\treturn \"\\\\\" + c;\n\t});\n};\n\n/*\nIE does not have sign function\n*/\nexports.sign = Math.sign || function(x) {\n\tx = +x; // convert to a number\n\tif(x === 0 || isNaN(x)) {\n\t\treturn x;\n\t}\n\treturn x > 0 ? 1 : -1;\n};\n\n/*\nIE does not have an endsWith function\n*/\nexports.strEndsWith = function(str,ending,position) {\n\tif(str.endsWith) {\n\t\treturn str.endsWith(ending,position);\n\t} else {\n\t\tif(typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > str.length) {\n\t\t\tposition = str.length;\n\t\t}\n\t\tposition -= ending.length;\n\t\tvar lastIndex = str.indexOf(ending, position);\n\t\treturn lastIndex !== -1 && lastIndex === position;\n\t}\n};\n\n/*\nReturn system information useful for debugging\n*/\nexports.getSystemInfo = function(str,ending,position) {\n\tvar results = [],\n\t\tsave = function(desc,value) {\n\t\t\tresults.push(desc + \": \" + value);\n\t\t};\n\tif($tw.browser) {\n\t\tsave(\"User Agent\",navigator.userAgent);\n\t\tsave(\"Online Status\",window.navigator.onLine);\n\t}\n\tif($tw.node) {\n\t\tsave(\"Node Version\",process.version);\n\t}\n\treturn results.join(\"\\n\");\n};\n\nexports.parseNumber = function(str) {\n\treturn parseFloat(str) || 0;\n};\n\nexports.parseInt = function(str) {\n\treturn parseInt(str,10) || 0;\n};\n\nexports.stringifyNumber = function(num) {\n\treturn num + \"\";\n};\n\nexports.makeCompareFunction = function(type,options) {\n\toptions = options || {};\n\t// set isCaseSensitive to true if not defined in options\n\tvar isCaseSensitive = (options.isCaseSensitive === false) ? false : true,\n\t\tgt = options.invert ? -1 : +1,\n\t\tlt = options.invert ? +1 : -1,\n\t\tcompare = function(a,b) {\n\t\t\tif(a > b) {\n\t\t\t\treturn gt ;\n\t\t\t} else if(a < b) {\n\t\t\t\treturn lt;\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t},\n\t\ttypes = {\n\t\t\t\"number\": function(a,b) {\n\t\t\t\treturn compare($tw.utils.parseNumber(a),$tw.utils.parseNumber(b));\n\t\t\t},\n\t\t\t\"integer\": function(a,b) {\n\t\t\t\treturn compare($tw.utils.parseInt(a),$tw.utils.parseInt(b));\n\t\t\t},\n\t\t\t\"string\": function(a,b) {\n\t\t\t\tif(!isCaseSensitive) {\n\t\t\t\t\ta = a.toLowerCase();\n\t\t\t\t\tb = b.toLowerCase();\n\t\t\t\t}\n\t\t\t\treturn compare(\"\" + a,\"\" + b);\n\t\t\t},\n\t\t\t\"date\": function(a,b) {\n\t\t\t\tvar dateA = $tw.utils.parseDate(a),\n\t\t\t\t\tdateB = $tw.utils.parseDate(b);\n\t\t\t\tif(!isFinite(dateA)) {\n\t\t\t\t\tdateA = new Date(0);\n\t\t\t\t}\n\t\t\t\tif(!isFinite(dateB)) {\n\t\t\t\t\tdateB = new Date(0);\n\t\t\t\t}\n\t\t\t\treturn compare(dateA,dateB);\n\t\t\t},\n\t\t\t\"version\": function(a,b) {\n\t\t\t\treturn $tw.utils.compareVersions(a,b);\n\t\t\t},\n\t\t\t\"alphanumeric\": function(a,b) {\n\t\t\t\tif(!isCaseSensitive) {\n\t\t\t\t\ta = a.toLowerCase();\n\t\t\t\t\tb = b.toLowerCase();\n\t\t\t\t}\n\t\t\t\treturn options.invert ? b.localeCompare(a,undefined,{numeric: true,sensitivity: \"base\"}) : a.localeCompare(b,undefined,{numeric: true,sensitivity: \"base\"});\n\t\t\t}\n\t\t};\n\treturn (types[type] || types[options.defaultType] || types.number);\n};\n\n})();\n","type":"application/javascript","module-type":"utils"},"$:/core/modules/widgets/action-confirm.js":{"title":"$:/core/modules/widgets/action-confirm.js","text":"/*\\\n\ntitle: $:/core/modules/widgets/action-confirm.js\ntype: application/javascript\nmodule-type: widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar ConfirmWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nConfirmWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nConfirmWidget.prototype.render = function(parent,nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.parentDomNode = parent;\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nConfirmWidget.prototype.execute = function() {\n\tthis.message = this.getAttribute(\"$message\",$tw.language.getString(\"ConfirmAction\"));\n\tthis.prompt = (this.getAttribute(\"$prompt\",\"yes\") == \"no\" ? false : true);\n\tthis.makeChildWidgets();\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nConfirmWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes[\"$message\"] || changedAttributes[\"$prompt\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nInvoke the action associated with this widget\n*/\nConfirmWidget.prototype.invokeAction = function(triggeringWidget,event) {\n\tvar invokeActions = true,\n\t\thandled = true,\n\t    \twin = event && event.event && event.event.view ? event.event.view : window;\n\tif(this.prompt) {\n\t\tinvokeActions = win.confirm(this.message);\n\t}\n\tif(invokeActions) {\n\t\thandled = this.invokeActions(triggeringWidget,event);\n\t}\n\treturn handled;\n};\n\nConfirmWidget.prototype.allowActionPropagation = function() {\n\treturn false;\n};\n\nexports[\"action-confirm\"] = ConfirmWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/action-createtiddler.js":{"title":"$:/core/modules/widgets/action-createtiddler.js","text":"/*\\\ntitle: $:/core/modules/widgets/action-createtiddler.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to create a new tiddler with a unique name and specified fields.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw:false, require:false, exports:false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar CreateTiddlerWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nCreateTiddlerWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nCreateTiddlerWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Render children\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nCreateTiddlerWidget.prototype.execute = function() {\n\tthis.actionBaseTitle = this.getAttribute(\"$basetitle\");\n\tthis.hasBase = !!this.actionBaseTitle;\n\tthis.actionSaveTitle = this.getAttribute(\"$savetitle\");\n\tthis.actionSaveDraftTitle = this.getAttribute(\"$savedrafttitle\");\n\tthis.actionTimestamp = this.getAttribute(\"$timestamp\",\"yes\") === \"yes\";\n\t//Following params are new since 5.1.22\n\tthis.actionTemplate = this.getAttribute(\"$template\");\n\tthis.useTemplate = !!this.actionTemplate;\n\tthis.actionOverwrite = this.getAttribute(\"$overwrite\",\"no\");\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nCreateTiddlerWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif($tw.utils.count(changedAttributes) > 0) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nInvoke the action associated with this widget\n*/\nCreateTiddlerWidget.prototype.invokeAction = function(triggeringWidget,event) {\n\tvar title = this.wiki.getTiddlerText(\"$:/language/DefaultNewTiddlerTitle\"), // Get the initial new-tiddler title\n\t\tfields = {},\n\t\tcreationFields,\n\t\tmodificationFields;\n\t$tw.utils.each(this.attributes,function(attribute,name) {\n\t\tif(name.charAt(0) !== \"$\") {\n\t\t\tfields[name] = attribute;\n\t\t}\n\t});\n\tif(this.actionTimestamp) {\n\t\tcreationFields = this.wiki.getCreationFields();\n\t\tmodificationFields = this.wiki.getModificationFields();\n\t}\n\tif(this.hasBase && this.actionOverwrite === \"no\") {\n\t\ttitle = this.wiki.generateNewTitle(this.actionBaseTitle);\n\t} else if (this.hasBase && this.actionOverwrite === \"yes\") {\n\t\ttitle = this.actionBaseTitle\n\t}\n\t// NO $basetitle BUT $template parameter is available\n\t// the title MUST be unique, otherwise the template would be overwritten\n\tif (!this.hasBase && this.useTemplate) {\n\t\ttitle = this.wiki.generateNewTitle(this.actionTemplate);\n\t} else if (!this.hasBase && !this.useTemplate) {\n\t\t// If no $basetitle and no $template then use initial title\n\t\ttitle = this.wiki.generateNewTitle(title);\n\t}\n\tvar templateTiddler = this.wiki.getTiddler(this.actionTemplate) || {};\n\tthis.wiki.addTiddler(new $tw.Tiddler(templateTiddler.fields,creationFields,fields,modificationFields,{title: title}));\n\tvar draftTitle = this.wiki.generateDraftTitle(title);\n\tif(this.actionSaveTitle) {\n\t\tthis.wiki.setTextReference(this.actionSaveTitle,title,this.getVariable(\"currentTiddler\"));\n\t}\n\tif(this.actionSaveDraftTitle) {\n\t\tthis.wiki.setTextReference(this.actionSaveDraftTitle,draftTitle,this.getVariable(\"currentTiddler\"));\n\t}\n\tthis.setVariable(\"createTiddler-title\",title);\n\tthis.setVariable(\"createTiddler-draftTitle\",draftTitle);\n\tthis.refreshChildren();\n\treturn true; // Action was invoked\n};\n\nexports[\"action-createtiddler\"] = CreateTiddlerWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/action-deletefield.js":{"title":"$:/core/modules/widgets/action-deletefield.js","text":"/*\\\ntitle: $:/core/modules/widgets/action-deletefield.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to delete fields of a tiddler.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar DeleteFieldWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nDeleteFieldWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nDeleteFieldWidget.prototype.render = function(parent,nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n\n/*\nCompute the internal state of the widget\n*/\nDeleteFieldWidget.prototype.execute = function() {\n\tthis.actionTiddler = this.getAttribute(\"$tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.actionField = this.getAttribute(\"$field\",null);\n\tthis.actionTimestamp = this.getAttribute(\"$timestamp\",\"yes\") === \"yes\";\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nDeleteFieldWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes[\"$tiddler\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nInvoke the action associated with this widget\n*/\nDeleteFieldWidget.prototype.invokeAction = function(triggeringWidget,event) {\n\tvar self = this,\n\t\ttiddler = this.wiki.getTiddler(self.actionTiddler),\n\t\tremoveFields = {},\n\t\thasChanged = false;\n\tif((this.actionField !== null) && tiddler) {\n\t\tremoveFields[this.actionField] = undefined;\n\t\tif(this.actionField in tiddler.fields) {\n\t\t\thasChanged = true;\n\t\t}\n\t}\n\tif(tiddler) {\n\t\t$tw.utils.each(this.attributes,function(attribute,name) {\n\t\t\tif(name.charAt(0) !== \"$\" && name !== \"title\") {\n\t\t\t\tremoveFields[name] = undefined;\n\t\t\t\tif(name in tiddler.fields) {\n\t\t\t\t\thasChanged = true;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tif(hasChanged) {\n\t\t\tvar creationFields = this.actionTimestamp ? this.wiki.getCreationFields() : {};\n\t\t\tvar modificationFields = this.actionTimestamp ? this.wiki.getModificationFields() : {};\n\t\t\tthis.wiki.addTiddler(new $tw.Tiddler(creationFields,tiddler,removeFields,modificationFields));\n\t\t}\n\t}\n\treturn true; // Action was invoked\n};\n\nexports[\"action-deletefield\"] = DeleteFieldWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/action-deletetiddler.js":{"title":"$:/core/modules/widgets/action-deletetiddler.js","text":"/*\\\ntitle: $:/core/modules/widgets/action-deletetiddler.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to delete a tiddler.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar DeleteTiddlerWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nDeleteTiddlerWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nDeleteTiddlerWidget.prototype.render = function(parent,nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n\n/*\nCompute the internal state of the widget\n*/\nDeleteTiddlerWidget.prototype.execute = function() {\n\tthis.actionFilter = this.getAttribute(\"$filter\");\n\tthis.actionTiddler = this.getAttribute(\"$tiddler\");\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nDeleteTiddlerWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes[\"$filter\"] || changedAttributes[\"$tiddler\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nInvoke the action associated with this widget\n*/\nDeleteTiddlerWidget.prototype.invokeAction = function(triggeringWidget,event) {\n\tvar tiddlers = [];\n\tif(this.actionFilter) {\n\t\ttiddlers = this.wiki.filterTiddlers(this.actionFilter,this);\n\t}\n\tif(this.actionTiddler) {\n\t\ttiddlers.push(this.actionTiddler);\n\t}\n\tfor(var t=0; t<tiddlers.length; t++) {\n\t\tthis.wiki.deleteTiddler(tiddlers[t]);\n\t}\n\treturn true; // Action was invoked\n};\n\nexports[\"action-deletetiddler\"] = DeleteTiddlerWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/action-listops.js":{"title":"$:/core/modules/widgets/action-listops.js","text":"/*\\\ntitle: $:/core/modules/widgets/action-listops.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to apply list operations to any tiddler field (defaults to the 'list' field of the current tiddler)\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\nvar ActionListopsWidget = function(parseTreeNode, options) {\n\tthis.initialise(parseTreeNode, options);\n};\n/**\n * Inherit from the base widget class\n */\nActionListopsWidget.prototype = new Widget();\n/**\n * Render this widget into the DOM\n */\nActionListopsWidget.prototype.render = function(parent, nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n/**\n * Compute the internal state of the widget\n */\nActionListopsWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.target = this.getAttribute(\"$tiddler\", this.getVariable(\n\t\t\"currentTiddler\"));\n\tthis.filter = this.getAttribute(\"$filter\");\n\tthis.subfilter = this.getAttribute(\"$subfilter\");\n\tthis.listField = this.getAttribute(\"$field\", \"list\");\n\tthis.listIndex = this.getAttribute(\"$index\");\n\tthis.filtertags = this.getAttribute(\"$tags\");\n};\n/**\n * \tRefresh the widget by ensuring our attributes are up to date\n */\nActionListopsWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif($tw.utils.count(changedAttributes) > 0) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n/**\n * \tInvoke the action associated with this widget\n */\nActionListopsWidget.prototype.invokeAction = function(triggeringWidget,\n\tevent) {\n\t//Apply the specified filters to the lists\n\tvar field = this.listField,\n\t\tindex,\n\t\tlist = this.listField;\n\tif(this.listIndex) {\n\t\tfield = undefined;\n\t\tindex = this.listIndex;\n\t\tlist = this.listIndex;\n\t}\n\tif(this.filter) {\n\t\tthis.wiki.setText(this.target, field, index, $tw.utils.stringifyList(\n\t\t\tthis.wiki\n\t\t\t.filterTiddlers(this.filter, this)));\n\t}\n\tif(this.subfilter) {\n\t\tvar inputList = this.wiki.getTiddlerList(this.target,field,index),\n\t\t\tsubfilter = \"[all[]] \" + this.subfilter;\n\t\tthis.wiki.setText(this.target, field, index, $tw.utils.stringifyList(this.wiki.filterTiddlers(subfilter,this,this.wiki.makeTiddlerIterator(inputList))));\n\t}\n\tif(this.filtertags) {\n\t\tvar tiddler = this.wiki.getTiddler(this.target),\n\t\t\toldtags = tiddler ? (tiddler.fields.tags || []).slice(0) : [],\n\t\t\ttagfilter = $tw.utils.stringifyList(oldtags) + \" \" + this.filtertags,\n\t\t\tnewtags = this.wiki.filterTiddlers(tagfilter,this);\n\t\tif($tw.utils.stringifyList(oldtags.sort()) !== $tw.utils.stringifyList(newtags.sort())) {\n\t\t\tthis.wiki.setText(this.target,\"tags\",undefined,$tw.utils.stringifyList(newtags));\n\t\t}\n\t}\n\treturn true; // Action was invoked\n};\n\nexports[\"action-listops\"] = ActionListopsWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/action-log.js":{"title":"$:/core/modules/widgets/action-log.js","text":"/*\\\ntitle: $:/core/modules/widgets/action-log.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to log debug messages\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar LogWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nLogWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nLogWidget.prototype.render = function(parent,nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n\nLogWidget.prototype.execute = function(){\n\tthis.message = this.getAttribute(\"$$message\",\"debug\");\n\tthis.logAll = this.getAttribute(\"$$all\",\"no\") === \"yes\" ? true : false;\n\tthis.filter = this.getAttribute(\"$$filter\");\n}\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nLogWidget.prototype.refresh = function(changedTiddlers) {\n\tthis.refreshSelf();\n\treturn true;\n};\n\n/*\nInvoke the action associated with this widget\n*/\nLogWidget.prototype.invokeAction = function(triggeringWidget,event) {\n\tthis.log();\n\treturn true; // Action was invoked\n};\n\nLogWidget.prototype.log = function() {\n\tvar data = {},\n\t\tdataCount,\n\t\tallVars = {},\n\t\tfilteredVars;\n\n\t$tw.utils.each(this.attributes,function(attribute,name) {\n\t\tif(name.substring(0,2) !== \"$$\") {\n\t\t\tdata[name] = attribute;\n\t\t}\n\t});\n\n\tfor(var v in this.variables) {\n\t\tvar variable = this.parentWidget && this.parentWidget.variables[v];\n\t\tif(variable && variable.isFunctionDefinition) {\n\t\t\tallVars[v] = variable.value;\n\t\t} else {\n\t\t\tallVars[v]  = this.getVariable(v,{defaultValue:\"\"});\n\t\t}\n\t}\n\tif(this.filter) {\n\t\tfilteredVars = this.wiki.compileFilter(this.filter).call(this.wiki,this.wiki.makeTiddlerIterator(allVars));\n\t\t$tw.utils.each(filteredVars,function(name) {\n\t\t\tdata[name] = allVars[name];\n\t\t});\n\t}\n\tdataCount = $tw.utils.count(data);\n\n\tconsole.group(this.message);\n\tif(dataCount > 0) {\n\t\t$tw.utils.logTable(data);\n\t}\n\tif(this.logAll || !dataCount) {\n\t\tconsole.groupCollapsed(\"All variables\");\n\t\t$tw.utils.logTable(allVars);\n\t\tconsole.groupEnd();\n\t}\n\tconsole.groupEnd();\n}\n\nexports[\"action-log\"] = LogWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/action-navigate.js":{"title":"$:/core/modules/widgets/action-navigate.js","text":"/*\\\ntitle: $:/core/modules/widgets/action-navigate.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to navigate to a tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar NavigateWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nNavigateWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nNavigateWidget.prototype.render = function(parent,nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n\n/*\nCompute the internal state of the widget\n*/\nNavigateWidget.prototype.execute = function() {\n\tthis.actionTo = this.getAttribute(\"$to\");\n\tthis.actionScroll = this.getAttribute(\"$scroll\");\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nNavigateWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes[\"$to\"] || changedAttributes[\"$scroll\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nInvoke the action associated with this widget\n*/\nNavigateWidget.prototype.invokeAction = function(triggeringWidget,event) {\n\tevent = event || {};\n\tvar bounds = triggeringWidget && triggeringWidget.getBoundingClientRect && triggeringWidget.getBoundingClientRect(),\n\t\tsuppressNavigation = event.metaKey || event.ctrlKey || (event.button === 1);\n\tif(this.actionScroll === \"yes\") {\n\t\tsuppressNavigation = false;\n\t} else if(this.actionScroll === \"no\") {\n\t\tsuppressNavigation = true;\n\t}\n\tthis.dispatchEvent({\n\t\ttype: \"tm-navigate\",\n\t\tnavigateTo: this.actionTo === undefined ? this.getVariable(\"currentTiddler\") : this.actionTo,\n\t\tnavigateFromTitle: this.getVariable(\"storyTiddler\"),\n\t\tnavigateFromNode: triggeringWidget,\n\t\tnavigateFromClientRect: bounds && { top: bounds.top, left: bounds.left, width: bounds.width, right: bounds.right, bottom: bounds.bottom, height: bounds.height\n\t\t},\n\t\tnavigateFromClientTop: bounds && bounds.top,\n\t\tnavigateFromClientLeft: bounds && bounds.left,\n\t\tnavigateFromClientWidth: bounds && bounds.width,\n\t\tnavigateFromClientRight: bounds && bounds.right,\n\t\tnavigateFromClientBottom: bounds && bounds.bottom,\n\t\tnavigateFromClientHeight: bounds && bounds.height,\n\t\tnavigateSuppressNavigation: suppressNavigation,\n\t\tmetaKey: event.metaKey,\n\t\tctrlKey: event.ctrlKey,\n\t\taltKey: event.altKey,\n\t\tshiftKey: event.shiftKey,\n\t\tevent: event\n\t});\n\treturn true; // Action was invoked\n};\n\nexports[\"action-navigate\"] = NavigateWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/action-popup.js":{"title":"$:/core/modules/widgets/action-popup.js","text":"/*\\\ntitle: $:/core/modules/widgets/action-popup.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to trigger a popup.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar Popup = require(\"$:/core/modules/utils/dom/popup.js\");\n\nvar ActionPopupWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nActionPopupWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nActionPopupWidget.prototype.render = function(parent,nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n\n/*\nCompute the internal state of the widget\n*/\nActionPopupWidget.prototype.execute = function() {\n\tthis.actionState = this.getAttribute(\"$state\");\n\tthis.actionCoords = this.getAttribute(\"$coords\");\n\tthis.floating = this.getAttribute(\"$floating\",\"no\") === \"yes\";\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nActionPopupWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes[\"$state\"] || changedAttributes[\"$coords\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nInvoke the action associated with this widget\n*/\nActionPopupWidget.prototype.invokeAction = function(triggeringWidget,event) {\n\t// Trigger the popup\n\tvar coordinates = Popup.parseCoordinates(this.actionCoords || \"\");\n\tif(coordinates) {\n\t\t$tw.popup.triggerPopup({\n\t\t\tdomNode: null,\n\t\t\tdomNodeRect: {\n\t\t\t\tleft: coordinates.left,\n\t\t\t\ttop: coordinates.top,\n\t\t\t\twidth: coordinates.width,\n\t\t\t\theight: coordinates.height\n\t\t\t},\n\t\t\ttitle: this.actionState,\n\t\t\twiki: this.wiki,\n\t\t\tfloating: this.floating,\n\t\t\tabsolute: coordinates.absolute\n\t\t});\n\t} else {\n\t\t$tw.popup.cancel(0);\n\t}\n\treturn true; // Action was invoked\n};\n\nexports[\"action-popup\"] = ActionPopupWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/action-sendmessage.js":{"title":"$:/core/modules/widgets/action-sendmessage.js","text":"/*\\\ntitle: $:/core/modules/widgets/action-sendmessage.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to send a message\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar SendMessageWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nSendMessageWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nSendMessageWidget.prototype.render = function(parent,nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n\n/*\nCompute the internal state of the widget\n*/\nSendMessageWidget.prototype.execute = function() {\n\tthis.actionMessage = this.getAttribute(\"$message\");\n\tthis.actionParam = this.getAttribute(\"$param\");\n\tthis.actionName = this.getAttribute(\"$name\");\n\tthis.actionValue = this.getAttribute(\"$value\",\"\");\n\tthis.actionNames = this.getAttribute(\"$names\");\n\tthis.actionValues = this.getAttribute(\"$values\");\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nSendMessageWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(Object.keys(changedAttributes).length) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nInvoke the action associated with this widget\n*/\nSendMessageWidget.prototype.invokeAction = function(triggeringWidget,event) {\n\t// Get the string parameter\n\tvar param = this.actionParam;\n\t// Assemble the parameters as a hashmap\n\tvar paramObject = Object.create(null);\n\t// Add names/values pairs if present\n\tif(this.actionNames && this.actionValues) {\n\t\tvar names = this.wiki.filterTiddlers(this.actionNames,this),\n\t\t\tvalues = this.wiki.filterTiddlers(this.actionValues,this);\n\t\t$tw.utils.each(names,function(name,index) {\n\t\t\tparamObject[name] = values[index] || \"\";\n\t\t});\n\t}\n\t// Add raw parameters\n\t$tw.utils.each(this.attributes,function(attribute,name) {\n\t\tif(name.charAt(0) !== \"$\") {\n\t\t\tparamObject[name] = attribute;\n\t\t}\n\t});\n\t// Add name/value pair if present\n\tif(this.actionName) {\n\t\tparamObject[this.actionName] = this.actionValue;\n\t}\n\t// Dispatch the message\n\tvar params = {\n\t\ttype: this.actionMessage,\n\t\tparam: param,\n\t\tparamObject: paramObject,\n\t\tevent: event,\n\t\ttiddlerTitle: this.getVariable(\"currentTiddler\"),\n\t\tnavigateFromTitle: this.getVariable(\"storyTiddler\")\n\t};\n\tthis.dispatchEvent(params);\n\treturn true; // Action was invoked\n};\n\nexports[\"action-sendmessage\"] = SendMessageWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/action-setfield.js":{"title":"$:/core/modules/widgets/action-setfield.js","text":"/*\\\ntitle: $:/core/modules/widgets/action-setfield.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to set a single field or index on a tiddler.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar SetFieldWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nSetFieldWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nSetFieldWidget.prototype.render = function(parent,nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n\n/*\nCompute the internal state of the widget\n*/\nSetFieldWidget.prototype.execute = function() {\n\tthis.actionTiddler = this.getAttribute(\"$tiddler\") || (!this.hasParseTreeNodeAttribute(\"$tiddler\") && this.getVariable(\"currentTiddler\"));\n\tthis.actionField = this.getAttribute(\"$field\");\n\tthis.actionIndex = this.getAttribute(\"$index\");\n\tthis.actionValue = this.getAttribute(\"$value\");\n\tthis.actionTimestamp = this.getAttribute(\"$timestamp\",\"yes\") === \"yes\";\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nSetFieldWidget.prototype.refresh = function(changedTiddlers) {\n\t// Nothing to refresh\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nInvoke the action associated with this widget\n*/\nSetFieldWidget.prototype.invokeAction = function(triggeringWidget,event) {\n\tvar self = this,\n\t\toptions = {};\n\tif(this.actionTiddler) {\n\t\toptions.suppressTimestamp = !this.actionTimestamp;\n\t\tif((typeof this.actionField == \"string\") || (typeof this.actionIndex == \"string\")  || (typeof this.actionValue == \"string\")) {\n\t\t\tthis.wiki.setText(this.actionTiddler,this.actionField,this.actionIndex,this.actionValue,options);\n\t\t}\n\t\t$tw.utils.each(this.attributes,function(attribute,name) {\n\t\t\tif(name.charAt(0) !== \"$\") {\n\t\t\t\tself.wiki.setText(self.actionTiddler,name,undefined,attribute,options);\n\t\t\t}\n\t\t});\n\t}\n\treturn true; // Action was invoked\n};\n\nexports[\"action-setfield\"] = SetFieldWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/action-setmultiplefields.js":{"title":"$:/core/modules/widgets/action-setmultiplefields.js","text":"/*\\\ntitle: $:/core/modules/widgets/action-setmultiplefields.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to set multiple fields or indexes on a tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar SetMultipleFieldsWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nSetMultipleFieldsWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nSetMultipleFieldsWidget.prototype.render = function(parent,nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n\n/*\nCompute the internal state of the widget\n*/\nSetMultipleFieldsWidget.prototype.execute = function() {\n\tthis.actionTiddler = this.getAttribute(\"$tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.actionFields = this.getAttribute(\"$fields\");\n\tthis.actionIndexes = this.getAttribute(\"$indexes\");\n\tthis.actionValues = this.getAttribute(\"$values\");\n\tthis.actionTimestamp = this.getAttribute(\"$timestamp\",\"yes\") === \"yes\";\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nSetMultipleFieldsWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes[\"$tiddler\"] || changedAttributes[\"$fields\"] || changedAttributes[\"$indexes\"] || changedAttributes[\"$values\"] || changedAttributes[\"$timestamp\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nInvoke the action associated with this widget\n*/\nSetMultipleFieldsWidget.prototype.invokeAction = function(triggeringWidget,event) {\n\tvar tiddler = this.wiki.getTiddler(this.actionTiddler),\n\t\tnames, values = this.wiki.filterTiddlers(this.actionValues,this);\n\tif(this.actionFields) {\n\t\tvar additions = {};\n\t\tnames = this.wiki.filterTiddlers(this.actionFields,this);\n\t\t$tw.utils.each(names,function(fieldname,index) {\n\t\t\tadditions[fieldname] = values[index] || \"\";\n\t\t});\n\t\tvar creationFields = this.actionTimestamp ? this.wiki.getCreationFields() : undefined,\n\t\t\tmodificationFields = this.actionTimestamp ? this.wiki.getModificationFields() : undefined;\n\t\tthis.wiki.addTiddler(new $tw.Tiddler(creationFields,tiddler,{title: this.actionTiddler},modificationFields,additions));\n\t} else if(this.actionIndexes) {\n\t\tvar data = this.wiki.getTiddlerData(this.actionTiddler,Object.create(null));\n\t\tnames = this.wiki.filterTiddlers(this.actionIndexes,this);\n\t\t$tw.utils.each(names,function(name,index) {\n\t\t\tdata[name] = values[index] || \"\";\n\t\t});\n\t\tthis.wiki.setTiddlerData(this.actionTiddler,data,{},{suppressTimestamp: !this.actionTimestamp});\n\t}\n\treturn true; // Action was invoked\n};\n\nexports[\"action-setmultiplefields\"] = SetMultipleFieldsWidget;\n\n})();\n\t","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/browse.js":{"title":"$:/core/modules/widgets/browse.js","text":"/*\\\ntitle: $:/core/modules/widgets/browse.js\ntype: application/javascript\nmodule-type: widget\n\nBrowse widget for browsing for files to import\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar BrowseWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nBrowseWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nBrowseWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Remember parent\n\tthis.parentDomNode = parent;\n\t// Compute attributes and execute state\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Create element\n\tvar domNode = this.document.createElement(\"input\");\n\tdomNode.setAttribute(\"type\",\"file\");\n\tif(this.browseMultiple) {\n\t\tdomNode.setAttribute(\"multiple\",\"multiple\");\n\t}\n\tif(this.tooltip) {\n\t\tdomNode.setAttribute(\"title\",this.tooltip);\n\t}\n\t// Nw.js supports \"nwsaveas\" to force a \"save as\" dialogue that allows a new or existing file to be selected\n\tif(this.nwsaveas) {\n\t\tdomNode.setAttribute(\"nwsaveas\",this.nwsaveas);\n\t}\n\tif(this.accept) {\n\t\tdomNode.setAttribute(\"accept\",this.accept);\n\t}\n\t// Nw.js supports \"webkitdirectory\" and \"nwdirectory\" to allow a directory to be selected\n\tif(this.webkitdirectory) {\n\t\tdomNode.setAttribute(\"webkitdirectory\",this.webkitdirectory);\n\t}\n\tif(this.nwdirectory) {\n\t\tdomNode.setAttribute(\"nwdirectory\",this.nwdirectory);\n\t}\n\t// Add a click event handler\n\tdomNode.addEventListener(\"change\",function (event) {\n\t\tif(self.message) {\n\t\t\tself.dispatchEvent({type: self.message, param: self.param, files: event.target.files});\n\t\t} else {\n\t\t\tself.wiki.readFiles(event.target.files,{\n\t\t\t\tcallback: function(tiddlerFieldsArray) {\n\t\t\t\t\tself.dispatchEvent({type: \"tm-import-tiddlers\", param: JSON.stringify(tiddlerFieldsArray)});\n\t\t\t\t},\n\t\t\t\tdeserializer: self.deserializer\n\t\t\t});\n\t\t}\n\t\treturn false;\n\t},false);\n\t// Assign data- attributes\n\tthis.assignAttributes(domNode,{\n\t\tsourcePrefix: \"data-\",\n\t\tdestPrefix: \"data-\"\n\t});\n\t// Insert element\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nBrowseWidget.prototype.execute = function() {\n\tthis.browseMultiple = this.getAttribute(\"multiple\");\n\tthis.deserializer = this.getAttribute(\"deserializer\");\n\tthis.message = this.getAttribute(\"message\");\n\tthis.param = this.getAttribute(\"param\");\n\tthis.tooltip = this.getAttribute(\"tooltip\");\n\tthis.nwsaveas = this.getAttribute(\"nwsaveas\");\n\tthis.accept = this.getAttribute(\"accept\");\n\tthis.webkitdirectory = this.getAttribute(\"webkitdirectory\");\n\tthis.nwdirectory = this.getAttribute(\"nwdirectory\");\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nBrowseWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif($tw.utils.count(changedAttributes) > 0) {\n\t\tthis.refreshSelf();\n\t\treturn true;\t\n\t}\n\treturn false;\n};\n\nexports.browse = BrowseWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/button.js":{"title":"$:/core/modules/widgets/button.js","text":"/*\\\ntitle: $:/core/modules/widgets/button.js\ntype: application/javascript\nmodule-type: widget\n\nButton widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar Popup = require(\"$:/core/modules/utils/dom/popup.js\");\n\nvar ButtonWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nButtonWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nButtonWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this,\n\t\ttag = \"button\",\n\t\tdomNode;\n\t// Remember parent\n\tthis.parentDomNode = parent;\n\t// Compute attributes and execute state\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Create element\n\tif(this.buttonTag && $tw.config.htmlUnsafeElements.indexOf(this.buttonTag) === -1) {\n\t\ttag = this.buttonTag;\n\t}\n\tdomNode = this.document.createElement(tag);\n\tthis.domNode = domNode;\n\t// Assign classes\n\tvar classes = this[\"class\"].split(\" \") || [],\n\t\tisPoppedUp = (this.popup || this.popupTitle) && this.isPoppedUp();\n\tif(this.selectedClass) {\n\t\tif((this.set || this.setTitle) && this.setTo && this.isSelected()) {\n\t\t\t$tw.utils.pushTop(classes, this.selectedClass.split(\" \"));\n\t\t\tdomNode.setAttribute(\"aria-checked\", \"true\");\n\t\t}\n\t\tif(isPoppedUp) {\n\t\t\t$tw.utils.pushTop(classes,this.selectedClass.split(\" \"));\n\t\t}\n\t}\n\tif(isPoppedUp) {\n\t\t$tw.utils.pushTop(classes,\"tc-popup-handle\");\n\t}\n\tdomNode.className = classes.join(\" \");\n\t// Assign data- attributes\n\tthis.assignAttributes(domNode,{\n\t\tsourcePrefix: \"data-\",\n\t\tdestPrefix: \"data-\"\n\t});\n\t// Assign other attributes\n\tif(this.style) {\n\t\tdomNode.setAttribute(\"style\",this.style);\n\t}\n\tif(this.tooltip) {\n\t\tdomNode.setAttribute(\"title\",this.tooltip);\n\t}\n\tif(this[\"aria-label\"]) {\n\t\tdomNode.setAttribute(\"aria-label\",this[\"aria-label\"]);\n\t}\n\tif (this.role) {\n\t\tdomNode.setAttribute(\"role\", this.role);\n\t}\n\tif(this.popup || this.popupTitle) {\n\t\tdomNode.setAttribute(\"aria-expanded\",isPoppedUp ? \"true\" : \"false\");\n\t}\n\t// Set the tabindex\n\tif(this.tabIndex) {\n\t\tdomNode.setAttribute(\"tabindex\",this.tabIndex);\n\t}\n\tif(this.isDisabled === \"yes\") {\n\t\tdomNode.setAttribute(\"disabled\",true);\n\t}\n\t// Add a click event handler\n\tdomNode.addEventListener(\"click\",function (event) {\n\t\tvar handled = false;\n\t\tif(self.invokeActions(self,event)) {\n\t\t\thandled = true;\n\t\t}\n\t\tif(self.to) {\n\t\t\tself.navigateTo(event);\n\t\t\thandled = true;\n\t\t}\n\t\tif(self.message) {\n\t\t\tself.dispatchMessage(event);\n\t\t\thandled = true;\n\t\t}\n\t\tif(self.popup || self.popupTitle) {\n\t\t\tself.triggerPopup(event);\n\t\t\thandled = true;\n\t\t}\n\t\tif(self.set || self.setTitle) {\n\t\t\tself.setTiddler();\n\t\t\thandled = true;\n\t\t}\n\t\tif(self.actions) {\n\t\t\tvar modifierKey = $tw.keyboardManager.getEventModifierKeyDescriptor(event);\n\t\t\tself.invokeActionString(self.actions,self,event,{modifier: modifierKey});\n\t\t}\n\t\tif(handled) {\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\t}\n\t\treturn handled;\n\t},false);\n\t// Make it draggable if required\n\tif(this.dragTiddler || this.dragFilter) {\n\t\t$tw.utils.makeDraggable({\n\t\t\tdomNode: domNode,\n\t\t\tdragTiddlerFn: function() {return self.dragTiddler;},\n\t\t\tdragFilterFn: function() {return self.dragFilter;},\n\t\t\twidget: this\n\t\t});\n\t}\n\t// Insert element\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n};\n\n/*\nWe don't allow actions to propagate because we trigger actions ourselves\n*/\nButtonWidget.prototype.allowActionPropagation = function() {\n\treturn false;\n};\n\nButtonWidget.prototype.getBoundingClientRect = function() {\n\treturn this.domNodes[0].getBoundingClientRect();\n};\n\nButtonWidget.prototype.isSelected = function() {\n    return this.setTitle ? (this.setField ? this.wiki.getTiddler(this.setTitle).getFieldString(this.setField) === this.setTo :\n\t\t(this.setIndex ? this.wiki.extractTiddlerDataItem(this.setTitle,this.setIndex) === this.setTo :\n\t\t\tthis.wiki.getTiddlerText(this.setTitle))) || this.defaultSetValue || this.getVariable(\"currentTiddler\") :\n\t\tthis.wiki.getTextReference(this.set,this.defaultSetValue,this.getVariable(\"currentTiddler\")) === this.setTo;\n};\n\nButtonWidget.prototype.isPoppedUp = function() {\n\tvar tiddler = this.popupTitle ? this.wiki.getTiddler(this.popupTitle) : this.wiki.getTiddler(this.popup);\n\tvar result = tiddler && tiddler.fields.text ? Popup.readPopupState(tiddler.fields.text) : false;\n\treturn result;\n};\n\nButtonWidget.prototype.navigateTo = function(event) {\n\tvar bounds = this.getBoundingClientRect();\n\tthis.dispatchEvent({\n\t\ttype: \"tm-navigate\",\n\t\tnavigateTo: this.to,\n\t\tnavigateFromTitle: this.getVariable(\"storyTiddler\"),\n\t\tnavigateFromNode: this,\n\t\tnavigateFromClientRect: { top: bounds.top, left: bounds.left, width: bounds.width, right: bounds.right, bottom: bounds.bottom, height: bounds.height\n\t\t},\n\t\tnavigateSuppressNavigation: event.metaKey || event.ctrlKey || (event.button === 1),\n\t\tevent: event\n\t});\n};\n\nButtonWidget.prototype.dispatchMessage = function(event) {\n\tthis.dispatchEvent({type: this.message, param: this.param, tiddlerTitle: this.getVariable(\"currentTiddler\"), event: event});\n};\n\nButtonWidget.prototype.triggerPopup = function(event) {\n\tif(this.popupTitle) {\n\t\t$tw.popup.triggerPopup({\n\t\t\tdomNode: this.domNodes[0],\n\t\t\tabsolute: (this.popupAbsCoords === \"yes\"),\n\t\t\ttitle: this.popupTitle,\n\t\t\twiki: this.wiki,\n\t\t\tnoStateReference: true\n\t\t});\n\t} else {\n\t\t$tw.popup.triggerPopup({\n\t\t\tdomNode: this.domNodes[0],\n\t\t\tabsolute: (this.popupAbsCoords === \"yes\"),\n\t\t\ttitle: this.popup,\n\t\t\twiki: this.wiki\n\t\t});\n\t}\n};\n\nButtonWidget.prototype.setTiddler = function() {\n\tif(this.setTitle) {\n\t\tthis.setField ? this.wiki.setText(this.setTitle,this.setField,undefined,this.setTo) :\n\t\t\t\t(this.setIndex ? this.wiki.setText(this.setTitle,undefined,this.setIndex,this.setTo) :\n\t\t\t\tthis.wiki.setText(this.setTitle,\"text\",undefined,this.setTo));\n\t} else {\n\t\tthis.wiki.setTextReference(this.set,this.setTo,this.getVariable(\"currentTiddler\"));\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nButtonWidget.prototype.execute = function() {\n\t// Get attributes\n\tthis.actions = this.getAttribute(\"actions\");\n\tthis.to = this.getAttribute(\"to\");\n\tthis.message = this.getAttribute(\"message\");\n\tthis.param = this.getAttribute(\"param\");\n\tthis.set = this.getAttribute(\"set\");\n\tthis.setTo = this.getAttribute(\"setTo\");\n\tthis.popup = this.getAttribute(\"popup\");\n\tthis.hover = this.getAttribute(\"hover\");\n\tthis[\"aria-label\"] = this.getAttribute(\"aria-label\");\n\tthis.role = this.getAttribute(\"role\");\n\tthis.tooltip = this.getAttribute(\"tooltip\");\n\tthis.style = this.getAttribute(\"style\");\n\tthis[\"class\"] = this.getAttribute(\"class\",\"\");\n\tthis.selectedClass = this.getAttribute(\"selectedClass\");\n\tthis.defaultSetValue = this.getAttribute(\"default\",\"\");\n\tthis.buttonTag = this.getAttribute(\"tag\");\n\tthis.dragTiddler = this.getAttribute(\"dragTiddler\");\n\tthis.dragFilter = this.getAttribute(\"dragFilter\");\n\tthis.setTitle = this.getAttribute(\"setTitle\");\n\tthis.setField = this.getAttribute(\"setField\");\n\tthis.setIndex = this.getAttribute(\"setIndex\");\n\tthis.popupTitle = this.getAttribute(\"popupTitle\");\n\tthis.popupAbsCoords = this.getAttribute(\"popupAbsCoords\", \"no\");\n\tthis.tabIndex = this.getAttribute(\"tabindex\");\n\tthis.isDisabled = this.getAttribute(\"disabled\",\"no\");\n\t// Make child widgets\n\tthis.makeChildWidgets();\n};\n\nButtonWidget.prototype.updateDomNodeClasses = function() {\n\tvar domNodeClasses = this.domNode.className.split(\" \"),\n\t\toldClasses = this.class.split(\" \"),\n\t\tnewClasses;\n\tthis[\"class\"] = this.getAttribute(\"class\",\"\");\n\tnewClasses = this.class.split(\" \");\n\t//Remove classes assigned from the old value of class attribute\n\t$tw.utils.each(oldClasses,function(oldClass){\n\t\tvar i = domNodeClasses.indexOf(oldClass);\n\t\tif(i !== -1) {\n\t\t\tdomNodeClasses.splice(i,1);\n\t\t}\n\t});\n\t//Add new classes from updated class attribute.\n\t$tw.utils.pushTop(domNodeClasses,newClasses);\n\tthis.domNode.className = domNodeClasses.join(\" \");\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nButtonWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tooltip || changedAttributes.actions || changedAttributes.to || changedAttributes.message || changedAttributes.param || changedAttributes.set || changedAttributes.setTo || changedAttributes.popup || changedAttributes.hover || changedAttributes.selectedClass || changedAttributes.style || changedAttributes.dragFilter || changedAttributes.dragTiddler || (this.set && changedTiddlers[this.set]) || (this.popup && changedTiddlers[this.popup]) || (this.popupTitle && changedTiddlers[this.popupTitle]) || changedAttributes.popupAbsCoords || changedAttributes.setTitle || changedAttributes.setField || changedAttributes.setIndex || changedAttributes.popupTitle || changedAttributes.disabled || changedAttributes[\"default\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\tif(changedAttributes[\"class\"]) {\n\t\t\tthis.updateDomNodeClasses();\n\t\t}\n\t\tthis.assignAttributes(this.domNodes[0],{\n\t\t\tchangedAttributes: changedAttributes,\n\t\t\tsourcePrefix: \"data-\",\n\t\t\tdestPrefix: \"data-\"\n\t\t});\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.button = ButtonWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/checkbox.js":{"title":"$:/core/modules/widgets/checkbox.js","text":"/*\\\ntitle: $:/core/modules/widgets/checkbox.js\ntype: application/javascript\nmodule-type: widget\n\nCheckbox widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar CheckboxWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nCheckboxWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nCheckboxWidget.prototype.render = function(parent,nextSibling) {\n\tvar isChecked;\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\t// Create our elements\n\tthis.labelDomNode = this.document.createElement(\"label\");\n\tthis.labelDomNode.setAttribute(\"class\",\"tc-checkbox \" + this.checkboxClass);\n\tthis.inputDomNode = this.document.createElement(\"input\");\n\tthis.inputDomNode.setAttribute(\"type\",\"checkbox\");\n\tisChecked = this.getValue();\n\tif(isChecked) {\n\t\tthis.inputDomNode.setAttribute(\"checked\",\"true\");\n\t\t$tw.utils.addClass(this.labelDomNode,\"tc-checkbox-checked\");\n\t}\n\tif(isChecked === undefined && this.checkboxIndeterminate === \"yes\") {\n\t\tthis.inputDomNode.indeterminate = true;\n\t}\n\tif(this.isDisabled === \"yes\") {\n\t\tthis.inputDomNode.setAttribute(\"disabled\",true);\n\t}\n\tthis.labelDomNode.appendChild(this.inputDomNode);\n\tthis.spanDomNode = this.document.createElement(\"span\");\n\tthis.labelDomNode.appendChild(this.spanDomNode);\n\t// Assign data- attributes\n\tthis.assignAttributes(this.inputDomNode,{\n\t\tsourcePrefix: \"data-\",\n\t\tdestPrefix: \"data-\"\n\t});\n\t// Add a click event handler\n\t$tw.utils.addEventListeners(this.inputDomNode,[\n\t\t{name: \"change\", handlerObject: this, handlerMethod: \"handleChangeEvent\"}\n\t]);\n\t// Insert the label into the DOM and render any children\n\tparent.insertBefore(this.labelDomNode,nextSibling);\n\tthis.renderChildren(this.spanDomNode,null);\n\tthis.domNodes.push(this.labelDomNode);\n};\n\nCheckboxWidget.prototype.getValue = function() {\n\tvar tiddler = this.wiki.getTiddler(this.checkboxTitle);\n\tif(tiddler || this.checkboxFilter) {\n\t\tif(tiddler && this.checkboxTag) {\n\t\t\tif(this.checkboxInvertTag === \"yes\") {\n\t\t\t\treturn !tiddler.hasTag(this.checkboxTag);\n\t\t\t} else {\n\t\t\t\treturn tiddler.hasTag(this.checkboxTag);\n\t\t\t}\n\t\t}\n\t\tif(tiddler && (this.checkboxField || this.checkboxIndex)) {\n\t\t\t// Same logic applies to fields and indexes\n\t\t\tvar value;\n\t\t\tif(this.checkboxField) {\n\t\t\t\tif($tw.utils.hop(tiddler.fields,this.checkboxField)) {\n\t\t\t\t\tvalue = tiddler.fields[this.checkboxField] || \"\";\n\t\t\t\t} else {\n\t\t\t\t\tvalue = this.checkboxDefault || \"\";\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tvalue = this.wiki.extractTiddlerDataItem(tiddler,this.checkboxIndex,this.checkboxDefault || \"\");\n\t\t\t}\n\t\t\tif(value === this.checkboxChecked) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif(value === this.checkboxUnchecked) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// Neither value found: were both specified?\n\t\t\tif(this.checkboxChecked && !this.checkboxUnchecked) {\n\t\t\t\treturn false; // Absence of checked value\n\t\t\t}\n\t\t\tif(this.checkboxUnchecked && !this.checkboxChecked) {\n\t\t\t\treturn true; // Absence of unchecked value\n\t\t\t}\n\t\t\tif(this.checkboxChecked && this.checkboxUnchecked) {\n\t\t\t\t// Both specified but neither found: indeterminate or false, depending\n\t\t\t\tif(this.checkboxIndeterminate === \"yes\") {\n\t\t\t\t\treturn undefined;\n\t\t\t\t} else {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif(this.checkboxListField || this.checkboxListIndex || this.checkboxFilter) {\n\t\t\t// Same logic applies to lists and filters\n\t\t\tvar list;\n\t\t\tif(this.checkboxListField) {\n\t\t\t\tif($tw.utils.hop(tiddler.fields,this.checkboxListField)) {\n\t\t\t\t\tlist = tiddler.getFieldList(this.checkboxListField) || [];\n\t\t\t\t} else {\n\t\t\t\t\tlist = $tw.utils.parseStringArray(this.checkboxDefault || \"\") || [];\n\t\t\t\t}\n\t\t\t} else if(this.checkboxListIndex) {\n\t\t\t\tlist = $tw.utils.parseStringArray(this.wiki.extractTiddlerDataItem(tiddler,this.checkboxListIndex,this.checkboxDefault || \"\")) || [];\n\t\t\t} else {\n\t\t\t\tlist = this.wiki.filterTiddlers(this.checkboxFilter,this) || [];\n\t\t\t}\n\t\t\tif(list.indexOf(this.checkboxChecked) !== -1) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif(list.indexOf(this.checkboxUnchecked) !== -1) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// Neither one present\n\t\t\tif(this.checkboxChecked && !this.checkboxUnchecked) {\n\t\t\t\treturn false; // Absence of checked value\n\t\t\t}\n\t\t\tif(this.checkboxUnchecked && !this.checkboxChecked) {\n\t\t\t\treturn true; // Absence of unchecked value\n\t\t\t}\n\t\t\tif(this.checkboxChecked && this.checkboxUnchecked) {\n\t\t\t\t// Both specified but neither found: indeterminate or false, depending\n\t\t\t\tif(this.checkboxIndeterminate === \"yes\") {\n\t\t\t\t\treturn undefined;\n\t\t\t\t} else {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Neither specified, so empty list is false, non-empty is true\n\t\t\treturn !!list.length;\n\t\t}\n\t} else {\n\t\tif(this.checkboxTag) {\n\t\t\treturn false;\n\t\t}\n\t\tif(this.checkboxField) {\n\t\t\tif(this.checkboxDefault === this.checkboxChecked) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif(this.checkboxDefault === this.checkboxUnchecked) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n};\n\nCheckboxWidget.prototype.handleChangeEvent = function(event) {\n\tvar checked = this.inputDomNode.checked,\n\t\ttiddler = this.wiki.getTiddler(this.checkboxTitle),\n\t\tfallbackFields = {text: \"\"},\n\t\tnewFields = {title: this.checkboxTitle},\n\t\thasChanged = false,\n\t\ttagCheck = false,\n\t\thasTag = tiddler && tiddler.hasTag(this.checkboxTag),\n\t\tvalue = checked ? this.checkboxChecked : this.checkboxUnchecked,\n\t\tnotValue = checked ? this.checkboxUnchecked : this.checkboxChecked;\n\tif(this.checkboxTag && this.checkboxInvertTag === \"yes\") {\n\t\ttagCheck = hasTag === checked;\n\t} else {\n\t\ttagCheck = hasTag !== checked;\n\t}\n\t// Set the tag if specified\n\tif(this.checkboxTag && (!tiddler || tagCheck)) {\n\t\tnewFields.tags = tiddler ? (tiddler.fields.tags || []).slice(0) : [];\n\t\tvar pos = newFields.tags.indexOf(this.checkboxTag);\n\t\tif(pos !== -1) {\n\t\t\tnewFields.tags.splice(pos,1);\n\t\t}\n\t\tif(this.checkboxInvertTag === \"yes\" && !checked) {\n\t\t\tnewFields.tags.push(this.checkboxTag);\n\t\t} else if(this.checkboxInvertTag !== \"yes\" && checked) {\n\t\t\tnewFields.tags.push(this.checkboxTag);\n\t\t}\n\t\thasChanged = true;\n\t}\n\t// Set the field if specified\n\tif(this.checkboxField) {\n\t\tif(!tiddler || tiddler.fields[this.checkboxField] !== value) {\n\t\t\tnewFields[this.checkboxField] = value;\n\t\t\thasChanged = true;\n\t\t}\n\t}\n\t// Set the index if specified\n\tif(this.checkboxIndex) {\n\t\tvar indexValue = this.wiki.extractTiddlerDataItem(this.checkboxTitle,this.checkboxIndex);\n\t\tif(!tiddler || indexValue !== value) {\n\t\t\thasChanged = true;\n\t\t}\n\t}\n\t// Set the list field (or index) if specified\n\tif(this.checkboxListField || this.checkboxListIndex) {\n\t\tvar fieldContents, listContents, oldPos, newPos;\n\t\tif(this.checkboxListField) {\n\t\t\tfieldContents = (tiddler ? tiddler.fields[this.checkboxListField] : undefined) || [];\n\t\t} else {\n\t\t\tfieldContents = this.wiki.extractTiddlerDataItem(this.checkboxTitle,this.checkboxListIndex);\n\t\t}\n\t\tif($tw.utils.isArray(fieldContents)) {\n\t\t\t// Make a copy so we can modify it without changing original that's refrenced elsewhere\n\t\t\tlistContents = fieldContents.slice(0);\n\t\t} else if(fieldContents === undefined) {\n\t\t\tlistContents = [];\n\t\t} else if(typeof fieldContents === \"string\") {\n\t\t\tlistContents = $tw.utils.parseStringArray(fieldContents);\n\t\t\t// No need to copy since parseStringArray returns a fresh array, not refrenced elsewhere\n\t\t} else {\n\t\t\t// Field was neither an array nor a string; it's probably something that shouldn't become\n\t\t\t// an array (such as a date field), so bail out *without* triggering actions\n\t\t\treturn;\n\t\t}\n\t\toldPos = notValue ? listContents.indexOf(notValue) : -1;\n\t\tnewPos = value ? listContents.indexOf(value) : -1;\n\t\tif(oldPos === -1 && newPos !== -1) {\n\t\t\t// old value absent, new value present: no change needed\n\t\t} else if(oldPos === -1) {\n\t\t\t// neither one was present\n\t\t\tif(value) {\n\t\t\t\tlistContents.push(value);\n\t\t\t\thasChanged = true;\n\t\t\t} else {\n\t\t\t\t// value unspecified? then leave list unchanged\n\t\t\t}\n\t\t} else if(newPos === -1) {\n\t\t\t// old value present, new value absent\n\t\t\tif(value) {\n\t\t\t\tlistContents[oldPos] = value;\n\t\t\t\thasChanged = true;\n\t\t\t} else {\n\t\t\t\tlistContents.splice(oldPos, 1)\n\t\t\t\thasChanged = true;\n\t\t\t}\n\t\t} else {\n\t\t\t// both were present: just remove the old one, leave new alone\n\t\t\tlistContents.splice(oldPos, 1)\n\t\t\thasChanged = true;\n\t\t}\n\t\tif(this.checkboxListField) {\n\t\t\tnewFields[this.checkboxListField] = $tw.utils.stringifyList(listContents);\n\t\t}\n\t\t// The listIndex case will be handled in the if(hasChanged) block below\n\t}\n\tif(hasChanged) {\n\t\tif(this.checkboxIndex) {\n\t\t\tthis.wiki.setText(this.checkboxTitle,\"\",this.checkboxIndex,value);\n\t\t} else if(this.checkboxListIndex) {\n\t\t\tvar listIndexValue = (listContents && listContents.length) ? $tw.utils.stringifyList(listContents) : undefined;\n\t\t\tthis.wiki.setText(this.checkboxTitle,\"\",this.checkboxListIndex,listIndexValue);\n\t\t} else {\n\t\t\tthis.wiki.addTiddler(new $tw.Tiddler(this.wiki.getCreationFields(),fallbackFields,tiddler,newFields,this.wiki.getModificationFields()));\n\t\t}\n\t}\n\t// Trigger actions\n\tif(this.checkboxActions) {\n\t\tthis.invokeActionString(this.checkboxActions,this,event);\n\t}\n\tif(this.checkboxCheckActions && checked) {\n\t\tthis.invokeActionString(this.checkboxCheckActions,this,event);\n\t}\n\tif(this.checkboxUncheckActions && !checked) {\n\t\tthis.invokeActionString(this.checkboxUncheckActions,this,event);\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nCheckboxWidget.prototype.execute = function() {\n\t// Get the parameters from the attributes\n\tthis.checkboxActions = this.getAttribute(\"actions\");\n\tthis.checkboxCheckActions = this.getAttribute(\"checkactions\");\n\tthis.checkboxUncheckActions = this.getAttribute(\"uncheckactions\");\n\tthis.checkboxTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.checkboxTag = this.getAttribute(\"tag\");\n\tthis.checkboxField = this.getAttribute(\"field\");\n\tthis.checkboxIndex = this.getAttribute(\"index\");\n\tthis.checkboxListField = this.getAttribute(\"listField\");\n\tthis.checkboxListIndex = this.getAttribute(\"listIndex\");\n\tthis.checkboxFilter = this.getAttribute(\"filter\");\n\tthis.checkboxChecked = this.getAttribute(\"checked\");\n\tthis.checkboxUnchecked = this.getAttribute(\"unchecked\");\n\tthis.checkboxDefault = this.getAttribute(\"default\");\n\tthis.checkboxIndeterminate = this.getAttribute(\"indeterminate\",\"no\");\n\tthis.checkboxClass = this.getAttribute(\"class\",\"\");\n\tthis.checkboxInvertTag = this.getAttribute(\"invertTag\",\"\");\n\tthis.isDisabled = this.getAttribute(\"disabled\",\"no\");\n\t// Make the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nCheckboxWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tiddler || changedAttributes.tag || changedAttributes.invertTag || changedAttributes.field || changedAttributes.index || changedAttributes.listField || changedAttributes.listIndex || changedAttributes.filter || changedAttributes.checked || changedAttributes.unchecked || changedAttributes[\"default\"] || changedAttributes.indeterminate || changedAttributes[\"class\"] || changedAttributes.disabled) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\tvar refreshed = false;\n\t\tif(changedTiddlers[this.checkboxTitle]) {\n\t\t\tvar isChecked = this.getValue();\n\t\t\tthis.inputDomNode.checked = !!isChecked;\n\t\t\tthis.inputDomNode.indeterminate = (isChecked === undefined);\n\t\t\trefreshed = true;\n\t\t\tif(isChecked) {\n\t\t\t\t$tw.utils.addClass(this.labelDomNode,\"tc-checkbox-checked\");\n\t\t\t} else {\n\t\t\t\t$tw.utils.removeClass(this.labelDomNode,\"tc-checkbox-checked\");\n\t\t\t}\n\t\t}\n\t\tthis.assignAttributes(this.inputDomNode,{\n\t\t\tchangedAttributes: changedAttributes,\n\t\t\tsourcePrefix: \"data-\",\n\t\t\tdestPrefix: \"data-\"\n\t\t});\n\t\treturn this.refreshChildren(changedTiddlers) || refreshed;\n\t}\n};\n\nexports.checkbox = CheckboxWidget;\n\n})();\n\t","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/codeblock.js":{"title":"$:/core/modules/widgets/codeblock.js","text":"/*\\\ntitle: $:/core/modules/widgets/codeblock.js\ntype: application/javascript\nmodule-type: widget\n\nCode block node widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar CodeBlockWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nCodeBlockWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nCodeBlockWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar codeNode = this.document.createElement(\"code\"),\n\t\tdomNode = this.document.createElement(\"pre\");\n\tcodeNode.appendChild(this.document.createTextNode(this.getAttribute(\"code\")));\n\tdomNode.appendChild(codeNode);\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.domNodes.push(domNode);\n\tif(this.postRender) {\n\t\tthis.postRender();\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nCodeBlockWidget.prototype.execute = function() {\n\tthis.language = this.getAttribute(\"language\");\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nCodeBlockWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.code || changedAttributes.language) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n};\n\nexports.codeblock = CodeBlockWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/count.js":{"title":"$:/core/modules/widgets/count.js","text":"/*\\\ntitle: $:/core/modules/widgets/count.js\ntype: application/javascript\nmodule-type: widget\n\nCount widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar CountWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nCountWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nCountWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar textNode = this.document.createTextNode(this.currentCount);\n\tparent.insertBefore(textNode,nextSibling);\n\tthis.domNodes.push(textNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nCountWidget.prototype.execute = function() {\n\t// Get parameters from our attributes\n\tthis.filter = this.getAttribute(\"filter\");\n\t// Execute the filter\n\tif(this.filter) {\n\t\tthis.currentCount = this.wiki.filterTiddlers(this.filter,this).length;\n\t} else {\n\t\tthis.currentCount = \"0\";\n\t}\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nCountWidget.prototype.refresh = function(changedTiddlers) {\n\t// Re-execute the filter to get the count\n\tthis.computeAttributes();\n\tvar oldCount = this.currentCount;\n\tthis.execute();\n\tif(this.currentCount !== oldCount) {\n\t\t// Regenerate and rerender the widget and replace the existing DOM node\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n\n};\n\nexports.count = CountWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/data.js":{"title":"$:/core/modules/widgets/data.js","text":"/*\\\ntitle: $:/core/modules/widgets/data.js\ntype: application/javascript\nmodule-type: widget\n\nWidget to dynamically represent one or more tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar DataWidget = function(parseTreeNode,options) {\n\tthis.dataWidgetTag = parseTreeNode.type;\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nDataWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nDataWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.dataPayload = this.computeDataTiddlerValues(); // Array of $tw.Tiddler objects\n\tthis.domNode = this.document.createTextNode(this.readDataTiddlerValuesAsJson());\n\tparent.insertBefore(this.domNode,nextSibling);\n\tthis.domNodes.push(this.domNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nDataWidget.prototype.execute = function() {\n\t// Nothing to do here\n};\n\n/*\nRead the tiddler value(s) from a data widget as an array of tiddler field objects (not $tw.Tiddler objects)\n*/\nDataWidget.prototype.readDataTiddlerValues = function() {\n\tvar results = [];\n\t$tw.utils.each(this.dataPayload,function(tiddler,index) {\n\t\tresults.push(tiddler.getFieldStrings());\n\t});\n\treturn results;\n};\n\n/*\nRead the tiddler value(s) from a data widget as an array of tiddler field objects (not $tw.Tiddler objects)\n*/\nDataWidget.prototype.readDataTiddlerValuesAsJson = function() {\n\treturn JSON.stringify(this.readDataTiddlerValues(),null,4);\n};\n\n/*\nCompute list of tiddlers from a data widget\n*/\nDataWidget.prototype.computeDataTiddlerValues = function() {\n\tvar self = this;\n\t// Read any attributes not prefixed with $\n\tvar item = Object.create(null);\n\t$tw.utils.each(this.attributes,function(value,name) {\n\t\tif(name.charAt(0) !== \"$\") {\n\t\t\titem[name] = value;\t\n\t\t}\n\t});\n\t// Deal with $tiddler, $filter or $compound-tiddler attributes\n\tvar tiddlers = [],\n\t\tcompoundTiddlers,\n\t\ttitle;\n\tif(this.hasAttribute(\"$tiddler\")) {\n\t\ttitle = this.getAttribute(\"$tiddler\");\n\t\tif(title) {\n\t\t\tvar tiddler = this.wiki.getTiddler(title);\n\t\t\tif(tiddler) {\n\t\t\t\ttiddlers.push(tiddler);\n\t\t\t}\n\t\t}\n\t}\n\tif(this.hasAttribute(\"$filter\")) {\n\t\tvar filter = this.getAttribute(\"$filter\");\n\t\tif(filter) {\n\t\t\tvar titles = this.wiki.filterTiddlers(filter);\n\t\t\t$tw.utils.each(titles,function(title) {\n\t\t\t\tvar tiddler = self.wiki.getTiddler(title);\n\t\t\t\tif(tiddler) {\n\t\t\t\t\ttiddlers.push(tiddler);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\tif(this.hasAttribute(\"$compound-tiddler\")) {\n\t\ttitle = this.getAttribute(\"$compound-tiddler\");\n\t\tif(title) {\n\t\t\ttiddlers.push.apply(tiddlers,this.extractCompoundTiddler(title));\n\t\t}\n\t}\n\tif(this.hasAttribute(\"$compound-filter\")) {\n\t\tfilter = this.getAttribute(\"$compound-filter\");\n\t\tif(filter) {\n\t\t\tcompoundTiddlers = this.wiki.filterTiddlers(filter);\n\t\t\t$tw.utils.each(compoundTiddlers, function(title){\n\t\t\t\ttiddlers.push.apply(tiddlers,self.extractCompoundTiddler(title));\n\t\t\t});\n\t\t}\n\t}\n\t// Return the literal item if none of the special attributes were used\n\tif(!this.hasAttribute(\"$tiddler\") && !this.hasAttribute(\"$filter\") && !this.hasAttribute(\"$compound-tiddler\") && !this.hasAttribute(\"$compound-filter\")) {\n\t\tif(Object.keys(item).length > 0 && !!item.title) {\n\t\t\treturn [new $tw.Tiddler(item)];\n\t\t} else {\n\t\t\treturn [];\n\t\t}\n\t} else {\n\t\t// Apply the item fields to each of the tiddlers\n\t\tif(Object.keys(item).length > 0) {\n\t\t\t$tw.utils.each(tiddlers,function(tiddler,index) {\n\t\t\t\ttiddlers[index] = new $tw.Tiddler(tiddler,item);\n\t\t\t});\n\t\t}\n\t\treturn tiddlers;\n\t}\n};\n\n/*\nHelper to extract tiddlers from text/vnd.tiddlywiki-multiple tiddlers\n*/\nDataWidget.prototype.extractCompoundTiddler = function(title) {\n\tvar tiddler = this.wiki.getTiddler(title);\n\tif(tiddler && tiddler.fields.type === \"text/vnd.tiddlywiki-multiple\") {\n\t\tvar text = tiddler.fields.text || \"\",\n\t\t\trawTiddlers = text.split(/\\r?\\n\\+\\r?\\n/),\n\t\t\ttiddlers = [];\n\t\t$tw.utils.each(rawTiddlers,function(rawTiddler) {\n\t\t\tvar fields = Object.create(null),\n\t\t\t\tsplit = rawTiddler.split(/\\r?\\n\\r?\\n/mg);\n\t\t\tif(split.length >= 1) {\n\t\t\t\tfields = $tw.utils.parseFields(split[0],fields);\n\t\t\t}\n\t\t\tif(split.length >= 2) {\n\t\t\t\tfields.text = split.slice(1).join(\"\\n\\n\");\n\t\t\t}\n\t\t\ttiddlers.push(new $tw.Tiddler(fields));\n\t\t});\n\t\treturn tiddlers;\n\t} else {\n\t\treturn [];\n\t}\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nDataWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tvar newPayload = this.computeDataTiddlerValues();\n\tif(hasPayloadChanged(this.dataPayload,newPayload)) {\n\t\tthis.dataPayload = newPayload;\n\t\tthis.domNode.textContent = this.readDataTiddlerValuesAsJson();\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n};\n\n/*\nCompare two arrays of tiddlers and return true if they are different\n*/\nfunction hasPayloadChanged(a,b) {\n\tif(a.length === b.length) {\n\t\tfor(var t=0; t<a.length; t++) {\n\t\t\tif(!(a[t].isEqual(b[t]))) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t} else {\n\t\treturn true;\n\t}\n}\n\nexports.data = DataWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/diff-text.js":{"title":"$:/core/modules/widgets/diff-text.js","text":"/*\\\ntitle: $:/core/modules/widgets/diff-text.js\ntype: application/javascript\nmodule-type: widget\n\nWidget to display a diff between two texts\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget,\n\tdmp = require(\"$:/core/modules/utils/diff-match-patch/diff_match_patch.js\");\n\nvar DiffTextWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nDiffTextWidget.prototype = new Widget();\n\nDiffTextWidget.prototype.invisibleCharacters = {\n\t\"\\n\": \"↩︎\\n\",\n\t\"\\r\": \"⇠\",\n\t\"\\t\": \"⇥\\t\"\n};\n\n/*\nRender this widget into the DOM\n*/\nDiffTextWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Create the diff\n\tvar dmpObject = new dmp.diff_match_patch(),\n\t\tdiffs = dmpObject.diff_main(this.getAttribute(\"source\",\"\"),this.getAttribute(\"dest\",\"\"));\n\t// Apply required cleanup\n\tswitch(this.getAttribute(\"cleanup\",\"semantic\")) {\n\t\tcase \"none\":\n\t\t\t// No cleanup\n\t\t\tbreak;\n\t\tcase \"efficiency\":\n\t\t\tdmpObject.diff_cleanupEfficiency(diffs);\n\t\t\tbreak;\n\t\tdefault: // case \"semantic\"\n\t\t\tdmpObject.diff_cleanupSemantic(diffs);\n\t\t\tbreak;\n\t}\n\t// Create the elements\n\tvar domContainer = this.document.createElement(\"div\"), \n\t\tdomDiff = this.createDiffDom(diffs);\n\tparent.insertBefore(domContainer,nextSibling);\n\t// Set variables\n\tthis.setVariable(\"diff-count\",diffs.reduce(function(acc,diff) {\n\t\tif(diff[0] !== dmp.DIFF_EQUAL) {\n\t\t\tacc++;\n\t\t}\n\t\treturn acc;\n\t},0).toString());\n\t// Render child widgets\n\tthis.renderChildren(domContainer,null);\n\t// Render the diff\n\tdomContainer.appendChild(domDiff);\n\t// Save our container\n\tthis.domNodes.push(domContainer);\n};\n\n/*\nCreate DOM elements representing a list of diffs\n*/\nDiffTextWidget.prototype.createDiffDom = function(diffs) {\n\tvar self = this;\n\t// Create the element and assign the attributes\n\tvar domPre = this.document.createElement(\"pre\"),\n\t\tdomCode = this.document.createElement(\"code\");\n\t$tw.utils.each(diffs,function(diff) {\n\t\tvar tag = diff[0] === dmp.DIFF_INSERT ? \"ins\" : (diff[0] === dmp.DIFF_DELETE ? \"del\" : \"span\"),\n\t\t\tclassName = diff[0] === dmp.DIFF_INSERT ? \"tc-diff-insert\" : (diff[0] === dmp.DIFF_DELETE ? \"tc-diff-delete\" : \"tc-diff-equal\"),\n\t\t\tdom = self.document.createElement(tag),\n\t\t\ttext = diff[1],\n\t\t\tcurrPos = 0,\n\t\t\tre = /([\\x00-\\x1F])/mg,\n\t\t\tmatch = re.exec(text),\n\t\t\tspan,\n\t\t\tprintable;\n\t\tdom.className = className;\n\t\twhile(match) {\n\t\t\tif(currPos < match.index) {\n\t\t\t\tdom.appendChild(self.document.createTextNode(text.slice(currPos,match.index)));\n\t\t\t}\n\t\t\tspan = self.document.createElement(\"span\");\n\t\t\tspan.className = \"tc-diff-invisible\";\n\t\t\tprintable = self.invisibleCharacters[match[0]] || (\"[0x\" + match[0].charCodeAt(0).toString(16) + \"]\");\n\t\t\tspan.appendChild(self.document.createTextNode(printable));\n\t\t\tdom.appendChild(span);\n\t\t\tcurrPos = match.index + match[0].length;\n\t\t\tmatch = re.exec(text);\n\t\t}\n\t\tif(currPos < text.length) {\n\t\t\tdom.appendChild(self.document.createTextNode(text.slice(currPos)));\n\t\t}\n\t\tdomCode.appendChild(dom);\n\t});\n\tdomPre.appendChild(domCode);\n\treturn domPre;\n};\n\n/*\nCompute the internal state of the widget\n*/\nDiffTextWidget.prototype.execute = function() {\n\t// Make child widgets\n\tvar parseTreeNodes;\n\tif(this.parseTreeNode && this.parseTreeNode.children && this.parseTreeNode.children.length > 0) {\n\t\tparseTreeNodes = this.parseTreeNode.children;\n\t} else {\n\t\tparseTreeNodes = [{\n\t\t\ttype: \"transclude\",\n\t\t\tattributes: {\n\t\t\t\ttiddler: {type: \"string\", value: \"$:/language/Diffs/CountMessage\"}\n\t\t\t}\n\t\t}];\n\t}\n\tthis.makeChildWidgets(parseTreeNodes);\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nDiffTextWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.source || changedAttributes.dest || changedAttributes.cleanup) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports[\"diff-text\"] = DiffTextWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/draggable.js":{"title":"$:/core/modules/widgets/draggable.js","text":"/*\\\ntitle: $:/core/modules/widgets/draggable.js\ntype: application/javascript\nmodule-type: widget\n\nDraggable widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar DraggableWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nDraggableWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nDraggableWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this,\n\t\ttag,\n\t\tdomNode,\n\t\tclasses = [];\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\t// Sanitise the specified tag\n\ttag = this.draggableTag;\n\tif($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {\n\t\ttag = \"div\";\n\t}\n\t// Create our element\n\tdomNode = this.document.createElement(tag);\n\t// Assign classes\n\tif(this.draggableClasses) {\n\t\tclasses.push(this.draggableClasses);\n\t}\n\tif(!this.dragHandleSelector && this.dragEnable) {\n\t\tclasses.push(\"tc-draggable\");\n\t}\n\tdomNode.setAttribute(\"class\",classes.join(\" \"));\n\t// Assign data- attributes and style. attributes\n\tthis.assignAttributes(domNode,{\n\t\tsourcePrefix: \"data-\",\n\t\tdestPrefix: \"data-\"\n\t});\n\t// Insert the node into the DOM and render any children\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\t// Add event handlers\n\tif(this.dragEnable) {\n\t\t$tw.utils.makeDraggable({\n\t\t\tdomNode: domNode,\n\t\t\tdragTiddlerFn: function() {return self.getAttribute(\"tiddler\");},\n\t\t\tdragFilterFn: function() {return self.getAttribute(\"filter\");},\n\t\t\tstartActions: self.startActions,\n\t\t\tendActions: self.endActions,\n\t\t\tdragImageType: self.dragImageType,\n\t\t\twidget: this,\n\t\t\tselector: self.dragHandleSelector\n\t\t});\n\t}\n\tthis.domNodes.push(domNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nDraggableWidget.prototype.execute = function() {\n\t// Pick up our attributes\n\tthis.draggableTag = this.getAttribute(\"tag\",\"div\");\n\tthis.draggableClasses = this.getAttribute(\"class\");\n\tthis.startActions = this.getAttribute(\"startactions\");\n\tthis.endActions = this.getAttribute(\"endactions\");\n\tthis.dragImageType = this.getAttribute(\"dragimagetype\");\n\tthis.dragHandleSelector = this.getAttribute(\"selector\");\n\tthis.dragEnable = this.getAttribute(\"enable\",\"yes\") === \"yes\";\n\t// Make the child widgets\n\tthis.makeChildWidgets();\n};\n\n\nDraggableWidget.prototype.updateDomNodeClasses = function() {\n\tvar domNodeClasses = this.domNodes[0].className.split(\" \"),\n\t\toldClasses = this.draggableClasses.split(\" \");\n\tthis.draggableClasses = this.getAttribute(\"class\");\n\t//Remove classes assigned from the old value of class attribute\n\t$tw.utils.each(oldClasses,function(oldClass){\n\t\tvar i = domNodeClasses.indexOf(oldClass);\n\t\tif(i !== -1) {\n\t\t\tdomNodeClasses.splice(i,1);\n\t\t}\n\t});\n\t//Add new classes from updated class attribute.\n\t$tw.utils.pushTop(domNodeClasses,this.draggableClasses);\n\tthis.domNodes[0].setAttribute(\"class\",domNodeClasses.join(\" \"))\n}\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nDraggableWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tag || changedAttributes.selector || changedAttributes.dragimagetype || changedAttributes.enable || changedAttributes.startactions || changedAttributes.endactions) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\tif(changedAttributes[\"class\"]) {\n\t\t\tthis.updateDomNodeClasses();\n\t\t}\n\t\tthis.assignAttributes(this.domNodes[0],{\n\t\t\tchangedAttributes: changedAttributes,\n\t\t\tsourcePrefix: \"data-\",\n\t\t\tdestPrefix: \"data-\"\n\t\t});\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.draggable = DraggableWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/droppable.js":{"title":"$:/core/modules/widgets/droppable.js","text":"/*\\\ntitle: $:/core/modules/widgets/droppable.js\ntype: application/javascript\nmodule-type: widget\n\nDroppable widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar DroppableWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nDroppableWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nDroppableWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this,\n\t\ttag = this.parseTreeNode.isBlock ? \"div\" : \"span\",\n\t\tdomNode;\n\t// Remember parent\n\tthis.parentDomNode = parent;\n\t// Compute attributes and execute state\n\tthis.computeAttributes();\n\tthis.execute();\n\tif(this.droppableTag && $tw.config.htmlUnsafeElements.indexOf(this.droppableTag) === -1) {\n\t\ttag = this.droppableTag;\n\t}\n\t// Create element and assign classes\n\tdomNode = this.document.createElement(tag);\n\tthis.domNode = domNode;\n\tthis.assignDomNodeClasses();\n\t// Assign data- attributes and style. attributes\n\tthis.assignAttributes(domNode,{\n\t\tsourcePrefix: \"data-\",\n\t\tdestPrefix: \"data-\"\n\t});\n\t// Add event handlers\n\tif(this.droppableEnable) {\n\t\t$tw.utils.addEventListeners(domNode,[\n\t\t\t{name: \"dragenter\", handlerObject: this, handlerMethod: \"handleDragEnterEvent\"},\n\t\t\t{name: \"dragover\", handlerObject: this, handlerMethod: \"handleDragOverEvent\"},\n\t\t\t{name: \"dragleave\", handlerObject: this, handlerMethod: \"handleDragLeaveEvent\"},\n\t\t\t{name: \"drop\", handlerObject: this, handlerMethod: \"handleDropEvent\"}\n\t\t]);\n\t} else {\n\t\t$tw.utils.addClass(this.domNode,this.disabledClass);\n\t}\n\t// Insert element\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n\t// Stack of outstanding enter/leave events\n\tthis.currentlyEntered = [];\n};\n\nDroppableWidget.prototype.enterDrag = function(event) {\n\tif(this.currentlyEntered.indexOf(event.target) === -1) {\n\t\tthis.currentlyEntered.push(event.target);\n\t}\n\t// If we're entering for the first time we need to apply highlighting\n\t$tw.utils.addClass(this.domNodes[0],\"tc-dragover\");\n};\n\nDroppableWidget.prototype.leaveDrag = function(event) {\n\tvar pos = this.currentlyEntered.indexOf(event.target);\n\tif(pos !== -1) {\n\t\tthis.currentlyEntered.splice(pos,1);\n\t}\n\t// Remove highlighting if we're leaving externally. The hacky second condition is to resolve a problem with Firefox whereby there is an erroneous dragenter event if the node being dragged is within the dropzone\n\tif(this.currentlyEntered.length === 0 || (this.currentlyEntered.length === 1 && this.currentlyEntered[0] === $tw.dragInProgress)) {\n\t\tthis.currentlyEntered = [];\n\t\tif(this.domNodes[0]) {\n\t\t\t$tw.utils.removeClass(this.domNodes[0],\"tc-dragover\");\n\t\t}\n\t}\n};\n\nDroppableWidget.prototype.handleDragEnterEvent  = function(event) {\n\tthis.enterDrag(event);\n\t// Tell the browser that we're ready to handle the drop\n\tevent.preventDefault();\n\t// Tell the browser not to ripple the drag up to any parent drop handlers\n\tevent.stopPropagation();\n\treturn false;\n};\n\nDroppableWidget.prototype.handleDragOverEvent  = function(event) {\n\t// Check for being over a TEXTAREA or INPUT\n\tif([\"TEXTAREA\",\"INPUT\"].indexOf(event.target.tagName) !== -1) {\n\t\treturn false;\n\t}\n\t// Tell the browser that we're still interested in the drop\n\tevent.preventDefault();\n\t// Set the drop effect\n\tevent.dataTransfer.dropEffect = this.droppableEffect;\n\treturn false;\n};\n\nDroppableWidget.prototype.handleDragLeaveEvent  = function(event) {\n\tthis.leaveDrag(event);\n\treturn false;\n};\n\nDroppableWidget.prototype.handleDropEvent  = function(event) {\n\tvar self = this;\n\tthis.leaveDrag(event);\n\t// Check for being over a TEXTAREA or INPUT\n\tif([\"TEXTAREA\",\"INPUT\"].indexOf(event.target.tagName) !== -1) {\n\t\treturn false;\n\t}\n\tvar dataTransfer = event.dataTransfer;\n\t// Remove highlighting\n\t$tw.utils.removeClass(this.domNodes[0],\"tc-dragover\");\n\t// Try to import the various data types we understand\n\tif(this.droppableActions) {\n\t\t$tw.utils.importDataTransfer(dataTransfer,null,function(fieldsArray) {\n\t\t\tfieldsArray.forEach(function(fields) {\n\t\t\t\tself.performActions(fields.title || fields.text,event);\n\t\t\t});\n\t\t});\n\t}\n\t// Send a TitleList to performListActions\n\tif(this.droppableListActions) {\n\t\t$tw.utils.importDataTransfer(dataTransfer,null,function(fieldsArray) {\n\t\t\tvar titleList = [];\n\t\t\tfieldsArray.forEach(function(fields) {\n\t\t\t\ttitleList.push(fields.title || fields.text);\n\t\t\t});\n\t\t\tself.performListActions($tw.utils.stringifyList(titleList),event);\n\t\t});\n\t}\n\t// Tell the browser that we handled the drop\n\tevent.preventDefault();\n\t// Stop the drop ripple up to any parent handlers\n\tevent.stopPropagation();\n\treturn false;\n};\n\nDroppableWidget.prototype.performListActions = function(titleList,event) {\n\tif(this.droppableListActions) {\n\t\tvar modifierKey = $tw.keyboardManager.getEventModifierKeyDescriptor(event);\n\t\tthis.invokeActionString(this.droppableListActions,this,event,{actionTiddlerList: titleList, modifier: modifierKey});\n\t}\n};\n\nDroppableWidget.prototype.performActions = function(title,event) {\n\tif(this.droppableActions) {\n\t\tvar modifierKey = $tw.keyboardManager.getEventModifierKeyDescriptor(event);\n\t\tthis.invokeActionString(this.droppableActions,this,event,{actionTiddler: title, modifier: modifierKey});\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nDroppableWidget.prototype.execute = function() {\n\tthis.droppableActions = this.getAttribute(\"actions\");\n\tthis.droppableListActions = this.getAttribute(\"listActions\");\n\tthis.droppableEffect = this.getAttribute(\"effect\",\"copy\");\n\tthis.droppableTag = this.getAttribute(\"tag\");\n\tthis.droppableEnable = (this.getAttribute(\"enable\") || \"yes\") === \"yes\";\n\tthis.disabledClass = this.getAttribute(\"disabledClass\",\"\");\n\t// Make child widgets\n\tthis.makeChildWidgets();\n};\n\nDroppableWidget.prototype.assignDomNodeClasses = function() {\n\tvar classes = this.getAttribute(\"class\",\"\").split(\" \");\n\tclasses.push(\"tc-droppable\");\n\tthis.domNode.className = classes.join(\" \");\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nDroppableWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tag || changedAttributes.enable || changedAttributes.disabledClass ||\n\t\tchangedAttributes.actions|| changedAttributes.listActions || changedAttributes.effect) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\tif(changedAttributes[\"class\"]) {\n\t\t\tthis.assignDomNodeClasses();\n\t\t}\n\t\tthis.assignAttributes(this.domNodes[0],{\n\t\t\tchangedAttributes: changedAttributes,\n\t\t\tsourcePrefix: \"data-\",\n\t\t\tdestPrefix: \"data-\"\n\t\t});\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.droppable = DroppableWidget;\n\n})();","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/dropzone.js":{"title":"$:/core/modules/widgets/dropzone.js","text":"/*\\\ntitle: $:/core/modules/widgets/dropzone.js\ntype: application/javascript\nmodule-type: widget\n\nDropzone widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar IMPORT_TITLE = \"$:/Import\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar DropZoneWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nDropZoneWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nDropZoneWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Remember parent\n\tthis.parentDomNode = parent;\n\t// Compute attributes and execute state\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Create element\n\tvar domNode = this.document.createElement(\"div\");\n\tthis.domNode = domNode;\n\tdomNode.className = this.dropzoneClass || \"tc-dropzone\";\n\t// Add event handlers\n\tif(this.dropzoneEnable) {\n\t\t$tw.utils.addEventListeners(domNode,[\n\t\t\t{name: \"dragenter\", handlerObject: this, handlerMethod: \"handleDragEnterEvent\"},\n\t\t\t{name: \"dragover\", handlerObject: this, handlerMethod: \"handleDragOverEvent\"},\n\t\t\t{name: \"dragleave\", handlerObject: this, handlerMethod: \"handleDragLeaveEvent\"},\n\t\t\t{name: \"drop\", handlerObject: this, handlerMethod: \"handleDropEvent\"},\n\t\t\t{name: \"paste\", handlerObject: this, handlerMethod: \"handlePasteEvent\"},\n\t\t\t{name: \"dragend\", handlerObject: this, handlerMethod: \"handleDragEndEvent\"}\n\t\t]);\n\t}\n\t// Insert element\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n\t// Stack of outstanding enter/leave events\n\tthis.currentlyEntered = [];\n};\n\n// Handler for transient event listeners added when the dropzone has an active drag in progress\nDropZoneWidget.prototype.handleEvent = function(event) {\n\tif(event.type === \"click\") {\n\t\tif(this.currentlyEntered.length) {\n\t\t\tthis.resetState();\n\t\t}\n\t} else if(event.type === \"dragenter\") {\n\t\tif(event.target && event.target !== this.domNode && !$tw.utils.domContains(this.domNode,event.target)) {\n\t\t\tthis.resetState();\n\t\t}\n\t} else if(event.type === \"dragleave\") {\n\t\t// Check if drag left the window\n\t\tif(event.relatedTarget === null || (event.relatedTarget && event.relatedTarget.nodeName === \"HTML\")) {\n\t\t\tthis.resetState();\n\t\t}\n\t}\n};\n\n// Reset the state of the dropzone after a drag has ended\nDropZoneWidget.prototype.resetState = function() {\n\t$tw.utils.removeClass(this.domNode,\"tc-dragover\");\n\tthis.currentlyEntered = [];\n\tthis.document.body.removeEventListener(\"click\",this,true);\n\tthis.document.body.removeEventListener(\"dragenter\",this,true);\n\tthis.document.body.removeEventListener(\"dragleave\",this,true);\n\tthis.dragInProgress = false;\n};\n\nDropZoneWidget.prototype.enterDrag = function(event) {\n\tif(this.currentlyEntered.indexOf(event.target) === -1) {\n\t\tthis.currentlyEntered.push(event.target);\n\t}\n\tif(!this.dragInProgress) {\n\t\tthis.dragInProgress = true;\n\t\t// If we're entering for the first time we need to apply highlighting\n\t\t$tw.utils.addClass(this.domNodes[0],\"tc-dragover\");\n\t\tthis.document.body.addEventListener(\"click\",this,true);\n\t\tthis.document.body.addEventListener(\"dragenter\",this,true);\n\t\tthis.document.body.addEventListener(\"dragleave\",this,true);\n\t}\n};\n\nDropZoneWidget.prototype.leaveDrag = function(event) {\n\tvar pos = this.currentlyEntered.indexOf(event.target);\n\tif(pos !== -1) {\n\t\tthis.currentlyEntered.splice(pos,1);\n\t}\n\t// Remove highlighting if we're leaving externally\n\tif(this.currentlyEntered.length === 0) {\n\t\tthis.resetState();\n\t}\n};\n\nDropZoneWidget.prototype.handleDragEnterEvent  = function(event) {\n\tif($tw.dragInProgress) {\n\t\treturn false;\n\t}\n\tif(this.filesOnly && !$tw.utils.dragEventContainsFiles(event)) {\n\t\treturn false;\n\t}\n\tthis.enterDrag(event);\n\t// Tell the browser that we're ready to handle the drop\n\tevent.preventDefault();\n\t// Tell the browser not to ripple the drag up to any parent drop handlers\n\tevent.stopPropagation();\n};\n\nDropZoneWidget.prototype.handleDragOverEvent  = function(event) {\n\t// Check for being over a TEXTAREA or INPUT\n\tif([\"TEXTAREA\",\"INPUT\"].indexOf(event.target.tagName) !== -1) {\n\t\treturn false;\n\t}\n\t// Check for this window being the source of the drag\n\tif($tw.dragInProgress) {\n\t\treturn false;\n\t}\n\t// Tell the browser that we're still interested in the drop\n\tevent.preventDefault();\n\t// Check if this is a synthetic event, IE does not allow accessing dropEffect outside of original event handler\n\tif(event.isTrusted) {\n\t\tevent.dataTransfer.dropEffect = \"copy\"; // Explicitly show this is a copy\n\t}\n};\n\nDropZoneWidget.prototype.handleDragLeaveEvent  = function(event) {\n\tthis.leaveDrag(event);\n};\n\nDropZoneWidget.prototype.handleDragEndEvent = function(event) {\n\tthis.resetState();\n};\n\nDropZoneWidget.prototype.filterByContentTypes = function(tiddlerFieldsArray) {\n\tvar filteredTypes,\n\t\tfiltered = [],\n\t\ttypes = [];\n\t$tw.utils.each(tiddlerFieldsArray,function(tiddlerFields) {\n\t\ttypes.push(tiddlerFields.type || \"\");\n\t});\n\tfilteredTypes = this.wiki.filterTiddlers(this.contentTypesFilter,this,this.wiki.makeTiddlerIterator(types));\n\t$tw.utils.each(tiddlerFieldsArray,function(tiddlerFields) {\n\t\tif(filteredTypes.indexOf(tiddlerFields.type) !== -1) {\n\t\t\tfiltered.push(tiddlerFields);\n\t\t}\n\t});\n\treturn filtered;\n};\n\nDropZoneWidget.prototype.readFileCallback = function(tiddlerFieldsArray) {\n\tif(this.contentTypesFilter) {\n\t\ttiddlerFieldsArray = this.filterByContentTypes(tiddlerFieldsArray);\n\t}\n\tif(tiddlerFieldsArray.length) {\n\t\tthis.dispatchEvent({type: \"tm-import-tiddlers\", param: JSON.stringify(tiddlerFieldsArray), autoOpenOnImport: this.autoOpenOnImport, importTitle: this.importTitle});\n\t\tif(this.actions) {\n\t\t\tthis.invokeActionString(this.actions,this,event,{importTitle: this.importTitle});\n\t\t}\n\t}\n};\n\nDropZoneWidget.prototype.handleDropEvent  = function(event) {\n\tvar self = this,\n\t\treadFileCallback = function(tiddlerFieldsArray) {\n\t\t\tself.readFileCallback(tiddlerFieldsArray);\n\t\t};\n\tthis.leaveDrag(event);\n\t// Check for being over a TEXTAREA or INPUT\n\tif([\"TEXTAREA\",\"INPUT\"].indexOf(event.target.tagName) !== -1) {\n\t\treturn false;\n\t}\n\t// Check for this window being the source of the drag\n\tif($tw.dragInProgress) {\n\t\treturn false;\n\t}\n\tvar self = this,\n\t\tdataTransfer = event.dataTransfer;\n\t// Remove highlighting\n\tthis.resetState();\n\t// Import any files in the drop\n\tvar numFiles = 0;\n\t// If we have type text/vnd.tiddlywiki then skip trying to import files\n\tif(dataTransfer.files && !$tw.utils.dragEventContainsType(event,\"text/vnd.tiddler\")) {\n\t\tnumFiles = this.wiki.readFiles(dataTransfer.files,{\n\t\t\tcallback: readFileCallback,\n\t\t\tdeserializer: this.dropzoneDeserializer\n\t\t});\n\t}\n\t// Try to import the various data types we understand\n\tif(numFiles === 0) {\n\t\tvar fallbackTitle = self.wiki.generateNewTitle(\"Untitled\");\n\t\t//Use the deserializer specified if any\n\t\tif(this.dropzoneDeserializer) {\n\t\t\tfor(var t= 0; t<dataTransfer.items.length; t++) {\n\t\t\t\tvar item = dataTransfer.items[t];\n\t\t\t\tif(item.kind === \"string\") {\n\t\t\t\t\titem.getAsString(function(str){\n\t\t\t\t\t\tvar tiddlerFields = self.wiki.deserializeTiddlers(null,str,{title: fallbackTitle},{deserializer:self.dropzoneDeserializer});\n\t\t\t\t\t\tif(tiddlerFields && tiddlerFields.length) {\n\t\t\t\t\t\t\treadFileCallback(tiddlerFields);\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t$tw.utils.importDataTransfer(dataTransfer,fallbackTitle,readFileCallback);\n\t\t}\n\t}\n\t// Tell the browser that we handled the drop\n\tevent.preventDefault();\n\t// Stop the drop ripple up to any parent handlers\n\tevent.stopPropagation();\n};\n\nDropZoneWidget.prototype.handlePasteEvent  = function(event) {\n\tvar self = this;\n\tvar\treadFileCallback = function(tiddlerFieldsArray) {\n\t\t\tself.readFileCallback(tiddlerFieldsArray);\n\t\t};\n\tvar getItem = function(type) {\n\t\t\ttype = type || \"text/plain\";\n\t\t\treturn function(str) {\n\t\t\t\t// Use the deserializer specified if any\n\t\t\t\tif(self.dropzoneDeserializer) {\n\t\t\t\t\ttiddlerFields = self.wiki.deserializeTiddlers(null,str,{title: self.wiki.generateNewTitle(\"Untitled \" + type)},{deserializer:self.dropzoneDeserializer});\n\t\t\t\t\tif(tiddlerFields && tiddlerFields.length) {\n\t\t\t\t\t\treadFileCallback(tiddlerFields);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\ttiddlerFields = {\n\t\t\t\t\t\ttitle: self.wiki.generateNewTitle(\"Untitled \" + type),\n\t\t\t\t\t\ttext: str,\n\t\t\t\t\t\ttype: type\n\t\t\t\t\t};\n\t\t\t\t\tif($tw.log.IMPORT) {\n\t\t\t\t\t\tconsole.log(\"Importing string '\" + str + \"', type: '\" + type + \"'\");\n\t\t\t\t\t}\n\t\t\t\t\treadFileCallback([tiddlerFields]);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t// Let the browser handle it if we're in a textarea or input box\n\tif([\"TEXTAREA\",\"INPUT\"].indexOf(event.target.tagName) == -1 && !event.target.isContentEditable && !event.twEditor) {\n\t\tvar self = this,\n\t\t\titems = event.clipboardData.items;\n\t\t// Enumerate the clipboard items\n\t\tfor(var t = 0; t<items.length; t++) {\n\t\t\tvar item = items[t];\n\t\t\tif(item.kind === \"file\") {\n\t\t\t\t// Import any files\n\t\t\t\tthis.wiki.readFile(item.getAsFile(),{\n\t\t\t\t\tcallback: readFileCallback,\n\t\t\t\t\tdeserializer: this.dropzoneDeserializer\n\t\t\t\t});\n\t\t\t} else if(item.kind === \"string\" && ![\"text/html\", \"text/plain\", \"Text\"].includes(item.type) && $tw.utils.itemHasValidDataType(item)) {\n\t\t\t\t// Try to import the various data types we understand\n\t\t\t\tvar fallbackTitle = self.wiki.generateNewTitle(\"Untitled\");\n\t\t\t\t//Use the deserializer specified if any\n\t\t\t\tif(this.dropzoneDeserializer) {\n\t\t\t\t\titem.getAsString(function(str){\n\t\t\t\t\t\tvar tiddlerFields = self.wiki.deserializeTiddlers(null,str,{title: fallbackTitle},{deserializer:self.dropzoneDeserializer});\n\t\t\t\t\t\tif(tiddlerFields && tiddlerFields.length) {\n\t\t\t\t\t\t\treadFileCallback(tiddlerFields);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\t$tw.utils.importPaste(item,fallbackTitle,readFileCallback);\n\t\t\t\t}\n\t\t\t} else if(item.kind === \"string\") {\n\t\t\t\t// Create tiddlers from string items\n\t\t\t\tvar tiddlerFields;\n\t\t\t\t// It's important to give getAsString a closure with the right type\n\t\t\t\t// So it can be added to the import queue\n\t\t\t\titem.getAsString(getItem(item.type));\n\t\t\t}\n\t\t}\n\t\t// Tell the browser that we've handled the paste\n\t\tevent.stopPropagation();\n\t\tevent.preventDefault();\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nDropZoneWidget.prototype.execute = function() {\n\tthis.dropzoneClass = this.getAttribute(\"class\");\n\tthis.dropzoneDeserializer = this.getAttribute(\"deserializer\");\n\tthis.dropzoneEnable = (this.getAttribute(\"enable\") || \"yes\") === \"yes\";\n\tthis.autoOpenOnImport = this.getAttribute(\"autoOpenOnImport\");\n\tthis.importTitle = this.getAttribute(\"importTitle\",IMPORT_TITLE);\n\tthis.actions = this.getAttribute(\"actions\");\n\tthis.contentTypesFilter = this.getAttribute(\"contentTypesFilter\");\n\tthis.filesOnly = this.getAttribute(\"filesOnly\",\"no\") === \"yes\";\n\t// Make child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nDropZoneWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif($tw.utils.count(changedAttributes) > 0) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.dropzone = DropZoneWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/edit-binary.js":{"title":"$:/core/modules/widgets/edit-binary.js","text":"/*\\\ntitle: $:/core/modules/widgets/edit-binary.js\ntype: application/javascript\nmodule-type: widget\n\nEdit-binary widget; placeholder for editing binary tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar BINARY_WARNING_MESSAGE = \"$:/core/ui/BinaryWarning\";\nvar EXPORT_BUTTON_IMAGE = \"$:/core/images/export-button\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar EditBinaryWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nEditBinaryWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nEditBinaryWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nEditBinaryWidget.prototype.execute = function() {\n\t// Get our parameters\n\tvar editTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tvar tiddler = this.wiki.getTiddler(editTitle);\n\tvar type = tiddler.fields.type;\n\tvar text = tiddler.fields.text;\n\t// Transclude the binary data tiddler warning message\n\tvar warn = {\n\t\ttype: \"element\",\n\t\ttag: \"p\",\n\t\tchildren: [{\n\t\t\ttype: \"transclude\",\n\t\t\tattributes: {\n\t\t\t\ttiddler: {type: \"string\", value: BINARY_WARNING_MESSAGE}\n\t\t\t}\n\t\t}]\n\t};\n\t// Create download link based on draft tiddler title\n\tvar link = {\n\t\ttype: \"element\",\n\t\ttag: \"a\",\n\t\tattributes: {\n\t\t\ttitle: {type: \"indirect\", textReference: \"!!draft.title\"},\n\t\t\tdownload: {type: \"indirect\", textReference: \"!!draft.title\"}\n\t\t},\n\t\tchildren: [{\n\t\ttype: \"transclude\",\n\t\t\tattributes: {\n\t\t\t\ttiddler: {type: \"string\", value: EXPORT_BUTTON_IMAGE}\n\t\t\t}\n\t\t}]\n\t};\n\t// Set the link href to internal data URI (no external)\n\tif(text) {\n\t\tlink.attributes.href = {\n\t\t\ttype: \"string\", \n\t\t\tvalue: \"data:\" + type + \";base64,\" + text\n\t\t};\n\t}\n\t// Combine warning message and download link in a div\n\tvar element = {\n\t\ttype: \"element\",\n\t\ttag: \"div\",\n\t\tattributes: {\n\t\t\tclass: {type: \"string\", value: \"tc-binary-warning\"}\n\t\t},\n\t\tchildren: [warn, link]\n\t}\n\t// Construct the child widgets\n\tthis.makeChildWidgets([element]);\n};\n\n/*\nRefresh by refreshing our child widget\n*/\nEditBinaryWidget.prototype.refresh = function(changedTiddlers) {\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports[\"edit-binary\"] = EditBinaryWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/edit-bitmap.js":{"title":"$:/core/modules/widgets/edit-bitmap.js","text":"/*\\\ntitle: $:/core/modules/widgets/edit-bitmap.js\ntype: application/javascript\nmodule-type: widget\n\nEdit-bitmap widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Default image sizes\nvar DEFAULT_IMAGE_WIDTH = 600,\n\tDEFAULT_IMAGE_HEIGHT = 370,\n\tDEFAULT_IMAGE_TYPE = \"image/png\";\n\n// Configuration tiddlers\nvar LINE_WIDTH_TITLE = \"$:/config/BitmapEditor/LineWidth\",\n\tLINE_COLOUR_TITLE = \"$:/config/BitmapEditor/Colour\",\n\tLINE_OPACITY_TITLE = \"$:/config/BitmapEditor/Opacity\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar EditBitmapWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nEditBitmapWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nEditBitmapWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Initialise the editor operations if they've not been done already\n\tif(!this.editorOperations) {\n\t\tEditBitmapWidget.prototype.editorOperations = {};\n\t\t$tw.modules.applyMethods(\"bitmapeditoroperation\",this.editorOperations);\n\t}\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\t// Create the wrapper for the toolbar and render its content\n\tthis.toolbarNode = this.document.createElement(\"div\");\n\tthis.toolbarNode.className = \"tc-editor-toolbar\";\n\tparent.insertBefore(this.toolbarNode,nextSibling);\n\tthis.domNodes.push(this.toolbarNode);\n\t// Create the on-screen canvas\n\tthis.canvasDomNode = $tw.utils.domMaker(\"canvas\",{\n\t\tdocument: this.document,\n\t\t\"class\":\"tc-edit-bitmapeditor\",\n\t\teventListeners: [{\n\t\t\tname: \"touchstart\", handlerObject: this, handlerMethod: \"handleTouchStartEvent\"\n\t\t},{\n\t\t\tname: \"touchmove\", handlerObject: this, handlerMethod: \"handleTouchMoveEvent\"\n\t\t},{\n\t\t\tname: \"touchend\", handlerObject: this, handlerMethod: \"handleTouchEndEvent\"\n\t\t},{\n\t\t\tname: \"mousedown\", handlerObject: this, handlerMethod: \"handleMouseDownEvent\"\n\t\t},{\n\t\t\tname: \"mousemove\", handlerObject: this, handlerMethod: \"handleMouseMoveEvent\"\n\t\t},{\n\t\t\tname: \"mouseup\", handlerObject: this, handlerMethod: \"handleMouseUpEvent\"\n\t\t}]\n\t});\n\t// Set the width and height variables\n\tthis.setVariable(\"tv-bitmap-editor-width\",this.canvasDomNode.width + \"px\");\n\tthis.setVariable(\"tv-bitmap-editor-height\",this.canvasDomNode.height + \"px\");\n\t// Render toolbar child widgets\n\tthis.renderChildren(this.toolbarNode,null);\n\t// // Insert the elements into the DOM\n\tparent.insertBefore(this.canvasDomNode,nextSibling);\n\tthis.domNodes.push(this.canvasDomNode);\n\t// Load the image into the canvas\n\tif($tw.browser) {\n\t\tthis.loadCanvas();\n\t}\n\t// Add widget message listeners\n\tthis.addEventListeners([\n\t\t{type: \"tm-edit-bitmap-operation\", handler: \"handleEditBitmapOperationMessage\"}\n\t]);\n};\n\n/*\nHandle an edit bitmap operation message from the toolbar\n*/\nEditBitmapWidget.prototype.handleEditBitmapOperationMessage = function(event) {\n\t// Invoke the handler\n\tvar handler = this.editorOperations[event.param];\n\tif(handler) {\n\t\thandler.call(this,event);\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nEditBitmapWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.editTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\t// Make the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nJust refresh the toolbar\n*/\nEditBitmapWidget.prototype.refresh = function(changedTiddlers) {\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nSet the bitmap size variables and refresh the toolbar\n*/\nEditBitmapWidget.prototype.refreshToolbar = function() {\n\t// Set the width and height variables\n\tthis.setVariable(\"tv-bitmap-editor-width\",this.canvasDomNode.width + \"px\");\n\tthis.setVariable(\"tv-bitmap-editor-height\",this.canvasDomNode.height + \"px\");\n\t// Refresh each of our child widgets\n\t$tw.utils.each(this.children,function(childWidget) {\n\t\tchildWidget.refreshSelf();\n\t});\n};\n\nEditBitmapWidget.prototype.loadCanvas = function() {\n\tvar tiddler = this.wiki.getTiddler(this.editTitle),\n\t\tcurrImage = new Image();\n\t// Set up event handlers for loading the image\n\tvar self = this;\n\tcurrImage.onload = function() {\n\t\t// Copy the image to the on-screen canvas\n\t\tself.initCanvas(self.canvasDomNode,currImage.width,currImage.height,currImage);\n\t\t// And also copy the current bitmap to the off-screen canvas\n\t\tself.currCanvas = self.document.createElement(\"canvas\");\n\t\tself.initCanvas(self.currCanvas,currImage.width,currImage.height,currImage);\n\t\t// Set the width and height input boxes\n\t\tself.refreshToolbar();\n\t};\n\tcurrImage.onerror = function() {\n\t\t// Set the on-screen canvas size and clear it\n\t\tself.initCanvas(self.canvasDomNode,DEFAULT_IMAGE_WIDTH,DEFAULT_IMAGE_HEIGHT);\n\t\t// Set the off-screen canvas size and clear it\n\t\tself.currCanvas = self.document.createElement(\"canvas\");\n\t\tself.initCanvas(self.currCanvas,DEFAULT_IMAGE_WIDTH,DEFAULT_IMAGE_HEIGHT);\n\t\t// Set the width and height input boxes\n\t\tself.refreshToolbar();\n\t};\n\t// Get the current bitmap into an image object\n\tif(tiddler && tiddler.fields.type && tiddler.fields.text) {\n\t\tcurrImage.src = \"data:\" + tiddler.fields.type + \";base64,\" + tiddler.fields.text;\n\t} else {\n\t\tcurrImage.width = DEFAULT_IMAGE_WIDTH;\n\t\tcurrImage.height = DEFAULT_IMAGE_HEIGHT;\n\t\tcurrImage.onerror();\n\t}\n};\n\nEditBitmapWidget.prototype.initCanvas = function(canvas,width,height,image) {\n\tcanvas.width = width;\n\tcanvas.height = height;\n\tvar ctx = canvas.getContext(\"2d\");\n\tif(image) {\n\t\tctx.drawImage(image,0,0);\n\t} else {\n\t\tctx.fillStyle = \"#fff\";\n\t\tctx.fillRect(0,0,canvas.width,canvas.height);\n\t}\n};\n\n/*\n** Change the size of the canvas, preserving the current image\n*/\nEditBitmapWidget.prototype.changeCanvasSize = function(newWidth,newHeight) {\n\t// Create and size a new canvas\n\tvar newCanvas = this.document.createElement(\"canvas\");\n\tthis.initCanvas(newCanvas,newWidth,newHeight);\n\t// Copy the old image\n\tvar ctx = newCanvas.getContext(\"2d\");\n\tctx.drawImage(this.currCanvas,0,0);\n\t// Set the new canvas as the current one\n\tthis.currCanvas = newCanvas;\n\t// Set the size of the onscreen canvas\n\tthis.canvasDomNode.width = newWidth;\n\tthis.canvasDomNode.height = newHeight;\n\t// Paint the onscreen canvas with the offscreen canvas\n\tctx = this.canvasDomNode.getContext(\"2d\");\n\tctx.drawImage(this.currCanvas,0,0);\n};\n\n/*\n** Rotate the canvas left by 90 degrees\n*/\nEditBitmapWidget.prototype.rotateCanvasLeft = function() {\n\t// Get the current size of the image\n\tvar origWidth = this.currCanvas.width,\n\t\torigHeight = this.currCanvas.height;\n\t// Create and size a new canvas\n\tvar newCanvas = this.document.createElement(\"canvas\"),\n\t\tnewWidth = origHeight,\n\t\tnewHeight = origWidth;\n\tthis.initCanvas(newCanvas,newWidth,newHeight);\n\t// Copy the old image\n\tvar ctx = newCanvas.getContext(\"2d\");\n\tctx.save();\n\tctx.translate(newWidth / 2,newHeight / 2);\n\tctx.rotate(-Math.PI / 2);\n\tctx.drawImage(this.currCanvas,-origWidth / 2,-origHeight / 2);\n\tctx.restore();\n\t// Set the new canvas as the current one\n\tthis.currCanvas = newCanvas;\n\t// Set the size of the onscreen canvas\n\tthis.canvasDomNode.width = newWidth;\n\tthis.canvasDomNode.height = newHeight;\n\t// Paint the onscreen canvas with the offscreen canvas\n\tctx = this.canvasDomNode.getContext(\"2d\");\n\tctx.drawImage(this.currCanvas,0,0);\n};\n\nEditBitmapWidget.prototype.handleTouchStartEvent = function(event) {\n\tthis.brushDown = true;\n\tthis.strokeStart(event.touches[0].clientX,event.touches[0].clientY);\n\tevent.preventDefault();\n\tevent.stopPropagation();\n\treturn false;\n};\n\nEditBitmapWidget.prototype.handleTouchMoveEvent = function(event) {\n\tif(this.brushDown) {\n\t\tthis.strokeMove(event.touches[0].clientX,event.touches[0].clientY);\n\t}\n\tevent.preventDefault();\n\tevent.stopPropagation();\n\treturn false;\n};\n\nEditBitmapWidget.prototype.handleTouchEndEvent = function(event) {\n\tif(this.brushDown) {\n\t\tthis.brushDown = false;\n\t\tthis.strokeEnd();\n\t}\n\tevent.preventDefault();\n\tevent.stopPropagation();\n\treturn false;\n};\n\nEditBitmapWidget.prototype.handleMouseDownEvent = function(event) {\n\tthis.strokeStart(event.clientX,event.clientY);\n\tthis.brushDown = true;\n\tevent.preventDefault();\n\tevent.stopPropagation();\n\treturn false;\n};\n\nEditBitmapWidget.prototype.handleMouseMoveEvent = function(event) {\n\tif(this.brushDown) {\n\t\tthis.strokeMove(event.clientX,event.clientY);\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t\treturn false;\n\t}\n\treturn true;\n};\n\nEditBitmapWidget.prototype.handleMouseUpEvent = function(event) {\n\tif(this.brushDown) {\n\t\tthis.brushDown = false;\n\t\tthis.strokeEnd();\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t\treturn false;\n\t}\n\treturn true;\n};\n\nEditBitmapWidget.prototype.adjustCoordinates = function(x,y) {\n\tvar canvasRect = this.canvasDomNode.getBoundingClientRect(),\n\t\tscale = this.canvasDomNode.width/canvasRect.width;\n\treturn {x: (x - canvasRect.left) * scale, y: (y - canvasRect.top) * scale};\n};\n\nEditBitmapWidget.prototype.strokeStart = function(x,y) {\n\t// Start off a new stroke\n\tthis.stroke = [this.adjustCoordinates(x,y)];\n};\n\nEditBitmapWidget.prototype.strokeMove = function(x,y) {\n\tvar ctx = this.canvasDomNode.getContext(\"2d\"),\n\t\tt;\n\t// Add the new position to the end of the stroke\n\tthis.stroke.push(this.adjustCoordinates(x,y));\n\t// Redraw the previous image\n\tctx.drawImage(this.currCanvas,0,0);\n\t// Render the stroke\n\tctx.globalAlpha = parseFloat(this.wiki.getTiddlerText(LINE_OPACITY_TITLE,\"1.0\"));\n\tctx.strokeStyle = this.wiki.getTiddlerText(LINE_COLOUR_TITLE,\"#ff0\");\n\tctx.lineWidth = parseFloat(this.wiki.getTiddlerText(LINE_WIDTH_TITLE,\"3\"));\n\tctx.lineCap = \"round\";\n\tctx.lineJoin = \"round\";\n\tctx.beginPath();\n\tctx.moveTo(this.stroke[0].x,this.stroke[0].y);\n\tfor(t=1; t<this.stroke.length-1; t++) {\n\t\tvar s1 = this.stroke[t],\n\t\t\ts2 = this.stroke[t-1],\n\t\t\ttx = (s1.x + s2.x)/2,\n\t\t\tty = (s1.y + s2.y)/2;\n\t\tctx.quadraticCurveTo(s2.x,s2.y,tx,ty);\n\t}\n\tctx.stroke();\n};\n\nEditBitmapWidget.prototype.strokeEnd = function() {\n\t// Copy the bitmap to the off-screen canvas\n\tvar ctx = this.currCanvas.getContext(\"2d\");\n\tctx.drawImage(this.canvasDomNode,0,0);\n\t// Save the image into the tiddler\n\tthis.saveChanges();\n};\n\nEditBitmapWidget.prototype.saveChanges = function() {\n\tvar tiddler = this.wiki.getTiddler(this.editTitle) || new $tw.Tiddler({title: this.editTitle,type: DEFAULT_IMAGE_TYPE});\n\t// data URIs look like \"data:<type>;base64,<text>\"\n\tvar dataURL = this.canvasDomNode.toDataURL(tiddler.fields.type),\n\t\tposColon = dataURL.indexOf(\":\"),\n\t\tposSemiColon = dataURL.indexOf(\";\"),\n\t\tposComma = dataURL.indexOf(\",\"),\n\t\ttype = dataURL.substring(posColon+1,posSemiColon),\n\t\ttext = dataURL.substring(posComma+1);\n\tvar update = {type: type, text: text};\n\tthis.wiki.addTiddler(new $tw.Tiddler(this.wiki.getModificationFields(),tiddler,update,this.wiki.getCreationFields()));\n};\n\nexports[\"edit-bitmap\"] = EditBitmapWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/edit-shortcut.js":{"title":"$:/core/modules/widgets/edit-shortcut.js","text":"/*\\\ntitle: $:/core/modules/widgets/edit-shortcut.js\ntype: application/javascript\nmodule-type: widget\n\nWidget to display an editable keyboard shortcut\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar EditShortcutWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nEditShortcutWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nEditShortcutWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.inputNode = this.document.createElement(\"input\");\n\t// Assign classes\n\tif(this.shortcutClass) {\n\t\tthis.inputNode.className = this.shortcutClass;\n\t}\n\t// Assign other attributes\n\tif(this.shortcutStyle) {\n\t\tthis.inputNode.setAttribute(\"style\",this.shortcutStyle);\n\t}\n\tif(this.shortcutTooltip) {\n\t\tthis.inputNode.setAttribute(\"title\",this.shortcutTooltip);\n\t}\n\tif(this.shortcutPlaceholder) {\n\t\tthis.inputNode.setAttribute(\"placeholder\",this.shortcutPlaceholder);\n\t}\n\tif(this.shortcutAriaLabel) {\n\t\tthis.inputNode.setAttribute(\"aria-label\",this.shortcutAriaLabel);\n\t}\n\t// Assign the current shortcut\n\tthis.updateInputNode();\n\t// Add event handlers\n\t$tw.utils.addEventListeners(this.inputNode,[\n\t\t{name: \"keydown\", handlerObject: this, handlerMethod: \"handleKeydownEvent\"}\n\t]);\n\t// Link into the DOM\n\tparent.insertBefore(this.inputNode,nextSibling);\n\tthis.domNodes.push(this.inputNode);\n\t// Focus the input Node if focus === \"yes\" or focus === \"true\"\n\tif(this.shortcutFocus === \"yes\" || this.shortcutFocus === \"true\") {\n\t\tthis.focus();\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nEditShortcutWidget.prototype.execute = function() {\n\tthis.shortcutTiddler = this.getAttribute(\"tiddler\");\n\tthis.shortcutField = this.getAttribute(\"field\");\n\tthis.shortcutIndex = this.getAttribute(\"index\");\n\tthis.shortcutPlaceholder = this.getAttribute(\"placeholder\");\n\tthis.shortcutDefault = this.getAttribute(\"default\",\"\");\n\tthis.shortcutClass = this.getAttribute(\"class\");\n\tthis.shortcutStyle = this.getAttribute(\"style\");\n\tthis.shortcutTooltip = this.getAttribute(\"tooltip\");\n\tthis.shortcutAriaLabel = this.getAttribute(\"aria-label\");\n\tthis.shortcutFocus = this.getAttribute(\"focus\");\n};\n\n/*\nUpdate the value of the input node\n*/\nEditShortcutWidget.prototype.updateInputNode = function() {\n\tif(this.shortcutField) {\n\t\tvar tiddler = this.wiki.getTiddler(this.shortcutTiddler);\n\t\tif(tiddler && $tw.utils.hop(tiddler.fields,this.shortcutField)) {\n\t\t\tthis.inputNode.value = tiddler.getFieldString(this.shortcutField);\n\t\t} else {\n\t\t\tthis.inputNode.value = this.shortcutDefault;\n\t\t}\n\t} else if(this.shortcutIndex) {\n\t\tthis.inputNode.value = this.wiki.extractTiddlerDataItem(this.shortcutTiddler,this.shortcutIndex,this.shortcutDefault);\n\t} else {\n\t\tthis.inputNode.value = this.wiki.getTiddlerText(this.shortcutTiddler,this.shortcutDefault);\n\t}\n};\n\n/*\nHandle a dom \"keydown\" event\n*/\nEditShortcutWidget.prototype.handleKeydownEvent = function(event) {\n\t// Ignore shift, ctrl, meta, alt\n\tif(event.keyCode && $tw.keyboardManager.getModifierKeys().indexOf(event.keyCode) === -1) {\n\t\t// Get the shortcut text representation\n\t\tvar value = $tw.keyboardManager.getPrintableShortcuts([{\n\t\t\tctrlKey: event.ctrlKey,\n\t\t\tshiftKey: event.shiftKey,\n\t\t\taltKey: event.altKey,\n\t\t\tmetaKey: event.metaKey,\n\t\t\tkeyCode: event.keyCode\n\t\t}]);\n\t\tif(value.length > 0) {\n\t\t\tthis.wiki.setText(this.shortcutTiddler,this.shortcutField,this.shortcutIndex,value[0]);\n\t\t}\n\t\t// Ignore the keydown if it was already handled\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n};\n\n/*\nfocus the input node\n*/\nEditShortcutWidget.prototype.focus = function() {\n\tif(this.inputNode.focus && this.inputNode.select) {\n\t\tthis.inputNode.focus();\n\t\tthis.inputNode.select();\n\t}\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget needed re-rendering\n*/\nEditShortcutWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.placeholder || changedAttributes[\"default\"] || changedAttributes[\"class\"] || changedAttributes.style || changedAttributes.tooltip || changedAttributes[\"aria-label\"] || changedAttributes.focus) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else if(changedTiddlers[this.shortcutTiddler]) {\n\t\tthis.updateInputNode();\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n};\n\nexports[\"edit-shortcut\"] = EditShortcutWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/edit-text.js":{"title":"$:/core/modules/widgets/edit-text.js","text":"/*\\\ntitle: $:/core/modules/widgets/edit-text.js\ntype: application/javascript\nmodule-type: widget\n\nEdit-text widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar editTextWidgetFactory = require(\"$:/core/modules/editor/factory.js\").editTextWidgetFactory,\n\tFramedEngine = require(\"$:/core/modules/editor/engines/framed.js\").FramedEngine,\n\tSimpleEngine = require(\"$:/core/modules/editor/engines/simple.js\").SimpleEngine;\n\nexports[\"edit-text\"] = editTextWidgetFactory(FramedEngine,SimpleEngine);\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/edit.js":{"title":"$:/core/modules/widgets/edit.js","text":"/*\\\ntitle: $:/core/modules/widgets/edit.js\ntype: application/javascript\nmodule-type: widget\n\nEdit widget is a meta-widget chooses the appropriate actual editting widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar EditWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nEditWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nEditWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n// Mappings from content type to editor type are stored in tiddlers with this prefix\nvar EDITOR_MAPPING_PREFIX = \"$:/config/EditorTypeMappings/\";\n\n/*\nCompute the internal state of the widget\n*/\nEditWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.editTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.editField = this.getAttribute(\"field\",\"text\");\n\tthis.editIndex = this.getAttribute(\"index\");\n\tthis.editClass = this.getAttribute(\"class\");\n\tthis.editPlaceholder = this.getAttribute(\"placeholder\");\n\tthis.editTabIndex = this.getAttribute(\"tabindex\");\n\tthis.editFocus = this.getAttribute(\"focus\",\"\");\n\tthis.editCancelPopups = this.getAttribute(\"cancelPopups\",\"\");\n\tthis.editInputActions = this.getAttribute(\"inputActions\");\n\tthis.editRefreshTitle = this.getAttribute(\"refreshTitle\");\n\tthis.editAutoComplete = this.getAttribute(\"autocomplete\");\n\t// Choose the appropriate edit widget\n\tthis.editorType = this.getEditorType();\n\t// Make the child widgets\n\tthis.makeChildWidgets([{\n\t\ttype: \"edit-\" + this.editorType,\n\t\tattributes: this.parseTreeNode.attributes,\n\t\tchildren: this.parseTreeNode.children\n\t}]);\n};\n\nEditWidget.prototype.getEditorType = function() {\n\t// Get the content type of the thing we're editing\n\tvar type;\n\tif(this.editField === \"text\") {\n\t\tvar tiddler = this.wiki.getTiddler(this.editTitle);\n\t\tif(tiddler) {\n\t\t\ttype = tiddler.fields.type;\n\t\t}\n\t}\n\ttype = type || \"text/vnd.tiddlywiki\";\n\tvar editorType = this.wiki.getTiddlerText(EDITOR_MAPPING_PREFIX + type);\n\tif(!editorType) {\n\t\tvar typeInfo = $tw.config.contentTypeInfo[type];\n\t\tif(typeInfo && typeInfo.encoding === \"base64\") {\n\t\t\teditorType = \"binary\";\n\t\t} else {\n\t\t\teditorType = \"text\";\n\t\t}\n\t}\n\treturn editorType;\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nEditWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\t// Refresh if an attribute has changed, or the type associated with the target tiddler has changed\n\tif(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.tabindex || changedAttributes.cancelPopups || changedAttributes.inputActions || changedAttributes.refreshTitle || changedAttributes.autocomplete || (this.getEditorType() !== this.editorType)) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports.edit = EditWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/element.js":{"title":"$:/core/modules/widgets/element.js","text":"/*\\\ntitle: $:/core/modules/widgets/element.js\ntype: application/javascript\nmodule-type: widget\n\nElement widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar ElementWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nElementWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nElementWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\t// Neuter blacklisted elements\n\tthis.tag = this.parseTreeNode.tag;\n\tif($tw.config.htmlUnsafeElements.indexOf(this.tag) !== -1) {\n\t\tthis.tag = \"safe-\" + this.tag;\n\t}\n\t// Restrict tag name to digits, letts and dashes\n\tthis.tag = this.tag.replace(/[^0-9a-zA-Z\\-]/mg,\"\");\n\t// Default to a span\n\tthis.tag = this.tag || \"span\";\n\t// Adjust headings by the current base level\n\tvar headingLevel = [\"h1\",\"h2\",\"h3\",\"h4\",\"h5\",\"h6\"].indexOf(this.tag);\n\tif(headingLevel !== -1) {\n\t\tvar baseLevel = parseInt(this.getVariable(\"tv-adjust-heading-level\",\"0\"),10) || 0;\n\t\theadingLevel = Math.min(Math.max(headingLevel + 1 + baseLevel,1),6);\n\t\tthis.tag = \"h\" + headingLevel;\n\t}\n\t// Select the namespace for the tag\n\tvar XHTML_NAMESPACE = \"http://www.w3.org/1999/xhtml\",\n\t\ttagNamespaces = {\n\t\t\tsvg: \"http://www.w3.org/2000/svg\",\n\t\t\tmath: \"http://www.w3.org/1998/Math/MathML\",\n\t\t\tbody: XHTML_NAMESPACE\n\t\t};\n\tthis.namespace = tagNamespaces[this.tag];\n\tif(this.namespace) {\n\t\tthis.setVariable(\"namespace\",this.namespace);\n\t} else {\n\t\tif(this.hasAttribute(\"xmlns\")) {\n\t\t\tthis.namespace = this.getAttribute(\"xmlns\");\n\t\t\tthis.setVariable(\"namespace\",this.namespace);\n\t\t} else {\n\t\t\tthis.namespace = this.getVariable(\"namespace\",{defaultValue: XHTML_NAMESPACE});\n\t\t}\n\t}\n\t// Invoke the th-rendering-element hook\n\tvar parseTreeNodes = $tw.hooks.invokeHook(\"th-rendering-element\",null,this);\n\tthis.isReplaced = !!parseTreeNodes;\n\tif(parseTreeNodes) {\n\t\t// Use the parse tree nodes provided by the hook\n\t\tthis.makeChildWidgets(parseTreeNodes);\n\t\tthis.renderChildren(this.parentDomNode,null);\n\t\treturn;\n\t}\n\t// Make the child widgets\n\tthis.makeChildWidgets();\n\t// Create the DOM node and render children\n\tvar domNode = this.document.createElementNS(this.namespace,this.tag);\n\tthis.assignAttributes(domNode,{excludeEventAttributes: true});\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nElementWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes(),\n\t\thasChangedAttributes = $tw.utils.count(changedAttributes) > 0;\n\tif(hasChangedAttributes) {\n\t\tif(!this.isReplaced) {\n\t\t\t// Update our attributes\n\t\t\tthis.assignAttributes(this.domNodes[0],{excludeEventAttributes: true});\n\t\t} else {\n\t\t\t// If we were replaced then completely refresh ourselves\n\t\t\treturn this.refreshSelf();\n\t\t}\n\t}\n\treturn this.refreshChildren(changedTiddlers) || hasChangedAttributes;\n};\n\nexports.element = ElementWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/encrypt.js":{"title":"$:/core/modules/widgets/encrypt.js","text":"/*\\\ntitle: $:/core/modules/widgets/encrypt.js\ntype: application/javascript\nmodule-type: widget\n\nEncrypt widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar EncryptWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nEncryptWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nEncryptWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar textNode = this.document.createTextNode(this.encryptedText);\n\tparent.insertBefore(textNode,nextSibling);\n\tthis.domNodes.push(textNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nEncryptWidget.prototype.execute = function() {\n\t// Get parameters from our attributes\n\tthis.filter = this.getAttribute(\"filter\",\"[!is[system]]\");\n\t// Encrypt the filtered tiddlers\n\tvar tiddlers = this.wiki.filterTiddlers(this.filter),\n\t\tjson = {},\n\t\tself = this;\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tvar tiddler = self.wiki.getTiddler(title),\n\t\t\tjsonTiddler = {};\n\t\tfor(var f in tiddler.fields) {\n\t\t\tjsonTiddler[f] = tiddler.getFieldString(f);\n\t\t}\n\t\tjson[title] = jsonTiddler;\n\t});\n\tthis.encryptedText = $tw.utils.htmlEncode($tw.crypto.encrypt(JSON.stringify(json)));\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nEncryptWidget.prototype.refresh = function(changedTiddlers) {\n\t// We don't need to worry about refreshing because the encrypt widget isn't for interactive use\n\treturn false;\n};\n\nexports.encrypt = EncryptWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/entity.js":{"title":"$:/core/modules/widgets/entity.js","text":"/*\\\ntitle: $:/core/modules/widgets/entity.js\ntype: application/javascript\nmodule-type: widget\n\nHTML entity widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar EntityWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nEntityWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nEntityWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar entityString = this.getAttribute(\"entity\",this.parseTreeNode.entity || \"\"),\n\t\ttextNode = this.document.createTextNode($tw.utils.entityDecode(entityString));\n\tparent.insertBefore(textNode,nextSibling);\n\tthis.domNodes.push(textNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nEntityWidget.prototype.execute = function() {\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nEntityWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.entity) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n};\n\nexports.entity = EntityWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/error.js":{"title":"$:/core/modules/widgets/error.js","text":"/*\\\ntitle: $:/core/modules/widgets/error.js\ntype: application/javascript\nmodule-type: widget\n\nError widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar ErrorWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nErrorWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nErrorWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar message = this.getAttribute(\"$message\",\"Unknown error\"),\n\t\tdomNode = this.document.createElement(\"span\");\n\tdomNode.appendChild(this.document.createTextNode(message));\n\tdomNode.className = \"tc-error\";\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.domNodes.push(domNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nErrorWidget.prototype.execute = function() {\n\t// Nothing to do for a text node\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nErrorWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes[\"$message\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n};\n\nexports.error = ErrorWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/eventcatcher.js":{"title":"$:/core/modules/widgets/eventcatcher.js","text":"/*\\\ntitle: $:/core/modules/widgets/eventcatcher.js\ntype: application/javascript\nmodule-type: widget\n\nEvent handler widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar EventWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nEventWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nEventWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Remember parent\n\tthis.parentDomNode = parent;\n\t// Compute attributes and execute state\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Create element\n\tvar tag = this.parseTreeNode.isBlock ? \"div\" : \"span\";\n\tif(this.elementTag && $tw.config.htmlUnsafeElements.indexOf(this.elementTag) === -1) {\n\t\ttag = this.elementTag;\n\t}\n\tvar domNode = this.document.createElement(tag);\n\tthis.domNode = domNode;\n\t// Assign classes\n\tthis.assignDomNodeClasses();\n\t// Add our event handler\n\t$tw.utils.each(this.types,function(type) {\n\t\tdomNode.addEventListener(type,function(event) {\n\t\t\tvar selector = self.getAttribute(\"selector\"),\n\t\t\t\tmatchSelector = self.getAttribute(\"matchSelector\"),\n\t\t\t\tactions = self.getAttribute(\"$\"+type) || self.getAttribute(\"actions-\"+type),\n\t\t\t\tstopPropagation = self.getAttribute(\"stopPropagation\",\"onaction\"),\n\t\t\t\tselectedNode = event.target,\n\t\t\t\tselectedNodeRect,\n\t\t\t\tcatcherNodeRect,\n\t\t\t\tvariables = {};\n\t\t\t// Firefox can fire dragover and dragenter events on text nodes instead of their parents\n\t\t\tif(selectedNode.nodeType === 3) {\n\t\t\t\tselectedNode = selectedNode.parentNode;\n\t\t\t}\n\t\t\t// Check that the selected node matches any matchSelector\n\t\t\tif(matchSelector && !$tw.utils.domMatchesSelector(selectedNode,matchSelector)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif(selector) {\n\t\t\t\t// Search ancestors for a node that matches the selector\n\t\t\t\twhile(!$tw.utils.domMatchesSelector(selectedNode,selector) && selectedNode !== domNode) {\n\t\t\t\t\tselectedNode = selectedNode.parentNode;\n\t\t\t\t}\n\t\t\t\t// Exit if we didn't find one\n\t\t\t\tif(selectedNode === domNode) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\t// Only set up variables if we have actions to invoke\n\t\t\t\tif(actions) {\n\t\t\t\t\tvariables = $tw.utils.collectDOMVariables(selectedNode,self.domNode,event);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Execute our actions with the variables\n\t\t\tif(actions) {\n\t\t\t\t// Add a variable for the modifier key\n\t\t\t\tvariables.modifier = $tw.keyboardManager.getEventModifierKeyDescriptor(event);\n\t\t\t\t// Add a variable for the mouse button\n\t\t\t\tif(\"button\" in event) {\n\t\t\t\t\tif(event.button === 0) {\n\t\t\t\t\t\tvariables[\"event-mousebutton\"] = \"left\";\n\t\t\t\t\t} else if(event.button === 1) {\n\t\t\t\t\t\tvariables[\"event-mousebutton\"] = \"middle\";\n\t\t\t\t\t} else if(event.button === 2) {\n\t\t\t\t\t\tvariables[\"event-mousebutton\"] = \"right\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tvariables[\"event-type\"] = event.type.toString();\n\t\t\t\tif(typeof event.detail === \"object\" && !!event.detail) {\n\t\t\t\t\t$tw.utils.each(event.detail,function(detailValue,detail) {\n\t\t\t\t\t\tvariables[\"event-detail-\" + detail] = detailValue.toString();\n\t\t\t\t\t});\n\t\t\t\t} else if(!!event.detail) {\n\t\t\t\t\tvariables[\"event-detail\"] = event.detail.toString();\n\t\t\t\t}\n\t\t\t\tself.invokeActionString(actions,self,event,variables);\n\t\t\t}\n\t\t\tif((actions && stopPropagation === \"onaction\") || stopPropagation === \"always\") {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tevent.stopPropagation();\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t},false);\n\t});\n\t// Insert element\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nEventWidget.prototype.execute = function() {\n\tvar self = this;\n\t// Get attributes that require a refresh on change\n\tthis.types = [];\n\t$tw.utils.each(this.attributes,function(value,key) {\n\t\tif(key.charAt(0) === \"$\") {\n\t\t\tself.types.push(key.slice(1));\n\t\t}\n\t});\n\tif(!this.types.length) {\n\t\tthis.types = this.getAttribute(\"events\",\"\").split(\" \");\n\t}\n\tthis.elementTag = this.getAttribute(\"tag\");\n\t// Make child widgets\n\tthis.makeChildWidgets();\n};\n\nEventWidget.prototype.assignDomNodeClasses = function() {\n\tvar classes = this.getAttribute(\"class\",\"\").split(\" \");\n\tclasses.push(\"tc-eventcatcher\");\n\tthis.domNode.className = classes.join(\" \");\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nEventWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes(),\n\t\tchangedAttributesCount = $tw.utils.count(changedAttributes);\n\tif(changedAttributesCount === 1 && changedAttributes[\"class\"]) {\n\t\tthis.assignDomNodeClasses();\n\t} else if(changedAttributesCount > 0) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.eventcatcher = EventWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/fieldmangler.js":{"title":"$:/core/modules/widgets/fieldmangler.js","text":"/*\\\ntitle: $:/core/modules/widgets/fieldmangler.js\ntype: application/javascript\nmodule-type: widget\n\nField mangler widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar FieldManglerWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nFieldManglerWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nFieldManglerWidget.prototype.render = function(parent,nextSibling) {\n\tthis.addEventListeners([\n\t\t{type: \"tm-remove-field\", handler: \"handleRemoveFieldEvent\"},\n\t\t{type: \"tm-add-field\", handler: \"handleAddFieldEvent\"},\n\t\t{type: \"tm-remove-tag\", handler: \"handleRemoveTagEvent\"},\n\t\t{type: \"tm-add-tag\", handler: \"handleAddTagEvent\"}\n\t]);\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nFieldManglerWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.mangleTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nFieldManglerWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tiddler) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nFieldManglerWidget.prototype.handleRemoveFieldEvent = function(event) {\n\tvar tiddler = this.wiki.getTiddler(this.mangleTitle),\n\t\tdeletion = {};\n\tdeletion[event.param] = undefined;\n\tthis.wiki.addTiddler(new $tw.Tiddler(tiddler,deletion));\n\treturn false;\n};\n\nFieldManglerWidget.prototype.handleAddFieldEvent = function(event) {\n\tvar tiddler = this.wiki.getTiddler(this.mangleTitle),\n\t\taddition = this.wiki.getModificationFields(),\n\t\taddField = function(name,value) {\n\t\t\tvar trimmedName = name.trim();\n\t\t\tif(!value && tiddler) {\n\t\t\t\tvalue = tiddler.fields[trimmedName];\n\t\t\t}\n\t\t\taddition[trimmedName] = value || \"\";\n\t\t\treturn;\n\t\t};\n\taddition.title = this.mangleTitle;\n\tif(typeof event.param === \"string\") {\n\t\taddField(event.param,\"\");\n\t}\n\tif(typeof event.paramObject === \"object\") {\n\t\tfor(var name in event.paramObject) {\n\t\t\taddField(name,event.paramObject[name]);\n\t\t}\n\t}\n\tthis.wiki.addTiddler(new $tw.Tiddler(tiddler,addition));\n\treturn false;\n};\n\nFieldManglerWidget.prototype.handleRemoveTagEvent = function(event) {\n\tvar tiddler = this.wiki.getTiddler(this.mangleTitle),\n\t\tmodification = this.wiki.getModificationFields();\n\tif(tiddler && tiddler.fields.tags) {\n\t\tvar p = tiddler.fields.tags.indexOf(event.param);\n\t\tif(p !== -1) {\n\t\t\tmodification.tags = (tiddler.fields.tags || []).slice(0);\n\t\t\tmodification.tags.splice(p,1);\n\t\t\tif(modification.tags.length === 0) {\n\t\t\t\tmodification.tags = undefined;\n\t\t\t}\n\t\t\tthis.wiki.addTiddler(new $tw.Tiddler(tiddler,modification));\n\t\t}\n\t}\n\treturn false;\n};\n\nFieldManglerWidget.prototype.handleAddTagEvent = function(event) {\n\tvar tiddler = this.wiki.getTiddler(this.mangleTitle),\n\t\tmodification = this.wiki.getModificationFields();\n\tif(tiddler && typeof event.param === \"string\") {\n\t\tvar tag = event.param.trim();\n\t\tif(tag !== \"\") {\n\t\t\tmodification.tags = (tiddler.fields.tags || []).slice(0);\n\t\t\t$tw.utils.pushTop(modification.tags,tag);\n\t\t\tthis.wiki.addTiddler(new $tw.Tiddler(tiddler,modification));\n\t\t}\n\t} else if(typeof event.param === \"string\" && event.param.trim() !== \"\" && this.mangleTitle.trim() !== \"\") {\n\t\tvar tag = [];\n\t\ttag.push(event.param.trim());\n\t\tthis.wiki.addTiddler(new $tw.Tiddler({title: this.mangleTitle, tags: tag},modification));\n\t}\n\treturn false;\n};\n\nexports.fieldmangler = FieldManglerWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/fields.js":{"title":"$:/core/modules/widgets/fields.js","text":"/*\\\ntitle: $:/core/modules/widgets/fields.js\ntype: application/javascript\nmodule-type: widget\n\nFields widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar FieldsWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nFieldsWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nFieldsWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar textNode = this.document.createTextNode(this.text);\n\tparent.insertBefore(textNode,nextSibling);\n\tthis.domNodes.push(textNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nFieldsWidget.prototype.execute = function() {\n\t// Get parameters from our attributes\n\tthis.tiddlerTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.template = this.getAttribute(\"template\");\n\tthis.sort = this.getAttribute(\"sort\",\"yes\") === \"yes\";\n\tthis.sortReverse = this.getAttribute(\"sortReverse\",\"no\") === \"yes\";\n\tthis.exclude = this.getAttribute(\"exclude\");\n\tthis.include = this.getAttribute(\"include\",null);\n\tthis.stripTitlePrefix = this.getAttribute(\"stripTitlePrefix\",\"no\") === \"yes\";\n\t// Get the value to display\n\tvar tiddler = this.wiki.getTiddler(this.tiddlerTitle);\n\n\t// Get the inclusion and exclusion list\n\tvar excludeArr = (this.exclude) ? this.exclude.split(\" \") : [\"text\"];\n\t// Include takes precedence\n\tvar includeArr = (this.include) ? this.include.split(\" \") : null;\n\n\t// Compose the template\n\tvar text = [];\n\tif(this.template && tiddler) {\n\t\tvar fields = [];\n\t\tif (includeArr) { // Include takes precedence\n\t\t\tfor(var i=0; i<includeArr.length; i++) {\n\t\t\t\tif(tiddler.fields[includeArr[i]]) {\n\t\t\t\t\tfields.push(includeArr[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfor(var fieldName in tiddler.fields) {\n\t\t\t\tif(excludeArr.indexOf(fieldName) === -1) {\n\t\t\t\t\tfields.push(fieldName);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (this.sort) fields.sort();\n\t\tif (this.sortReverse) fields.reverse();\n\t\tfor(var f=0, fmax=fields.length; f<fmax; f++) {\n\t\t\tfieldName = fields[f];\n\t\t\tvar row = this.template,\n\t\t\t\tvalue = tiddler.getFieldString(fieldName);\n\t\t\tif(this.stripTitlePrefix && fieldName === \"title\") {\n\t\t\t\tvar reStrip = /^\\{[^\\}]+\\}(.+)/mg,\n\t\t\t\t\treMatch = reStrip.exec(value);\n\t\t\t\tif(reMatch) {\n\t\t\t\t\tvalue = reMatch[1];\n\t\t\t\t}\n\t\t\t}\n\t\t\trow = $tw.utils.replaceString(row,\"$name$\",fieldName);\n\t\t\trow = $tw.utils.replaceString(row,\"$value$\",value);\n\t\t\trow = $tw.utils.replaceString(row,\"$encoded_value$\",$tw.utils.htmlEncode(value));\n\t\t\ttext.push(row);\n\t\t}\n\t}\n\tthis.text = text.join(\"\");\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nFieldsWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif( changedAttributes.tiddler || changedAttributes.template || changedAttributes.exclude ||\n\t\tchangedAttributes.include || changedAttributes.sort || changedAttributes.sortReverse ||\n\t\tchangedTiddlers[this.tiddlerTitle] || changedAttributes.stripTitlePrefix) {\n\t\t\tthis.refreshSelf();\n\t\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n};\n\nexports.fields = FieldsWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/fill.js":{"title":"$:/core/modules/widgets/fill.js","text":"/*\\\ntitle: $:/core/modules/widgets/fill.js\ntype: application/javascript\nmodule-type: widget\n\nSub-widget used by the transclude widget for specifying values for slots within transcluded content. It doesn't do anything by itself because the transclude widget only ever deals with the parse tree nodes, and doesn't instantiate the widget itself\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar FillWidget = function(parseTreeNode,options) {\n\t// Initialise\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nFillWidget.prototype = new Widget();\n\nexports.fill = FillWidget;\n\n})();\n\t","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/genesis.js":{"title":"$:/core/modules/widgets/genesis.js","text":"/*\\\ntitle: $:/core/modules/widgets/genesis.js\ntype: application/javascript\nmodule-type: widget\n\nGenesis widget for dynamically creating widgets\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar GenesisWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nGenesisWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nGenesisWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes({filterFn: function(name) {\n\t\t// Only compute our own attributes which start with a single dollar\n\t\treturn name.charAt(0) === \"$\" && name.charAt(1) !== \"$\";\n\t}});\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nGenesisWidget.prototype.execute = function() {\n\tvar self = this;\n\t// Collect attributes\n\tthis.genesisType = this.getAttribute(\"$type\");\n\tthis.genesisRemappable = this.getAttribute(\"$remappable\",\"yes\") === \"yes\";\n\tthis.genesisNames = this.getAttribute(\"$names\",\"\");\n\tthis.genesisValues = this.getAttribute(\"$values\",\"\");\n\tthis.genesisIsBlock = this.getAttribute(\"$mode\",this.parseTreeNode.isBlock && \"block\") === \"block\";\n\t// Do not create a child widget if the $type attribute is missing or blank\n\tif(!this.genesisType) {\n\t\tthis.makeChildWidgets(this.parseTreeNode.children);\n\t\treturn;\n\t}\n\t// Construct parse tree\n\tvar isElementWidget = this.genesisType.charAt(0) !== \"$\",\n\t\tnodeType = isElementWidget ? \"element\" : this.genesisType.substr(1),\n\t\tnodeTag = isElementWidget ? this.genesisType : undefined;\n\tvar parseTreeNodes = [{\n\t\ttype: nodeType,\n\t\ttag: nodeTag,\n\t\tattributes: {},\n\t\torderedAttributes: [],\n\t\tisBlock: this.genesisIsBlock,\n\t\tchildren: this.parseTreeNode.children || [],\n\t\tisNotRemappable: !this.genesisRemappable\n\t}];\n\t// Apply attributes in $names/$values\n\tthis.attributeNames = [];\n\tthis.attributeValues = [];\n\tif(this.genesisNames && this.genesisValues) {\n\t\tthis.attributeNames = this.wiki.filterTiddlers(self.genesisNames,this);\n\t\tthis.attributeValues = this.wiki.filterTiddlers(self.genesisValues,this);\n\t\t$tw.utils.each(this.attributeNames,function(varname,index) {\n\t\t\t$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],varname,self.attributeValues[index] || \"\");\n\t\t});\n\t}\n\t// Apply explicit attributes\n\t$tw.utils.each($tw.utils.getOrderedAttributesFromParseTreeNode(this.parseTreeNode),function(attribute) {\n\t\tvar name = attribute.name;\n\t\tif(name.charAt(0) === \"$\") {\n\t\t\tif(name.charAt(1) === \"$\") {\n\t\t\t\t// Double $$ is changed to a single $\n\t\t\t\tname = name.substr(1);\n\t\t\t} else {\n\t\t\t\t// Single dollar is ignored\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\t$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],$tw.utils.extend({},attribute,{name: name}));\n\t});\n\t// Construct the child widgets\n\tthis.makeChildWidgets(parseTreeNodes);\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nGenesisWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes(),\n\t\tfilterNames = this.getAttribute(\"$names\",\"\"),\n\t\tfilterValues = this.getAttribute(\"$values\",\"\"),\n\t\tattributeNames = this.wiki.filterTiddlers(filterNames,this),\n\t\tattributeValues = this.wiki.filterTiddlers(filterValues,this);\n\tif($tw.utils.count(changedAttributes) > 0 || !$tw.utils.isArrayEqual(this.attributeNames,attributeNames) || !$tw.utils.isArrayEqual(this.attributeValues,attributeValues)) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports.genesis = GenesisWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/image.js":{"title":"$:/core/modules/widgets/image.js","text":"/*\\\ntitle: $:/core/modules/widgets/image.js\ntype: application/javascript\nmodule-type: widget\n\nThe image widget displays an image referenced with an external URI or with a local tiddler title.\n\n```\n<$image src=\"TiddlerTitle\" width=\"320\" height=\"400\" class=\"classnames\">\n```\n\nThe image source can be the title of an existing tiddler or the URL of an external image.\n\nExternal images always generate an HTML `<img>` tag.\n\nTiddlers that have a _canonical_uri field generate an HTML `<img>` tag with the src attribute containing the URI.\n\nTiddlers that contain image data generate an HTML `<img>` tag with the src attribute containing a base64 representation of the image.\n\nTiddlers that contain wikitext could be rendered to a DIV of the usual size of a tiddler, and then transformed to the size requested.\n\nThe width and height attributes are interpreted as a number of pixels, and do not need to include the \"px\" suffix.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar ImageWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nImageWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nImageWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Create element\n\t// Determine what type of image it is\n\tvar tag = \"img\", src = \"\",\n\t\ttiddler = this.wiki.getTiddler(this.imageSource);\n\tif(!tiddler) {\n\t\t// The source isn't the title of a tiddler, so we'll assume it's a URL\n\t\tsrc = this.getVariable(\"tv-get-export-image-link\",{params: [{name: \"src\",value: this.imageSource}],defaultValue: this.imageSource});\n\t} else {\n\t\t// Check if it is an image tiddler\n\t\tif(this.wiki.isImageTiddler(this.imageSource)) {\n\t\t\tvar type = tiddler.fields.type,\n\t\t\t\ttext = tiddler.fields.text,\n\t\t\t\t_canonical_uri = tiddler.fields._canonical_uri,\n\t\t\t\ttypeInfo = $tw.config.contentTypeInfo[type] || {},\n\t\t\t\tdeserializerType = typeInfo.deserializerType || type;\n\t\t\t// If the tiddler has body text then it doesn't need to be lazily loaded\n\t\t\tif(text) {\n\t\t\t\t// Render the appropriate element for the image type by looking up the encoding in the content type info\n\t\t\t\tvar encoding = typeInfo.encoding || \"utf8\";\n\t\t\t\tif (encoding === \"base64\") {\n\t\t\t\t\t// .pdf .png .jpg etc.\n\t\t\t\t\tsrc = \"data:\" + deserializerType + \";base64,\" + text;\n\t\t\t\t\tif (deserializerType === \"application/pdf\") {\n\t\t\t\t\t\ttag = \"embed\";\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// .svg .tid .xml etc.\n\t\t\t\t\tsrc = \"data:\" + deserializerType + \",\" + encodeURIComponent(text);\n\t\t\t\t}\n\t\t\t} else if(_canonical_uri) {\n\t\t\t\tswitch(deserializerType) {\n\t\t\t\t\tcase \"application/pdf\":\n\t\t\t\t\t\ttag = \"embed\";\n\t\t\t\t\t\tsrc = _canonical_uri;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"image/svg+xml\":\n\t\t\t\t\t\tsrc = _canonical_uri;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tsrc = _canonical_uri;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Just trigger loading of the tiddler\n\t\t\t\tthis.wiki.getTiddlerText(this.imageSource);\n\t\t\t}\n\t\t}\n\t}\n\t// Create the element and assign the attributes\n\tvar domNode = this.document.createElement(tag);\n\tdomNode.setAttribute(\"src\",src);\n\tif(this.imageClass) {\n\t\tdomNode.setAttribute(\"class\",this.imageClass);\n\t}\n\tif(this.imageUsemap) {\n\t    \tdomNode.setAttribute(\"usemap\",this.imageUsemap);\n\t}\n\tif(this.imageWidth) {\n\t\tdomNode.setAttribute(\"width\",this.imageWidth);\n\t}\n\tif(this.imageHeight) {\n\t\tdomNode.setAttribute(\"height\",this.imageHeight);\n\t}\n\tif(this.imageTooltip) {\n\t\tdomNode.setAttribute(\"title\",this.imageTooltip);\n\t}\n\tif(this.imageAlt) {\n\t\tdomNode.setAttribute(\"alt\",this.imageAlt);\n\t}\n\tif(this.lazyLoading && tag === \"img\") {\n\t\tdomNode.setAttribute(\"loading\",this.lazyLoading);\n\t}\n\t// Add classes when the image loads or fails\n\t$tw.utils.addClass(domNode,\"tc-image-loading\");\n\tdomNode.addEventListener(\"load\",function() {\n\t\t$tw.utils.removeClass(domNode,\"tc-image-loading\");\n\t\t$tw.utils.addClass(domNode,\"tc-image-loaded\");\n\t},false);\n\tdomNode.addEventListener(\"error\",function() {\n\t\t$tw.utils.removeClass(domNode,\"tc-image-loading\");\n\t\t$tw.utils.addClass(domNode,\"tc-image-error\");\n\t},false);\n\t// Insert element\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.domNodes.push(domNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nImageWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.imageSource = this.getAttribute(\"source\");\n\tthis.imageWidth = this.getAttribute(\"width\");\n\tthis.imageHeight = this.getAttribute(\"height\");\n\tthis.imageClass = this.getAttribute(\"class\");\n    \tthis.imageUsemap = this.getAttribute(\"usemap\");\n\tthis.imageTooltip = this.getAttribute(\"tooltip\");\n\tthis.imageAlt = this.getAttribute(\"alt\");\n\tthis.lazyLoading = this.getAttribute(\"loading\");\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nImageWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.source || changedAttributes.width || changedAttributes.height || changedAttributes[\"class\"] || changedAttributes.usemap || changedAttributes.tooltip || changedTiddlers[this.imageSource]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n};\n\nexports.image = ImageWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/importvariables.js":{"title":"$:/core/modules/widgets/importvariables.js","text":"/*\\\ntitle: $:/core/modules/widgets/importvariables.js\ntype: application/javascript\nmodule-type: widget\n\nImport variable definitions from other tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar ImportVariablesWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nImportVariablesWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nImportVariablesWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nImportVariablesWidget.prototype.execute = function(tiddlerList) {\n\tvar widgetPointer = this;\n\t// Got to flush all the accumulated variables\n\tthis.variables = Object.create(null);\n\tif(this.parentWidget) {\n\t\tObject.setPrototypeOf(this.variables,this.parentWidget.variables);\n\t}\n\t// Get our parameters\n\tthis.filter = this.getAttribute(\"filter\");\n\t// Compute the filter\n\tthis.tiddlerList = tiddlerList || this.wiki.filterTiddlers(this.filter,this);\n\t// Accumulate the <$set> widgets from each tiddler\n\t$tw.utils.each(this.tiddlerList,function(title) {\n\t\tvar parser = widgetPointer.wiki.parseTiddler(title,{parseAsInline:true, configTrimWhiteSpace:false});\n\t\tif(parser) {\n\t\t\tvar parseTreeNode = parser.tree[0];\n\t\t\twhile(parseTreeNode && [\"setvariable\",\"set\",\"parameters\"].indexOf(parseTreeNode.type) !== -1) {\n\t\t\t\tvar node = {\n\t\t\t\t\ttype: \"set\",\n\t\t\t\t\tattributes: parseTreeNode.attributes,\n\t\t\t\t\tparams: parseTreeNode.params,\n\t\t\t\t\tisMacroDefinition: parseTreeNode.isMacroDefinition,\n\t\t\t\t\tisFunctionDefinition: parseTreeNode.isFunctionDefinition,\n\t\t\t\t\tisProcedureDefinition: parseTreeNode.isProcedureDefinition,\n\t\t\t\t\tisWidgetDefinition: parseTreeNode.isWidgetDefinition,\n\t\t\t\t\tconfigTrimWhiteSpace: parseTreeNode.configTrimWhiteSpace\n\t\t\t\t};\n\t\t\t\tif(parseTreeNode.type === \"set\" || parseTreeNode.type === \"setvariable\") {\n\t\t\t\t\tif(parseTreeNode.isMacroDefinition || parseTreeNode.isProcedureDefinition || parseTreeNode.isWidgetDefinition || parseTreeNode.isFunctionDefinition) {\n\t\t\t\t\t\t// Macro definitions can be folded into\n\t\t\t\t\t\t// current widget instead of adding\n\t\t\t\t\t\t// another link to the chain.\n\t\t\t\t\t\tvar widget = widgetPointer.makeChildWidget(node);\n\t\t\t\t\t\twidget.computeAttributes();\n\t\t\t\t\t\twidget.execute();\n\t\t\t\t\t\t// We SHALLOW copy over all variables\n\t\t\t\t\t\t// in widget. We can't use\n\t\t\t\t\t\t// $tw.utils.assign, because that copies\n\t\t\t\t\t\t// up the prototype chain, which we\n\t\t\t\t\t\t// don't want.\n\t\t\t\t\t\t$tw.utils.each(Object.keys(widget.variables), function(key) {\n\t\t\t\t\t\t\twidgetPointer.variables[key] = widget.variables[key];\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\twidgetPointer.children = [widgetPointer.makeChildWidget(node)];\n\t\t\t\t\t\t// No more regenerating children for\n\t\t\t\t\t\t// this widget. If it needs to refresh,\n\t\t\t\t\t\t// it'll do so along with the the whole\n\t\t\t\t\t\t// importvariable tree.\n\t\t\t\t\t\tif (widgetPointer != this) {\n\t\t\t\t\t\t\twidgetPointer.makeChildWidgets = function(){};\n\t\t\t\t\t\t}\n\t\t\t\t\t\twidgetPointer = widgetPointer.children[0];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tparseTreeNode = parseTreeNode.children && parseTreeNode.children[0];\n\t\t\t}\n\t\t} \n\t});\n\n\tif (widgetPointer != this) {\n\t\twidgetPointer.parseTreeNode.children = this.parseTreeNode.children;\n\t} else {\n\t\twidgetPointer.makeChildWidgets();\n\t}\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nImportVariablesWidget.prototype.refresh = function(changedTiddlers) {\n\t// Recompute our attributes and the filter list\n\tvar changedAttributes = this.computeAttributes(),\n\t\ttiddlerList = this.wiki.filterTiddlers(this.getAttribute(\"filter\"),this);\n\t// Refresh if the filter has changed, or the list of tiddlers has changed, or any of the tiddlers in the list has changed\n\tfunction haveListedTiddlersChanged() {\n\t\tvar changed = false;\n\t\ttiddlerList.forEach(function(title) {\n\t\t\tif(changedTiddlers[title]) {\n\t\t\t\tchanged = true;\n\t\t\t}\n\t\t});\n\t\treturn changed;\n\t}\n\tif(changedAttributes.filter || !$tw.utils.isArrayEqual(this.tiddlerList,tiddlerList) || haveListedTiddlersChanged()) {\n\t\t// Compute the filter\n\t\tthis.removeChildDomNodes();\n\t\tthis.execute(tiddlerList);\n\t\tthis.renderChildren(this.parentDomNode,this.findNextSiblingDomNode());\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports.importvariables = ImportVariablesWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/jsontiddler.js":{"title":"$:/core/modules/widgets/jsontiddler.js","text":"/*\\\ntitle: $:/core/modules/widgets/jsontiddler.js\ntype: application/javascript\nmodule-type: widget\n\nRender a tiddler as JSON text\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar JSONTiddlerWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nJSONTiddlerWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nJSONTiddlerWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Collect the fields from the optional base tiddler\n\tvar fields = this.getTiddlerFields();\n\t// Add custom fields specified in attributes starting with $\n\t$tw.utils.each(this.attributes,function(attribute,name) {\n\t\tif(name.charAt(0) === \"$\") {\n\t\t\tfields[name.slice(1)] = attribute;\n\t\t}\n\t});\n\t// JSONify\n\tvar json = JSON.stringify(fields);\n\t// Escape unsafe script characters\n\tif(this.attEscapeUnsafeScriptChars) {\n\t\tjson = json.replace(/</g,\"\\\\u003C\");\n\t}\n\t// Update the DOM\n\tvar textNode = this.document.createTextNode(json);\n\tparent.insertBefore(textNode,nextSibling);\n\tthis.domNodes.push(textNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nJSONTiddlerWidget.prototype.execute = function() {\n\tthis.attTiddler = this.getAttribute(\"tiddler\");\n\tthis.attExclude = this.getAttribute(\"exclude\",\"\");\n\tthis.attEscapeUnsafeScriptChars = this.getAttribute(\"escapeUnsafeScriptChars\",\"no\") === \"yes\";\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nJSONTiddlerWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif($tw.utils.count(changedAttributes) > 0 || (this.attTiddler && changedTiddlers[this.attTiddler])) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n};\n\nJSONTiddlerWidget.prototype.getTiddlerFields = function() {\n\tvar fields = {};\n\tif(this.attTiddler) {\n\t\tvar tiddler = this.wiki.getTiddler(this.attTiddler);\n\t\tif(tiddler) {\n\t\t\tfields = tiddler.getFieldStrings({exclude: this.attExclude.split(\" \")});\n\t\t} else {\n\t\t\tfields = {title: this.attTiddler};\n\t\t}\n\t}\n\treturn fields;\n};\n\nexports.jsontiddler = JSONTiddlerWidget;\n\n})();","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/keyboard.js":{"title":"$:/core/modules/widgets/keyboard.js","text":"/*\\\ntitle: $:/core/modules/widgets/keyboard.js\ntype: application/javascript\nmodule-type: widget\n\nKeyboard shortcut widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar KeyboardWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nKeyboardWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nKeyboardWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Remember parent\n\tthis.parentDomNode = parent;\n\t// Compute attributes and execute state\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar tag = this.parseTreeNode.isBlock ? \"div\" : \"span\";\n\tif(this.tag && $tw.config.htmlUnsafeElements.indexOf(this.tag) === -1) {\n\t\ttag = this.tag;\n\t}\n\t// Create element\n\tvar domNode = this.document.createElement(tag);\n\t// Assign classes\n\tthis.domNode = domNode;\n\tthis.assignDomNodeClasses();\n\t// Add a keyboard event handler\n\t$tw.utils.addEventListeners(domNode,[\n\t\t{name: \"keydown\", handlerObject: this, handlerMethod: \"handleChangeEvent\"}\n\t]);\n\t// Insert element\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n};\n\nKeyboardWidget.prototype.handleChangeEvent = function(event) {\n\tif ($tw.keyboardManager.handleKeydownEvent(event, {onlyPriority: true})) {\n\t\treturn true;\n\t}\n\n\tvar keyInfo = $tw.keyboardManager.getMatchingKeyDescriptor(event,this.keyInfoArray);\n\tif(keyInfo) {\n\t\tvar handled = this.invokeActions(this,event);\n\t\tif(this.actions) {\n\t\t\tvar variables = {\n\t\t\t\t\t\"event-key\": event.key,\n\t\t\t\t\t\"event-code\": event.code,\n\t\t\t\t\t\"modifier\": $tw.keyboardManager.getEventModifierKeyDescriptor(event)\n\t\t\t\t};\n\t\t\tif(keyInfo.keyDescriptor) {\n\t\t\t\tvariables[\"event-key-descriptor\"] = keyInfo.keyDescriptor;\n\t\t\t}\n\t\t\tthis.invokeActionString(this.actions,this,event,variables);\n\t\t}\n\t\tthis.dispatchMessage(event);\n\t\tif(handled || this.actions || this.message) {\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\t}\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nKeyboardWidget.prototype.dispatchMessage = function(event) {\n\tthis.dispatchEvent({type: this.message, param: this.param, tiddlerTitle: this.getVariable(\"currentTiddler\")});\n};\n\n/*\nCompute the internal state of the widget\n*/\nKeyboardWidget.prototype.execute = function() {\n\tvar self = this;\n\t// Get attributes\n\tthis.actions = this.getAttribute(\"actions\",\"\");\n\tthis.message = this.getAttribute(\"message\",\"\");\n\tthis.param = this.getAttribute(\"param\",\"\");\n\tthis.key = this.getAttribute(\"key\",\"\");\n\tthis.tag = this.getAttribute(\"tag\",\"\");\n\tif($tw.keyboardManager) {\n\t\tthis.keyInfoArray = $tw.keyboardManager.parseKeyDescriptors(this.key);\n\t\tif(this.key.substr(0,2) === \"((\" && this.key.substr(-2,2) === \"))\") {\n\t\t\tthis.shortcutTiddlers = [];\n\t\t\tvar name = this.key.substring(2,this.key.length -2);\n\t\t\t$tw.utils.each($tw.keyboardManager.lookupNames,function(platformDescriptor) {\n\t\t\t\tself.shortcutTiddlers.push(\"$:/config/\" + platformDescriptor + \"/\" + name);\n\t\t\t});\n\t\t}\t\n\t}\n\t// Make child widgets\n\tthis.makeChildWidgets();\n};\n\nKeyboardWidget.prototype.assignDomNodeClasses = function() {\n\tvar classes = this.getAttribute(\"class\",\"\").split(\" \");\n\tclasses.push(\"tc-keyboard\");\n\tthis.domNode.className = classes.join(\" \");\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nKeyboardWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.message || changedAttributes.param || changedAttributes.key || changedAttributes.tag) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else if(changedAttributes[\"class\"]) {\n\t\tthis.assignDomNodeClasses();\n\t}\n\t// Update the keyInfoArray if one of its shortcut-config-tiddlers has changed\n\tif(this.shortcutTiddlers && $tw.utils.hopArray(changedTiddlers,this.shortcutTiddlers) && $tw.keyboardManager) {\n\t\tthis.keyInfoArray = $tw.keyboardManager.parseKeyDescriptors(this.key);\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.keyboard = KeyboardWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/let.js":{"title":"$:/core/modules/widgets/let.js","text":"/*\\\ntitle: $:/core/modules/widgets/let.js\ntype: application/javascript\nmodule-type: widget\n\nThis widget allows defining multiple variables at once, while allowing\nthe later variables to depend upon the earlier ones.\n\n```\n\\define helloworld() Hello world!\n<$let currentTiddler=\"target\" value={{!!value}} currentTiddler=\"different\">\n  {{!!value}} will be different from <<value>>\n</$let>\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar LetWidget = function(parseTreeNode,options) {\n\t// Initialise\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nLetWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nLetWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\nLetWidget.prototype.computeAttributes = function() {\n\t// Before computing attributes, we must make clear that none of the\n\t// existing attributes are staged for lookup, even on a refresh\n\tvar changedAttributes = {},\n\t\tself = this;\n\tthis.currentValueFor = Object.create(null);\n\t$tw.utils.each($tw.utils.getOrderedAttributesFromParseTreeNode(this.parseTreeNode),function(attribute) {\n\t\tvar value = self.computeAttribute(attribute),\n\t\t\tname = attribute.name;\n\t\t// Now that it's prepped, we're allowed to look this variable up\n\t\t// when defining later variables\n\t\tif(value !== undefined) {\n\t\t\tself.currentValueFor[name] = value;\n\t\t}\n\t});\n\t// Run through again, setting variables and looking for differences\n\t$tw.utils.each(this.currentValueFor,function(value,name) {\n\t\tif (self.attributes[name] !== value) {\n\t\t\tself.attributes[name] = value;\n\t\t\tself.setVariable(name,value);\n\t\t\tchangedAttributes[name] = true;\n\t\t}\n\t});\n\treturn changedAttributes;\n};\n\nLetWidget.prototype.getVariableInfo = function(name,options) {\n\t// Special handling: If this variable exists in this very $let, we can\n\t// use it, but only if it's been staged.\n\tif ($tw.utils.hop(this.currentValueFor,name)) {\n\t\treturn {\n\t\t\ttext: this.currentValueFor[name]\n\t\t};\n\t}\n\treturn Widget.prototype.getVariableInfo.call(this,name,options);\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nLetWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif($tw.utils.count(changedAttributes) > 0) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports[\"let\"] = LetWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/link.js":{"title":"$:/core/modules/widgets/link.js","text":"/*\\\ntitle: $:/core/modules/widgets/link.js\ntype: application/javascript\nmodule-type: widget\n\nLink widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar LinkWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nLinkWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nLinkWidget.prototype.render = function(parent,nextSibling) {\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\t// Get the value of the tv-wikilinks configuration macro\n\tvar wikiLinksMacro = this.getVariable(\"tv-wikilinks\"),\n\t\tuseWikiLinks = wikiLinksMacro ? (wikiLinksMacro.trim() !== \"no\") : true,\n\t\tmissingLinksEnabled = !(this.hideMissingLinks && this.isMissing && !this.isShadow);\n\t// Render the link if required\n\tif(useWikiLinks && missingLinksEnabled) {\n\t\tthis.renderLink(parent,nextSibling);\n\t} else {\n\t\t// Just insert the link text\n\t\tvar domNode = this.document.createElement(\"span\");\n\t\t// Assign data- attributes\n\t\tthis.assignAttributes(domNode,{\n\t\t\tsourcePrefix: \"data-\",\n\t\t\tdestPrefix: \"data-\"\n\t\t});\n\t\tparent.insertBefore(domNode,nextSibling);\n\t\tthis.renderChildren(domNode,null);\n\t\tthis.domNodes.push(domNode);\n\t}\n};\n\n/*\nRender this widget into the DOM\n*/\nLinkWidget.prototype.renderLink = function(parent,nextSibling) {\n\tvar self = this;\n\t// Sanitise the specified tag\n\tvar tag = this.linkTag;\n\tif($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {\n\t\ttag = \"a\";\n\t}\n\t// Create our element\n\tvar namespace = this.getVariable(\"namespace\",{defaultValue: \"http://www.w3.org/1999/xhtml\"}),\n\t\tdomNode = this.document.createElementNS(namespace,tag);\n\t// Assign classes\n\tvar classes = [];\n\tif(this.overrideClasses === undefined) {\n\t\tclasses.push(\"tc-tiddlylink\");\n\t\tif(this.isShadow) {\n\t\t\tclasses.push(\"tc-tiddlylink-shadow\");\n\t\t}\n\t\tif(this.isMissing && !this.isShadow) {\n\t\t\tclasses.push(\"tc-tiddlylink-missing\");\n\t\t} else {\n\t\t\tif(!this.isMissing) {\n\t\t\t\tclasses.push(\"tc-tiddlylink-resolves\");\n\t\t\t}\n\t\t}\n\t\tif(this.linkClasses) {\n\t\t\tclasses.push(this.linkClasses);\n\t\t}\n\t} else if(this.overrideClasses !== \"\") {\n\t\tclasses.push(this.overrideClasses)\n\t}\n\tif(classes.length > 0) {\n\t\tdomNode.setAttribute(\"class\",classes.join(\" \"));\n\t}\n\t// Set an href\n\tvar wikilinkTransformFilter = this.getVariable(\"tv-filter-export-link\"),\n\t\twikiLinkText;\n\tif(wikilinkTransformFilter) {\n\t\t// Use the filter to construct the href\n\t\twikiLinkText = this.wiki.filterTiddlers(wikilinkTransformFilter,this,function(iterator) {\n\t\t\titerator(self.wiki.getTiddler(self.to),self.to)\n\t\t})[0];\n\t} else {\n\t\t// Expand the tv-wikilink-template variable to construct the href\n\t\tvar wikiLinkTemplateMacro = this.getVariable(\"tv-wikilink-template\"),\n\t\t\twikiLinkTemplate = wikiLinkTemplateMacro ? wikiLinkTemplateMacro.trim() : \"#$uri_encoded$\";\n\t\twikiLinkText = $tw.utils.replaceString(wikiLinkTemplate,\"$uri_encoded$\",$tw.utils.encodeURIComponentExtended(this.to));\n\t\twikiLinkText = $tw.utils.replaceString(wikiLinkText,\"$uri_doubleencoded$\",$tw.utils.encodeURIComponentExtended($tw.utils.encodeURIComponentExtended(this.to)));\n\t}\n\t// Override with the value of tv-get-export-link if defined\n\twikiLinkText = this.getVariable(\"tv-get-export-link\",{params: [{name: \"to\",value: this.to}],defaultValue: wikiLinkText});\n\tif(tag === \"a\") {\n\t\tvar namespaceHref = (namespace === \"http://www.w3.org/2000/svg\") ? \"http://www.w3.org/1999/xlink\" : undefined;\n\t\tdomNode.setAttributeNS(namespaceHref,\"href\",wikiLinkText);\n\t}\n\t// Set the tabindex\n\tif(this.tabIndex) {\n\t\tdomNode.setAttribute(\"tabindex\",this.tabIndex);\n\t}\n\t// Set the tooltip\n\t// HACK: Performance issues with re-parsing the tooltip prevent us defaulting the tooltip to \"<$transclude field='tooltip'><$transclude field='title'/></$transclude>\"\n\tvar tooltipWikiText = this.tooltip || this.getVariable(\"tv-wikilink-tooltip\");\n\tif(tooltipWikiText) {\n\t\tvar tooltipText = this.wiki.renderText(\"text/plain\",\"text/vnd.tiddlywiki\",tooltipWikiText,{\n\t\t\t\tparseAsInline: true,\n\t\t\t\tvariables: {\n\t\t\t\t\tcurrentTiddler: this.to\n\t\t\t\t},\n\t\t\t\tparentWidget: this\n\t\t\t});\n\t\tdomNode.setAttribute(\"title\",tooltipText);\n\t}\n\tif(this[\"aria-label\"]) {\n\t\tdomNode.setAttribute(\"aria-label\",this[\"aria-label\"]);\n\t}\n\t// Add a click event handler\n\t$tw.utils.addEventListeners(domNode,[\n\t\t{name: \"click\", handlerObject: this, handlerMethod: \"handleClickEvent\"},\n\t]);\n\t// Make the link draggable if required\n\tif(this.draggable === \"yes\") {\n\t\t$tw.utils.makeDraggable({\n\t\t\tdomNode: domNode,\n\t\t\tdragTiddlerFn: function() {return self.to;},\n\t\t\twidget: this\n\t\t});\n\t}\n\t// Assign data- attributes\n\tthis.assignAttributes(domNode,{\n\t\tsourcePrefix: \"data-\",\n\t\tdestPrefix: \"data-\"\n\t});\n\t// Insert the link into the DOM and render any children\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n};\n\nLinkWidget.prototype.handleClickEvent = function(event) {\n\t// Send the click on its way as a navigate event\n\tvar bounds = this.domNodes[0].getBoundingClientRect();\n\tthis.dispatchEvent({\n\t\ttype: \"tm-navigate\",\n\t\tnavigateTo: this.to,\n\t\tnavigateFromTitle: this.getVariable(\"storyTiddler\"),\n\t\tnavigateFromNode: this,\n\t\tnavigateFromClientRect: { top: bounds.top, left: bounds.left, width: bounds.width, right: bounds.right, bottom: bounds.bottom, height: bounds.height\n\t\t},\n\t\tnavigateFromClientTop: bounds.top,\n\t\tnavigateFromClientLeft: bounds.left,\n\t\tnavigateFromClientWidth: bounds.width,\n\t\tnavigateFromClientRight: bounds.right,\n\t\tnavigateFromClientBottom: bounds.bottom,\n\t\tnavigateFromClientHeight: bounds.height,\n\t\tnavigateSuppressNavigation: event.metaKey || event.ctrlKey || (event.button === 1),\n\t\tmetaKey: event.metaKey,\n\t\tctrlKey: event.ctrlKey,\n\t\taltKey: event.altKey,\n\t\tshiftKey: event.shiftKey,\n\t\tevent: event\n\t});\n\tif(this.domNodes[0].hasAttribute(\"href\")) {\n\t\tevent.preventDefault();\n\t}\n\tevent.stopPropagation();\n\treturn false;\n};\n\n/*\nCompute the internal state of the widget\n*/\nLinkWidget.prototype.execute = function() {\n\t// Pick up our attributes\n\tthis.to = this.getAttribute(\"to\",this.getVariable(\"currentTiddler\"));\n\tthis.tooltip = this.getAttribute(\"tooltip\");\n\tthis[\"aria-label\"] = this.getAttribute(\"aria-label\");\n\tthis.linkClasses = this.getAttribute(\"class\");\n\tthis.overrideClasses = this.getAttribute(\"overrideClass\");\n\tthis.tabIndex = this.getAttribute(\"tabindex\");\n\tthis.draggable = this.getAttribute(\"draggable\",\"yes\");\n\tthis.linkTag = this.getAttribute(\"tag\",\"a\");\n\t// Determine the link characteristics\n\tthis.isMissing = !this.wiki.tiddlerExists(this.to);\n\tthis.isShadow = this.wiki.isShadowTiddler(this.to);\n\tthis.hideMissingLinks = (this.getVariable(\"tv-show-missing-links\") || \"yes\") === \"no\";\n\t// Make the child widgets\n\tvar templateTree;\n\tif(this.parseTreeNode.children && this.parseTreeNode.children.length > 0) {\n\t\ttemplateTree = this.parseTreeNode.children;\n\t} else {\n\t\t// Default template is a link to the title\n\t\ttemplateTree = [{type: \"text\", text: this.to}];\n\t}\n\tthis.makeChildWidgets(templateTree);\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nLinkWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif($tw.utils.count(changedAttributes) > 0 || changedTiddlers[this.to]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.link = LinkWidget;\n\n})();\n\t","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/linkcatcher.js":{"title":"$:/core/modules/widgets/linkcatcher.js","text":"/*\\\ntitle: $:/core/modules/widgets/linkcatcher.js\ntype: application/javascript\nmodule-type: widget\n\nLinkcatcher widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar LinkCatcherWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nLinkCatcherWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nLinkCatcherWidget.prototype.render = function(parent,nextSibling) {\n\tthis.addEventListeners([\n\t\t{type: \"tm-navigate\", handler: \"handleNavigateEvent\"}\n\t]);\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nLinkCatcherWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.catchTo = this.getAttribute(\"to\");\n\tthis.catchMessage = this.getAttribute(\"message\");\n\tthis.catchSet = this.getAttribute(\"set\");\n\tthis.catchSetTo = this.getAttribute(\"setTo\");\n\tthis.catchActions = this.getAttribute(\"actions\");\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n\t// When executing actions we avoid trapping navigate events, so that we don't trigger ourselves recursively\n\tthis.executingActions = false;\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nLinkCatcherWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.to || changedAttributes.message || changedAttributes.set || changedAttributes.setTo) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\n/*\nHandle a tm-navigate event\n*/\nLinkCatcherWidget.prototype.handleNavigateEvent = function(event) {\n\tif(!this.executingActions) {\n\t\t// Execute the actions\n\t\tif(this.catchTo) {\n\t\t\tthis.wiki.setTextReference(this.catchTo,event.navigateTo,this.getVariable(\"currentTiddler\"));\n\t\t}\n\t\tif(this.catchMessage && this.parentWidget) {\n\t\t\tthis.parentWidget.dispatchEvent({\n\t\t\t\ttype: this.catchMessage,\n\t\t\t\tparam: event.navigateTo,\n\t\t\t\tnavigateTo: event.navigateTo\n\t\t\t});\n\t\t}\n\t\tif(this.catchSet) {\n\t\t\tvar tiddler = this.wiki.getTiddler(this.catchSet);\n\t\t\tthis.wiki.addTiddler(new $tw.Tiddler(tiddler,{title: this.catchSet, text: this.catchSetTo}));\n\t\t}\n\t\tif(this.catchActions) {\n\t\t\tthis.executingActions = true;\n\t\t\tvar modifierKey = $tw.keyboardManager.getEventModifierKeyDescriptor(event);\n\t\t\tthis.invokeActionString(this.catchActions,this,event,{navigateTo: event.navigateTo, modifier: modifierKey});\n\t\t\tthis.executingActions = false;\n\t\t}\n\t} else {\n\t\t\t// This is a navigate event generated by the actions of this linkcatcher,\n\t\t\t// so we don't trap it again, but just pass it to the parent\n\t\t\tthis.parentWidget.dispatchEvent(event);\n\t}\n\treturn false;\n};\n\nexports.linkcatcher = LinkCatcherWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/list.js":{"title":"$:/core/modules/widgets/list.js","text":"/*\\\ntitle: $:/core/modules/widgets/list.js\ntype: application/javascript\nmodule-type: widget\n\nList and list item widgets\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\n/*\nThe list widget creates list element sub-widgets that reach back into the list widget for their configuration\n*/\n\nvar ListWidget = function(parseTreeNode,options) {\n\t// Main initialisation inherited from widget.js\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nListWidget.prototype = new Widget();\n\nListWidget.prototype.initialise = function(parseTreeNode,options) {\n\t// Bail if parseTreeNode is undefined, meaning that the ListWidget constructor was called without any arguments so that it can be subclassed\n\tif(parseTreeNode === undefined) {\n\t\treturn;\n\t}\n\t// First call parent constructor to set everything else up\n\tWidget.prototype.initialise.call(this,parseTreeNode,options);\n\t// Now look for <$list-template> and <$list-empty> widgets as immediate child widgets\n\t// This is safe to do during initialization because parse trees never change after creation\n\tthis.findExplicitTemplates();\n}\n\n/*\nRender this widget into the DOM\n*/\nListWidget.prototype.render = function(parent,nextSibling) {\n\t// Initialise the storyviews if they've not been done already\n\tif(!this.storyViews) {\n\t\tListWidget.prototype.storyViews = {};\n\t\t$tw.modules.applyMethods(\"storyview\",this.storyViews);\n\t}\n\tthis.parentDomNode = parent;\n\tvar changedAttributes = this.computeAttributes();\n\tthis.execute(changedAttributes);\n\tthis.renderChildren(parent,nextSibling);\n\t// Construct the storyview\n\tvar StoryView = this.storyViews[this.storyViewName];\n\tif(this.storyViewName && !StoryView) {\n\t\tStoryView = this.storyViews[\"classic\"];\n\t}\n\tif(StoryView && !this.document.isTiddlyWikiFakeDom) {\n\t\tthis.storyview = new StoryView(this);\n\t} else {\n\t\tthis.storyview = null;\n\t}\n\tif(this.storyview && this.storyview.renderEnd) {\n\t\tthis.storyview.renderEnd();\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nListWidget.prototype.execute = function(changedAttributes) {\n\tvar self = this;\n\t// Get our attributes\n\tthis.template = this.getAttribute(\"template\");\n\tthis.editTemplate = this.getAttribute(\"editTemplate\");\n\tthis.variableName = this.getAttribute(\"variable\",\"currentTiddler\");\n\tthis.counterName = this.getAttribute(\"counter\");\n\tthis.storyViewName = this.getAttribute(\"storyview\");\n\tthis.historyTitle = this.getAttribute(\"history\");\n\t// Create join template only if needed\n\tif(this.join === undefined || (changedAttributes && changedAttributes.join)) {\n\t\tthis.join = this.makeJoinTemplate();\n\t}\n\t// Compose the list elements\n\tthis.list = this.getTiddlerList();\n\tvar members = [],\n\t\tself = this;\n\t// Check for an empty list\n\tif(this.list.length === 0) {\n\t\tmembers = this.getEmptyMessage();\n\t} else {\n\t\t$tw.utils.each(this.list,function(title,index) {\n\t\t\tmembers.push(self.makeItemTemplate(title,index));\n\t\t});\n\t}\n\t// Construct the child widgets\n\tthis.makeChildWidgets(members);\n\t// Clear the last history\n\tthis.history = [];\n};\n\nListWidget.prototype.findExplicitTemplates = function() {\n\tvar self = this;\n\tthis.explicitListTemplate = null;\n\tthis.explicitEmptyTemplate = null;\n\tthis.explicitJoinTemplate = null;\n\tthis.hasTemplateInBody = false;\n\tvar searchChildren = function(childNodes) {\n\t\tvar foundInlineTemplate = false;\n\t\t$tw.utils.each(childNodes,function(node) {\n\t\t\tif(node.type === \"list-template\") {\n\t\t\t\tself.explicitListTemplate = node.children;\n\t\t\t} else if(node.type === \"list-empty\") {\n\t\t\t\tself.explicitEmptyTemplate = node.children;\n\t\t\t} else if(node.type === \"list-join\") {\n\t\t\t\tself.explicitJoinTemplate = node.children;\n\t\t\t} else if(node.type === \"element\" && node.tag === \"p\") {\n\t\t\t\tsearchChildren(node.children);\n\t\t\t\tfoundInlineTemplate = true;\n\t\t\t} else {\n\t\t\t\tfoundInlineTemplate = true;\n\t\t\t}\n\t\t});\n\t\treturn foundInlineTemplate;\n\t};\n\tthis.hasTemplateInBody = searchChildren(this.parseTreeNode.children);\n}\n\nListWidget.prototype.getTiddlerList = function() {\n\tvar limit = $tw.utils.getInt(this.getAttribute(\"limit\",\"\"),undefined);\n\tvar defaultFilter = \"[!is[system]sort[title]]\";\n\tvar results = this.wiki.filterTiddlers(this.getAttribute(\"filter\",defaultFilter),this);\n\tif(limit !== undefined) {\n\t\tif(limit >= 0) {\n\t\t\tresults = results.slice(0,limit);\n\t\t} else {\n\t\t\tresults = results.slice(limit);\n\t\t}\n\t}\n\treturn results;\n};\n\nListWidget.prototype.getEmptyMessage = function() {\n\tvar parser,\n\t\temptyMessage = this.getAttribute(\"emptyMessage\");\n\t// If emptyMessage attribute is not present or empty then look for an explicit empty template\n\tif(!emptyMessage) {\n\t\tif(this.explicitEmptyTemplate) {\n\t\t\treturn this.explicitEmptyTemplate;\n\t\t} else {\n\t\t\treturn [];\n\t\t}\n\t}\n\tparser = this.wiki.parseText(\"text/vnd.tiddlywiki\",emptyMessage,{parseAsInline: true});\n\tif(parser) {\n\t\treturn parser.tree;\n\t} else {\n\t\treturn [];\n\t}\n};\n\n/*\nCompose the template for a join between list items\n*/\nListWidget.prototype.makeJoinTemplate = function() {\n\tvar parser,\n\t\tjoin = this.getAttribute(\"join\",\"\");\n\tif(join) {\n\t\tparser = this.wiki.parseText(\"text/vnd.tiddlywiki\",join,{parseAsInline:true})\n\t\tif(parser) {\n\t\t\treturn parser.tree;\n\t\t} else {\n\t\t\treturn [];\n\t\t}\n\t} else {\n\t\treturn this.explicitJoinTemplate; // May be null, and that's fine\n\t}\n};\n\n/*\nCompose the template for a list item\n*/\nListWidget.prototype.makeItemTemplate = function(title,index) {\n\t// Check if the tiddler is a draft\n\tvar tiddler = this.wiki.getTiddler(title),\n\t\tisDraft = tiddler && tiddler.hasField(\"draft.of\"),\n\t\ttemplate = this.template,\n\t\tjoin = this.join,\n\t\ttemplateTree;\n\tif(isDraft && this.editTemplate) {\n\t\ttemplate = this.editTemplate;\n\t}\n\t// Compose the transclusion of the template\n\tif(template) {\n\t\ttemplateTree = [{type: \"transclude\", attributes: {tiddler: {type: \"string\", value: template}}}];\n\t} else {\n\t\t// Check for child nodes of the list widget\n\t\tif(this.parseTreeNode.children && this.parseTreeNode.children.length > 0) {\n\t\t\t// Check for a <$list-item> widget\n\t\t\tif(this.explicitListTemplate) {\n\t\t\t\ttemplateTree = this.explicitListTemplate;\n\t\t\t} else if(this.hasTemplateInBody) {\n\t\t\t\ttemplateTree = this.parseTreeNode.children;\n\t\t\t}\n\t\t}\n\t\tif(!templateTree || templateTree.length === 0) {\n\t\t\t// Default template is a link to the title\n\t\t\ttemplateTree = [{type: \"element\", tag: this.parseTreeNode.isBlock ? \"div\" : \"span\", children: [{type: \"link\", attributes: {to: {type: \"string\", value: title}}, children: [\n\t\t\t\t{type: \"text\", text: title}\n\t\t\t]}]}];\n\t\t}\n\t}\n\t// Return the list item\n\tvar parseTreeNode = {type: \"listitem\", itemTitle: title, variableName: this.variableName, children: templateTree, join: join};\n\tparseTreeNode.isLast = index === this.list.length - 1;\n\tif(this.counterName) {\n\t\tparseTreeNode.counter = (index + 1).toString();\n\t\tparseTreeNode.counterName = this.counterName;\n\t\tparseTreeNode.isFirst = index === 0;\n\t}\n\treturn parseTreeNode;\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nListWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes(),\n\t\tresult;\n\t// Call the storyview\n\tif(this.storyview && this.storyview.refreshStart) {\n\t\tthis.storyview.refreshStart(changedTiddlers,changedAttributes);\n\t}\n\t// Completely refresh if any of our attributes have changed\n\tif(changedAttributes.filter || changedAttributes.variable || changedAttributes.counter || changedAttributes.template || changedAttributes.editTemplate || changedAttributes.join || changedAttributes.emptyMessage || changedAttributes.storyview || changedAttributes.history) {\n\t\tthis.refreshSelf();\n\t\tresult = true;\n\t} else {\n\t\t// Handle any changes to the list\n\t\tresult = this.handleListChanges(changedTiddlers);\n\t\t// Handle any changes to the history stack\n\t\tif(this.historyTitle && changedTiddlers[this.historyTitle]) {\n\t\t\tthis.handleHistoryChanges();\n\t\t}\n\t}\n\t// Call the storyview\n\tif(this.storyview && this.storyview.refreshEnd) {\n\t\tthis.storyview.refreshEnd(changedTiddlers,changedAttributes);\n\t}\n\treturn result;\n};\n\n/*\nHandle any changes to the history list\n*/\nListWidget.prototype.handleHistoryChanges = function() {\n\t// Get the history data\n\tvar newHistory = this.wiki.getTiddlerDataCached(this.historyTitle,[]);\n\t// Ignore any entries of the history that match the previous history\n\tvar entry = 0;\n\twhile(entry < newHistory.length && entry < this.history.length && newHistory[entry].title === this.history[entry].title) {\n\t\tentry++;\n\t}\n\t// Navigate forwards to each of the new tiddlers\n\twhile(entry < newHistory.length) {\n\t\tif(this.storyview && this.storyview.navigateTo) {\n\t\t\tthis.storyview.navigateTo(newHistory[entry]);\n\t\t}\n\t\tentry++;\n\t}\n\t// Update the history\n\tthis.history = newHistory;\n};\n\n/*\nProcess any changes to the list\n*/\nListWidget.prototype.handleListChanges = function(changedTiddlers) {\n\t// Get the new list\n\tvar prevList = this.list;\n\tthis.list = this.getTiddlerList();\n\t// Check for an empty list\n\tif(this.list.length === 0) {\n\t\t// Check if it was empty before\n\t\tif(prevList.length === 0) {\n\t\t\t// If so, just refresh the empty message\n\t\t\treturn this.refreshChildren(changedTiddlers);\n\t\t} else {\n\t\t\t// Replace the previous content with the empty message\n\t\t\tfor(t=this.children.length-1; t>=0; t--) {\n\t\t\t\tthis.removeListItem(t);\n\t\t\t}\n\t\t\tvar nextSibling = this.findNextSiblingDomNode();\n\t\t\tthis.makeChildWidgets(this.getEmptyMessage());\n\t\t\tthis.renderChildren(this.parentDomNode,nextSibling);\n\t\t\treturn true;\n\t\t}\n\t} else {\n\t\t// If the list was empty then we need to remove the empty message\n\t\tif(prevList.length === 0) {\n\t\t\tthis.removeChildDomNodes();\n\t\t\tthis.children = [];\n\t\t}\n\t\t// If we are providing an counter variable then we must refresh the items, otherwise we can rearrange them\n\t\tvar hasRefreshed = false,t;\n\t\tif(this.counterName) {\n\t\t\tvar mustRefreshOldLast = false;\n\t\t\tvar oldLength = this.children.length;\n\t\t\t// Cycle through the list and remove and re-insert the first item that has changed, and all the remaining items\n\t\t\tfor(t=0; t<this.list.length; t++) {\n\t\t\t\tif(hasRefreshed || !this.children[t] || this.children[t].parseTreeNode.itemTitle !== this.list[t]) {\n\t\t\t\t\tif(this.children[t]) {\n\t\t\t\t\t\tthis.removeListItem(t);\n\t\t\t\t\t}\n\t\t\t\t\tthis.insertListItem(t,this.list[t]);\n\t\t\t\t\tif(!hasRefreshed && t === oldLength) {\n\t\t\t\t\t\tmustRefreshOldLast = true;\n\t\t\t\t\t}\n\t\t\t\t\thasRefreshed = true;\n\t\t\t\t} else {\n\t\t\t\t\t// Refresh the item we're reusing\n\t\t\t\t\tvar refreshed = this.children[t].refresh(changedTiddlers);\n\t\t\t\t\thasRefreshed = hasRefreshed || refreshed;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// If items were inserted then we must recreate the item that used to be at the last position as it is no longer last\n\t\t\tif(mustRefreshOldLast && oldLength > 0) {\n\t\t\t\tvar oldLastIdx = oldLength-1;\n\t\t\t\tthis.removeListItem(oldLastIdx);\n\t\t\t\tthis.insertListItem(oldLastIdx,this.list[oldLastIdx]);\n\t\t\t}\n\t\t\t// If there are items to remove and we have not refreshed then recreate the item that will now be at the last position\n\t\t\tif(!hasRefreshed && this.children.length > this.list.length) {\n\t\t\t\tthis.removeListItem(this.list.length-1);\n\t\t\t\tthis.insertListItem(this.list.length-1,this.list[this.list.length-1]);\n\t\t\t}\n\t\t} else {\n\t\t\t// Cycle through the list, inserting and removing list items as needed\n\t\t\tvar mustRecreateLastItem = false;\n\t\t\tif(this.join && this.join.length) {\n\t\t\t\tif(this.children.length !== this.list.length) {\n\t\t\t\t\t\tmustRecreateLastItem = true;\n\t\t\t\t} else if(prevList[prevList.length-1] !== this.list[this.list.length-1]) {\n\t\t\t\t\t\tmustRecreateLastItem = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar isLast = false, wasLast = false;\n\t\t\tfor(t=0; t<this.list.length; t++) {\n\t\t\t\tisLast = t === this.list.length-1;\n\t\t\t\tvar index = this.findListItem(t,this.list[t]);\n\t\t\t\twasLast = index === this.children.length-1;\n\t\t\t\tif(wasLast && (index !== t || this.children.length !== this.list.length)) {\n\t\t\t\t\tmustRecreateLastItem = !!(this.join && this.join.length);\n\t\t\t\t}\n\t\t\t\tif(index === undefined) {\n\t\t\t\t\t// The list item must be inserted\n\t\t\t\t\tif(isLast && mustRecreateLastItem && t>0) {\n\t\t\t\t\t\t// First re-create previosly-last item that will no longer be last\n\t\t\t\t\t\tthis.removeListItem(t-1);\n\t\t\t\t\t\tthis.insertListItem(t-1,this.list[t-1]);\n\t\t\t\t\t}\n\t\t\t\t\tthis.insertListItem(t,this.list[t]);\n\t\t\t\t\thasRefreshed = true;\n\t\t\t\t} else {\n\t\t\t\t\t// There are intervening list items that must be removed\n\t\t\t\t\tfor(var n=index-1; n>=t; n--) {\n\t\t\t\t\t\tthis.removeListItem(n);\n\t\t\t\t\t\thasRefreshed = true;\n\t\t\t\t\t}\n\t\t\t\t\t// Refresh the item we're reusing, or recreate if necessary\n\t\t\t\t\tif(mustRecreateLastItem && (isLast || wasLast)) {\n\t\t\t\t\t\tthis.removeListItem(t);\n\t\t\t\t\t\tthis.insertListItem(t,this.list[t]);\n\t\t\t\t\t\thasRefreshed = true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvar refreshed = this.children[t].refresh(changedTiddlers);\n\t\t\t\t\t\thasRefreshed = hasRefreshed || refreshed;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Remove any left over items\n\t\tfor(t=this.children.length-1; t>=this.list.length; t--) {\n\t\t\tthis.removeListItem(t);\n\t\t\thasRefreshed = true;\n\t\t}\n\t\treturn hasRefreshed;\n\t}\n};\n\n/*\nFind the list item with a given title, starting from a specified position\n*/\nListWidget.prototype.findListItem = function(startIndex,title) {\n\twhile(startIndex < this.children.length) {\n\t\tif(this.children[startIndex].parseTreeNode.itemTitle === title) {\n\t\t\treturn startIndex;\n\t\t}\n\t\tstartIndex++;\n\t}\n\treturn undefined;\n};\n\n/*\nInsert a new list item at the specified index\n*/\nListWidget.prototype.insertListItem = function(index,title) {\n\t// Create, insert and render the new child widgets\n\tvar widget = this.makeChildWidget(this.makeItemTemplate(title,index));\n\twidget.parentDomNode = this.parentDomNode; // Hack to enable findNextSiblingDomNode() to work\n\tthis.children.splice(index,0,widget);\n\tvar nextSibling = widget.findNextSiblingDomNode();\n\twidget.render(this.parentDomNode,nextSibling);\n\t// Animate the insertion if required\n\tif(this.storyview && this.storyview.insert) {\n\t\tthis.storyview.insert(widget);\n\t}\n\treturn true;\n};\n\n/*\nRemove the specified list item\n*/\nListWidget.prototype.removeListItem = function(index) {\n\tvar widget = this.children[index];\n\t// Animate the removal if required\n\tif(this.storyview && this.storyview.remove) {\n\t\tthis.storyview.remove(widget);\n\t} else {\n\t\twidget.removeChildDomNodes();\n\t}\n\t// Remove the child widget\n\tthis.children.splice(index,1);\n};\n\nexports.list = ListWidget;\n\nvar ListItemWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nListItemWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nListItemWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nListItemWidget.prototype.execute = function() {\n\t// Set the current list item title\n\tthis.setVariable(this.parseTreeNode.variableName,this.parseTreeNode.itemTitle);\n\tif(this.parseTreeNode.counterName) {\n\t\tthis.setVariable(this.parseTreeNode.counterName,this.parseTreeNode.counter);\n\t\tthis.setVariable(this.parseTreeNode.counterName + \"-first\",this.parseTreeNode.isFirst ? \"yes\" : \"no\");\n\t\tthis.setVariable(this.parseTreeNode.counterName + \"-last\",this.parseTreeNode.isLast ? \"yes\" : \"no\");\n\t}\n\t// Add join if needed\n\tvar children = this.parseTreeNode.children,\n\t\tjoin = this.parseTreeNode.join;\n\tif(join && join.length && !this.parseTreeNode.isLast) {\n\t\tchildren = children.slice(0);\n\t\t$tw.utils.each(join,function(joinNode) {\n\t\t\tchildren.push(joinNode);\n\t\t})\n\t}\n\t// Construct the child widgets\n\tthis.makeChildWidgets(children);\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nListItemWidget.prototype.refresh = function(changedTiddlers) {\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.listitem = ListItemWidget;\n\n/*\nMake <$list-template> and <$list-empty> widgets that do nothing\n*/\nvar ListTemplateWidget = function(parseTreeNode,options) {\n\t// Main initialisation inherited from widget.js\n\tthis.initialise(parseTreeNode,options);\n};\nListTemplateWidget.prototype = new Widget();\nListTemplateWidget.prototype.render = function() {}\nListTemplateWidget.prototype.refresh = function() { return false; }\n\nexports[\"list-template\"] = ListTemplateWidget;\n\nvar ListEmptyWidget = function(parseTreeNode,options) {\n\t// Main initialisation inherited from widget.js\n\tthis.initialise(parseTreeNode,options);\n};\nListEmptyWidget.prototype = new Widget();\nListEmptyWidget.prototype.render = function() {}\nListEmptyWidget.prototype.refresh = function() { return false; }\n\nexports[\"list-empty\"] = ListEmptyWidget;\n\nvar ListJoinWidget = function(parseTreeNode,options) {\n\t// Main initialisation inherited from widget.js\n\tthis.initialise(parseTreeNode,options);\n};\nListJoinWidget.prototype = new Widget();\nListJoinWidget.prototype.render = function() {}\nListJoinWidget.prototype.refresh = function() { return false; }\n\nexports[\"list-join\"] = ListJoinWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/log.js":{"title":"$:/core/modules/widgets/log.js","text":"/*\\\ntitle: $:/core/modules/widgets/log.js\ntype: application/javascript\nmodule-type: widget-subclass\n\nWidget to log debug messages\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.baseClass = \"action-log\";\n\nexports.name = \"log\";\n\nexports.constructor = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n}\n\nexports.prototype = {};\n\nexports.prototype.render = function(event) {\n\tObject.getPrototypeOf(Object.getPrototypeOf(this)).render.call(this,event);\n\tObject.getPrototypeOf(Object.getPrototypeOf(this)).log.call(this);\n}\n\n})();","type":"application/javascript","module-type":"widget-subclass"},"$:/core/modules/widgets/macrocall.js":{"title":"$:/core/modules/widgets/macrocall.js","text":"/*\\\ntitle: $:/core/modules/widgets/macrocall.js\ntype: application/javascript\nmodule-type: widget\n\nMacrocall widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar MacroCallWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nMacroCallWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nMacroCallWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nMacroCallWidget.prototype.execute = function() {\n\tthis.macroName = this.parseTreeNode.name || this.getAttribute(\"$name\"),\n\tthis.parseType = this.getAttribute(\"$type\",\"text/vnd.tiddlywiki\");\n\tthis.renderOutput = this.getAttribute(\"$output\",\"text/html\");\n\t// Merge together the parameters specified in the parse tree with the specified attributes\n\tvar params = this.parseTreeNode.params ? this.parseTreeNode.params.slice(0) : [];\n\t$tw.utils.each(this.attributes,function(attribute,name) {\n\t\tif(name.charAt(0) !== \"$\") {\n\t\t\tparams.push({name: name, value: attribute});\n\t\t}\n\t});\n\t// Make a transclude widget\n\tvar positionalName = 0,\n\t\tparseTreeNodes = [{\n\t\t\ttype: \"transclude\",\n\t\t\tisBlock: this.parseTreeNode.isBlock,\n\t\t\tchildren: this.parseTreeNode.children\n\t\t}];\n\t$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],\"$variable\",this.macroName);\n\t$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],\"$type\",this.parseType);\n\t$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],\"$output\",this.renderOutput);\n\t$tw.utils.each(params,function(param) {\n\t\tvar name = param.name;\n\t\tif(name) {\n\t\t\tif(name.charAt(0) === \"$\") {\n\t\t\t\tname = \"$\" + name;\n\t\t\t}\n\t\t\t$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],name,param.value);\n\t\t} else {\n\t\t\t$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],(positionalName++) + \"\",param.value);\n\t\t}\n\t});\n\t// Construct the child widgets\n\tthis.makeChildWidgets(parseTreeNodes);\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nMacroCallWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif($tw.utils.count(changedAttributes) > 0) {\n\t\t// Rerender ourselves\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports.macrocall = MacroCallWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/messagecatcher.js":{"title":"$:/core/modules/widgets/messagecatcher.js","text":"/*\\\ntitle: $:/core/modules/widgets/messagecatcher.js\ntype: application/javascript\nmodule-type: widget\n\nMessage catcher widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar MessageCatcherWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nMessageCatcherWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nMessageCatcherWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Remember parent\n\tthis.parentDomNode = parent;\n\t// Compute attributes and execute state\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Helper to add an event handler\n\tvar addEventHandler = function(type,actions) {\n\t\tif(type && actions) {\n\t\t\tvar isActionStringExecuting = false;\n\t\t\tself.addEventListener(\n\t\t\t\ttype,\n\t\t\t\tfunction(event) {\n\t\t\t\t\t// Don't trap the event if it came from one of our action handlers\n\t\t\t\t\tif(isActionStringExecuting) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\t// Collect all the event properties into variables\n\t\t\t\t\tvar collectProps = function(obj,prefix) {\n\t\t\t\t\t\tprefix = prefix || \"\";\n\t\t\t\t\t\tvar props = {},\n\t\t\t\t\t\t\tnames = [];\n\t\t\t\t\t\t$tw.utils.each(obj,function(value,name) {\n\t\t\t\t\t\t\tif([\"string\",\"boolean\",\"number\"].indexOf(typeof value) !== -1) {\n\t\t\t\t\t\t\t\tnames.push(name);\n\t\t\t\t\t\t\t\tprops[prefix + \"-\" + name] = value.toString();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t\tprops[\"list-\" + prefix] = $tw.utils.stringifyList(names);\n\t\t\t\t\t\treturn props;\n\t\t\t\t\t};\n\t\t\t\t\tvar variables = $tw.utils.extend(\n\t\t\t\t\t\t{},\n\t\t\t\t\t\tcollectProps(event.paramObject,\"event-paramObject\"),\n\t\t\t\t\t\tcollectProps(event,\"event\"),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmodifier: $tw.keyboardManager.getEventModifierKeyDescriptor(event)\n\t\t\t\t\t\t});\n\t\t\t\t\tisActionStringExecuting = true;\n\t\t\t\t\tself.invokeActionString(actions,self,event,variables);\n\t\t\t\t\tisActionStringExecuting = false;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\t}\n\t// Add the main event handler\n\taddEventHandler(this.getAttribute(\"type\"),this.getAttribute(\"actions\"));\n\t// Add any other event handlers\n\t$tw.utils.each(this.attributes,function(value,key) {\n\t\tif(key.charAt(0) === \"$\") {\n\t\t\taddEventHandler(key.slice(1),value);\n\t\t}\n\t});\n\t// Render children\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nMessageCatcherWidget.prototype.execute = function() {\n\t// Make child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nMessageCatcherWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif($tw.utils.count(changedAttributes) > 0) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.messagecatcher = MessageCatcherWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/navigator.js":{"title":"$:/core/modules/widgets/navigator.js","text":"/*\\\ntitle: $:/core/modules/widgets/navigator.js\ntype: application/javascript\nmodule-type: widget\n\nNavigator widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar IMPORT_TITLE = \"$:/Import\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar NavigatorWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nNavigatorWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nNavigatorWidget.prototype.render = function(parent,nextSibling) {\n\tthis.addEventListeners([\n\t\t{type: \"tm-navigate\", handler: \"handleNavigateEvent\"},\n\t\t{type: \"tm-edit-tiddler\", handler: \"handleEditTiddlerEvent\"},\n\t\t{type: \"tm-delete-tiddler\", handler: \"handleDeleteTiddlerEvent\"},\n\t\t{type: \"tm-save-tiddler\", handler: \"handleSaveTiddlerEvent\"},\n\t\t{type: \"tm-cancel-tiddler\", handler: \"handleCancelTiddlerEvent\"},\n\t\t{type: \"tm-close-tiddler\", handler: \"handleCloseTiddlerEvent\"},\n\t\t{type: \"tm-close-all-tiddlers\", handler: \"handleCloseAllTiddlersEvent\"},\n\t\t{type: \"tm-close-other-tiddlers\", handler: \"handleCloseOtherTiddlersEvent\"},\n\t\t{type: \"tm-new-tiddler\", handler: \"handleNewTiddlerEvent\"},\n\t\t{type: \"tm-import-tiddlers\", handler: \"handleImportTiddlersEvent\"},\n\t\t{type: \"tm-perform-import\", handler: \"handlePerformImportEvent\"},\n\t\t{type: \"tm-fold-tiddler\", handler: \"handleFoldTiddlerEvent\"},\n\t\t{type: \"tm-fold-other-tiddlers\", handler: \"handleFoldOtherTiddlersEvent\"},\n\t\t{type: \"tm-fold-all-tiddlers\", handler: \"handleFoldAllTiddlersEvent\"},\n\t\t{type: \"tm-unfold-all-tiddlers\", handler: \"handleUnfoldAllTiddlersEvent\"}\n\t]);\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nNavigatorWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.storyTitle = this.getAttribute(\"story\");\n\tthis.historyTitle = this.getAttribute(\"history\");\n\tthis.setVariable(\"tv-story-list\",this.storyTitle);\n\tthis.setVariable(\"tv-history-list\",this.historyTitle);\n\tthis.story = new $tw.Story({\n\t\twiki: this.wiki,\n\t\tstoryTitle: this.storyTitle,\n\t\thistoryTitle: this.historyTitle\n\t});\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nNavigatorWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.story || changedAttributes.history) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nNavigatorWidget.prototype.getStoryList = function() {\n\treturn this.storyTitle ? this.wiki.getTiddlerList(this.storyTitle) : null;\n};\n\nNavigatorWidget.prototype.saveStoryList = function(storyList) {\n\tif(this.storyTitle) {\n\t\tvar storyTiddler = this.wiki.getTiddler(this.storyTitle);\n\t\tthis.wiki.addTiddler(new $tw.Tiddler(\n\t\t\t{title: this.storyTitle},\n\t\t\tstoryTiddler,\n\t\t\t{list: storyList}\n\t\t));\n\t}\n};\n\nNavigatorWidget.prototype.removeTitleFromStory = function(storyList,title) {\n\tif(storyList) {\n\t\tvar p = storyList.indexOf(title);\n\t\twhile(p !== -1) {\n\t\t\tstoryList.splice(p,1);\n\t\t\tp = storyList.indexOf(title);\n\t\t}\n\t}\n};\n\nNavigatorWidget.prototype.replaceFirstTitleInStory = function(storyList,oldTitle,newTitle) {\n\tif(storyList) {\n\t\tvar pos = storyList.indexOf(oldTitle);\n\t\tif(pos !== -1) {\n\t\t\tstoryList[pos] = newTitle;\n\t\t\tdo {\n\t\t\t\tpos = storyList.indexOf(oldTitle,pos + 1);\n\t\t\t\tif(pos !== -1) {\n\t\t\t\t\tstoryList.splice(pos,1);\n\t\t\t\t}\n\t\t\t} while(pos !== -1);\n\t\t} else {\n\t\t\tstoryList.splice(0,0,newTitle);\n\t\t}\n\t}\n};\n\nNavigatorWidget.prototype.addToStory = function(title,fromTitle) {\n\tif(this.storyTitle) {\n\t\tthis.story.addToStory(title,fromTitle,{\n\t\t\topenLinkFromInsideRiver: this.getAttribute(\"openLinkFromInsideRiver\",\"top\"),\n\t\t\topenLinkFromOutsideRiver: this.getAttribute(\"openLinkFromOutsideRiver\",\"top\")\n\t\t});\n\t}\n};\n\n/*\nAdd a new record to the top of the history stack\ntitle: a title string or an array of title strings\nfromPageRect: page coordinates of the origin of the navigation\n*/\nNavigatorWidget.prototype.addToHistory = function(title,fromPageRect) {\n\tthis.story.addToHistory(title,fromPageRect,this.historyTitle);\n};\n\n/*\nHandle a tm-navigate event\n*/\nNavigatorWidget.prototype.handleNavigateEvent = function(event) {\n\tevent = $tw.hooks.invokeHook(\"th-navigating\",event);\n\tif(event.navigateTo) {\n\t\tthis.addToStory(event.navigateTo,event.navigateFromTitle);\n\t\tif(!event.navigateSuppressNavigation) {\n\t\t\tthis.addToHistory(event.navigateTo,event.navigateFromClientRect);\n\t\t}\n\t}\n\treturn false;\n};\n\n// Close a specified tiddler\nNavigatorWidget.prototype.handleCloseTiddlerEvent = function(event) {\n\tevent = $tw.hooks.invokeHook(\"th-closing-tiddler\",event);\n\tvar title = event.param || event.tiddlerTitle,\n\t\tstoryList = this.getStoryList();\n\t// Look for tiddlers with this title to close\n\tthis.removeTitleFromStory(storyList,title);\n\tthis.saveStoryList(storyList);\n\treturn false;\n};\n\n// Close all tiddlers\nNavigatorWidget.prototype.handleCloseAllTiddlersEvent = function(event) {\n\tthis.saveStoryList([]);\n\treturn false;\n};\n\n// Close other tiddlers\nNavigatorWidget.prototype.handleCloseOtherTiddlersEvent = function(event) {\n\tvar title = event.param || event.tiddlerTitle;\n\tthis.saveStoryList([title]);\n\treturn false;\n};\n\n// Place a tiddler in edit mode\nNavigatorWidget.prototype.handleEditTiddlerEvent = function(event) {\n\tvar editTiddler = $tw.hooks.invokeHook(\"th-editing-tiddler\",event),\n\t\twin = event.event && event.event.view ? event.event.view : window;\n\tif(!editTiddler) {\n\t\treturn false;\n\t}\n\tvar self = this;\n\tfunction isUnmodifiedShadow(title) {\n\t\treturn self.wiki.isShadowTiddler(title) && !self.wiki.tiddlerExists(title);\n\t}\n\tfunction confirmEditShadow(title) {\n\t\treturn win.confirm($tw.language.getString(\n\t\t\t\"ConfirmEditShadowTiddler\",\n\t\t\t{variables:\n\t\t\t\t{title: title}\n\t\t\t}\n\t\t));\n\t}\n\tvar title = event.param || event.tiddlerTitle;\n\tif(isUnmodifiedShadow(title) && !confirmEditShadow(title)) {\n\t\treturn false;\n\t}\n\t// Replace the specified tiddler with a draft in edit mode\n\tvar draftTiddler = this.makeDraftTiddler(title);\n\t// Update the story and history if required\n\tif(!event.paramObject || event.paramObject.suppressNavigation !== \"yes\") {\n\t\tvar draftTitle = draftTiddler.fields.title,\n\t\t\tstoryList = this.getStoryList();\n\t\tthis.removeTitleFromStory(storyList,draftTitle);\n\t\tthis.replaceFirstTitleInStory(storyList,title,draftTitle);\n\t\tthis.addToHistory(draftTitle,event.navigateFromClientRect);\n\t\tthis.saveStoryList(storyList);\n\t\treturn false;\n\t}\n};\n\n// Delete a tiddler\nNavigatorWidget.prototype.handleDeleteTiddlerEvent = function(event) {\n\t// Get the tiddler we're deleting\n\tvar title = event.param || event.tiddlerTitle,\n\t\ttiddler = this.wiki.getTiddler(title),\n\t\tstoryList = this.getStoryList(),\n\t\toriginalTitle = tiddler ? tiddler.fields[\"draft.of\"] : \"\",\n\t\toriginalTiddler = originalTitle ? this.wiki.getTiddler(originalTitle) : undefined,\n\t\tconfirmationTitle,\n\t\twin = event.event && event.event.view ? event.event.view : window;\n\t// Check if the tiddler we're deleting is in draft mode\n\tif(originalTitle) {\n\t\t// If so, we'll prompt for confirmation referencing the original tiddler\n\t\tconfirmationTitle = originalTitle;\n\t} else {\n\t\t// If not a draft, then prompt for confirmation referencing the specified tiddler\n\t\tconfirmationTitle = title;\n\t}\n\t// Seek confirmation\n\tif(((originalTitle && this.wiki.getTiddler(originalTitle)) || (tiddler && ((tiddler.fields.text || \"\") !== \"\"))) && !win.confirm($tw.language.getString(\n\t\t\t\t\"ConfirmDeleteTiddler\",\n\t\t\t\t{variables:\n\t\t\t\t\t{title: confirmationTitle}\n\t\t\t\t}\n\t\t\t))) {\n\t\treturn false;\n\t}\n\t// Delete the original tiddler\n\tif(originalTitle) {\n\t\tif(originalTiddler) {\n\t\t\t$tw.hooks.invokeHook(\"th-deleting-tiddler\",originalTiddler);\n\t\t}\n\t\tthis.wiki.deleteTiddler(originalTitle);\n\t\tthis.removeTitleFromStory(storyList,originalTitle);\n\t}\n\t// Invoke the hook function and delete this tiddler\n\tif(tiddler) {\n\t\t$tw.hooks.invokeHook(\"th-deleting-tiddler\",tiddler);\n\t\tthis.wiki.deleteTiddler(title);\t\n\t}\n\t// Remove the closed tiddler from the story\n\tthis.removeTitleFromStory(storyList,title);\n\tthis.saveStoryList(storyList);\n\t// Trigger an autosave\n\t$tw.rootWidget.dispatchEvent({type: \"tm-auto-save-wiki\"});\n\treturn false;\n};\n\n/*\nCreate/reuse the draft tiddler for a given title\n*/\nNavigatorWidget.prototype.makeDraftTiddler = function(targetTitle) {\n\t// See if there is already a draft tiddler for this tiddler\n\tvar draftTitle = this.wiki.findDraft(targetTitle);\n\tif(draftTitle) {\n\t\treturn this.wiki.getTiddler(draftTitle);\n\t}\n\t// Get the current value of the tiddler we're editing\n\tvar tiddler = this.wiki.getTiddler(targetTitle);\n\t// Save the initial value of the draft tiddler\n\tdraftTitle = this.generateDraftTitle(targetTitle);\n\tvar draftTiddler = new $tw.Tiddler({\n\t\t\t\ttext: \"\",\n\t\t\t},\n\t\t\ttiddler,\n\t\t\t{\n\t\t\t\ttitle: draftTitle,\n\t\t\t\t\"draft.title\": targetTitle,\n\t\t\t\t\"draft.of\": targetTitle\n\t\t\t},\n\t\t\tthis.wiki.getModificationFields()\n\t\t);\n\tthis.wiki.addTiddler(draftTiddler);\n\treturn draftTiddler;\n};\n\n/*\nGenerate a title for the draft of a given tiddler\n*/\nNavigatorWidget.prototype.generateDraftTitle = function(title) {\n\treturn this.wiki.generateDraftTitle(title);\n};\n\n// Take a tiddler out of edit mode, saving the changes\nNavigatorWidget.prototype.handleSaveTiddlerEvent = function(event) {\n\tvar title = event.param || event.tiddlerTitle,\n\t\ttiddler = this.wiki.getTiddler(title),\n\t\tstoryList = this.getStoryList(),\n\t\twin = event.event && event.event.view ? event.event.view : window;\n\t// Replace the original tiddler with the draft\n\tif(tiddler) {\n\t\tvar draftTitle = (tiddler.fields[\"draft.title\"] || \"\").trim(),\n\t\t\tdraftOf = (tiddler.fields[\"draft.of\"] || \"\").trim();\n\t\tif(draftTitle) {\n\t\t\tvar isRename = draftOf !== draftTitle,\n\t\t\t\tisConfirmed = true;\n\t\t\tif(isRename && this.wiki.tiddlerExists(draftTitle)) {\n\t\t\t\tisConfirmed = win.confirm($tw.language.getString(\n\t\t\t\t\t\"ConfirmOverwriteTiddler\",\n\t\t\t\t\t{variables:\n\t\t\t\t\t\t{title: draftTitle}\n\t\t\t\t\t}\n\t\t\t\t));\n\t\t\t}\n\t\t\tif(isConfirmed) {\n\t\t\t\t// Create the new tiddler and pass it through the th-saving-tiddler hook\n\t\t\t\tvar newTiddler = new $tw.Tiddler(this.wiki.getCreationFields(),tiddler,{\n\t\t\t\t\ttitle: draftTitle,\n\t\t\t\t\t\"draft.title\": undefined,\n\t\t\t\t\t\"draft.of\": undefined\n\t\t\t\t},this.wiki.getModificationFields());\n\t\t\t\tnewTiddler = $tw.hooks.invokeHook(\"th-saving-tiddler\",newTiddler,tiddler);\n\t\t\t\tthis.wiki.addTiddler(newTiddler);\n\t\t\t\t// If enabled, relink references to renamed tiddler\n\t\t\t\tvar shouldRelink = this.getAttribute(\"relinkOnRename\",\"no\").toLowerCase().trim() === \"yes\";\n\t\t\t\tif(isRename && shouldRelink && this.wiki.tiddlerExists(draftOf)) {\n\t\t\t\t\tthis.wiki.relinkTiddler(draftOf,draftTitle);\n\t\t\t\t}\n\t\t\t\t// Remove the draft tiddler\n\t\t\t\tthis.wiki.deleteTiddler(title);\n\t\t\t\t// Remove the original tiddler if we're renaming it\n\t\t\t\tif(isRename) {\n\t\t\t\t\tthis.wiki.deleteTiddler(draftOf);\n\t\t\t\t}\n\t\t\t\t// #2381 always remove new title & old\n\t\t\t\tthis.removeTitleFromStory(storyList,draftTitle);\n\t\t\t\tthis.removeTitleFromStory(storyList,draftOf);\n\t\t\t\tif(!event.paramObject || event.paramObject.suppressNavigation !== \"yes\") {\n\t\t\t\t\t// Replace the draft in the story with the original\n\t\t\t\t\tthis.replaceFirstTitleInStory(storyList,title,draftTitle);\n\t\t\t\t\tthis.addToHistory(draftTitle,event.navigateFromClientRect);\n\t\t\t\t\tif(draftTitle !== this.storyTitle) {\n\t\t\t\t\t\tthis.saveStoryList(storyList);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Trigger an autosave\n\t\t\t\t$tw.rootWidget.dispatchEvent({type: \"tm-auto-save-wiki\"});\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n};\n\n// Take a tiddler out of edit mode without saving the changes\nNavigatorWidget.prototype.handleCancelTiddlerEvent = function(event) {\n\tevent = $tw.hooks.invokeHook(\"th-cancelling-tiddler\", event);\n\tvar win = event.event && event.event.view ? event.event.view : window;\n\t// Flip the specified tiddler from draft back to the original\n\tvar draftTitle = event.param || event.tiddlerTitle,\n\t\tdraftTiddler = this.wiki.getTiddler(draftTitle),\n\t\toriginalTitle = draftTiddler && draftTiddler.fields[\"draft.of\"];\n\tif(draftTiddler && originalTitle) {\n\t\t// Ask for confirmation if the tiddler text has changed\n\t\tvar isConfirmed = true,\n\t\t\toriginalTiddler = this.wiki.getTiddler(originalTitle),\n\t\t\tstoryList = this.getStoryList();\n\t\tif(this.wiki.isDraftModified(draftTitle)) {\n\t\t\tisConfirmed = win.confirm($tw.language.getString(\n\t\t\t\t\"ConfirmCancelTiddler\",\n\t\t\t\t{variables:\n\t\t\t\t\t{title: draftTitle}\n\t\t\t\t}\n\t\t\t));\n\t\t}\n\t\t// Remove the draft tiddler\n\t\tif(isConfirmed) {\n\t\t\tthis.wiki.deleteTiddler(draftTitle);\n\t\t\tif(!event.paramObject || event.paramObject.suppressNavigation !== \"yes\") {\n\t\t\t\tif(originalTiddler) {\n\t\t\t\t\tthis.replaceFirstTitleInStory(storyList,draftTitle,originalTitle);\n\t\t\t\t\tthis.addToHistory(originalTitle,event.navigateFromClientRect);\n\t\t\t\t} else {\n\t\t\t\t\tthis.removeTitleFromStory(storyList,draftTitle);\n\t\t\t\t}\n\t\t\t\tthis.saveStoryList(storyList);\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n};\n\n// Create a new draft tiddler\n// event.param can either be the title of a template tiddler, or a hashmap of fields.\n//\n// The title of the newly created tiddler follows these rules:\n// * If a hashmap was used and a title field was specified, use that title\n// * If a hashmap was used without a title field, use a default title, if necessary making it unique with a numeric suffix\n// * If a template tiddler was used, use the title of the template, if necessary making it unique with a numeric suffix\n//\n// If a draft of the target tiddler already exists then it is reused\nNavigatorWidget.prototype.handleNewTiddlerEvent = function(event) {\n\tevent = $tw.hooks.invokeHook(\"th-new-tiddler\", event);\n\t// Get the story details\n\tvar storyList = this.getStoryList(),\n\t\ttemplateTiddler, additionalFields, title, draftTitle, existingTiddler,\n\t\ttemplateHasTags = false;\n\t// Get the template tiddler (if any)\n\tif(typeof event.param === \"string\") {\n\t\t// Get the template tiddler\n\t\ttemplateTiddler = this.wiki.getTiddler(event.param);\n\t\t// Generate a new title\n\t\ttitle = this.wiki.generateNewTitle(event.param || $tw.language.getString(\"DefaultNewTiddlerTitle\"));\n\t}\n\t// Get the specified additional fields\n\tif(typeof event.paramObject === \"object\") {\n\t\tadditionalFields = event.paramObject;\n\t}\n\tif(typeof event.param === \"object\") { // Backwards compatibility with 5.1.3\n\t\tadditionalFields = event.param;\n\t}\n\tif(additionalFields && additionalFields.title) {\n\t\ttitle = additionalFields.title;\n\t}\n\t// Make a copy of the additional fields excluding any blank ones\n\tvar filteredAdditionalFields = $tw.utils.extend({},additionalFields);\n\tObject.keys(filteredAdditionalFields).forEach(function(fieldName) {\n\t\tif(filteredAdditionalFields[fieldName] === \"\") {\n\t\t\tdelete filteredAdditionalFields[fieldName];\n\t\t}\n\t});\n\t// Generate a title if we don't have one\n\ttitle = title || this.wiki.generateNewTitle($tw.language.getString(\"DefaultNewTiddlerTitle\"));\n\t// Find any existing draft for this tiddler\n\tdraftTitle = this.wiki.findDraft(title);\n\t// Pull in any existing tiddler\n\tif(draftTitle) {\n\t\texistingTiddler = this.wiki.getTiddler(draftTitle);\n\t} else {\n\t\tdraftTitle = this.generateDraftTitle(title);\n\t\texistingTiddler = this.wiki.getTiddler(title);\n\t}\n\t// Merge the tags\n\tvar mergedTags = [];\n\tif(existingTiddler && existingTiddler.fields.tags) {\n\t\t$tw.utils.pushTop(mergedTags,existingTiddler.fields.tags);\n\t}\n\tif(additionalFields && additionalFields.tags) {\n\t\t// Merge tags\n\t\tmergedTags = $tw.utils.pushTop(mergedTags,$tw.utils.parseStringArray(additionalFields.tags));\n\t}\n\tvar additionalFieldsHasTags = !!(additionalFields && (additionalFields.tags === \"\"));\n\tif(templateTiddler && templateTiddler.fields.tags) {\n\t\t// Merge tags\n\t\ttemplateHasTags = true;\n\t\tmergedTags = $tw.utils.pushTop(mergedTags,templateTiddler.fields.tags);\n\t}\n\t// Save the draft tiddler\n\tvar draftTiddler = new $tw.Tiddler({\n\t\t\ttext: \"\",\n\t\t\t\"draft.title\": title\n\t\t},\n\t\ttemplateTiddler,\n\t\tadditionalFields,\n\t\tthis.wiki.getCreationFields(),\n\t\texistingTiddler,\n\t\tfilteredAdditionalFields,\n\t\t{\n\t\t\ttitle: draftTitle,\n\t\t\t\"draft.of\": title,\n\t\t\t// If template or additionalFields have \"tags\" even if empty a tags field will be created.\n\t\t\ttags: ((mergedTags.length > 0) || templateHasTags || additionalFieldsHasTags) ? mergedTags : undefined\n\t\t},this.wiki.getModificationFields());\n\tthis.wiki.addTiddler(draftTiddler);\n\t// Update the story to insert the new draft at the top and remove any existing tiddler\n\tif(storyList && storyList.indexOf(draftTitle) === -1) {\n\t\tvar slot = storyList.indexOf(event.navigateFromTitle);\n\t\tif(slot === -1) {\n\t\t\tslot = this.getAttribute(\"openLinkFromOutsideRiver\",\"top\") === \"bottom\" ? storyList.length - 1 : slot;\n\t\t}\n\t\tstoryList.splice(slot + 1,0,draftTitle);\n\t}\n\tif(storyList && storyList.indexOf(title) !== -1) {\n\t\tstoryList.splice(storyList.indexOf(title),1);\n\t}\n\tthis.saveStoryList(storyList);\n\t// Add a new record to the top of the history stack\n\tthis.addToHistory(draftTitle);\n\treturn false;\n};\n\n// Import JSON tiddlers into a pending import tiddler\nNavigatorWidget.prototype.handleImportTiddlersEvent = function(event) {\n\t// Get the tiddlers\n\tvar tiddlers = $tw.utils.parseJSONSafe(event.param,[]);\n\t// Get the current $:/Import tiddler\n\tvar paramObject = event.paramObject || {},\n\t\timportTitle = event.importTitle || paramObject.importTitle || IMPORT_TITLE,\n\t\timportTiddler = this.wiki.getTiddler(importTitle),\n\t\timportData = this.wiki.getTiddlerData(importTitle,{}),\n\t\tnewFields = new Object({\n\t\t\ttitle: importTitle,\n\t\t\ttype: \"application/json\",\n\t\t\t\"plugin-type\": \"import\",\n\t\t\t\"status\": \"pending\"\n\t\t}),\n\t\tincomingTiddlers = [];\n\t// Process each tiddler\n\timportData.tiddlers = importData.tiddlers || {};\n\t$tw.utils.each(tiddlers,function(tiddlerFields) {\n\t\ttiddlerFields.title = $tw.utils.trim(tiddlerFields.title);\n\t\tvar title = tiddlerFields.title;\n\t\tif(title) {\n\t\t\tincomingTiddlers.push(title);\n\t\t\timportData.tiddlers[title] = tiddlerFields;\n\t\t}\n\t});\n\t// Give the active upgrader modules a chance to process the incoming tiddlers\n\tvar messages = this.wiki.invokeUpgraders(incomingTiddlers,importData.tiddlers);\n\t// Deselect any disabled, but _not_ suppressed tiddlers\n\tvar systemMessage = $tw.language.getString(\"Import/Upgrader/Tiddler/Unselected\");\n\t$tw.utils.each(messages,function(message,title) {\n\t\tnewFields[\"message-\" + title] = message;\n\t\tif(message.indexOf(systemMessage) !== -1) {\n\t\t\tnewFields[\"selection-\" + title] = \"unchecked\";\n\t\t}\n\t});\n\t// Deselect suppressed tiddlers ... they have been removed and can't be selected anymore\n\t$tw.utils.each(importData.tiddlers,function(tiddler,title) {\n\t\tif($tw.utils.count(tiddler) === 0) {\n\t\t\tnewFields[\"selection-\" + title] = \"unchecked\";\n\t\t\tnewFields[\"suppressed-\" + title] = \"yes\";\n\t\t}\n\t});\n\t// Save the $:/Import tiddler\n\tnewFields.text = JSON.stringify(importData,null,$tw.config.preferences.jsonSpaces);\n\tthis.wiki.addTiddler(new $tw.Tiddler(importTiddler,newFields));\n\t// Update the story and history details\n\tvar autoOpenOnImport = event.autoOpenOnImport || paramObject.autoOpenOnImport || this.getVariable(\"tv-auto-open-on-import\");\n\tif(autoOpenOnImport !== \"no\") {\n\t\tvar storyList = this.getStoryList(),\n\t\t\thistory = [];\n\t\t// Add it to the story\n\t\tif(storyList && storyList.indexOf(importTitle) === -1) {\n\t\t\tstoryList.unshift(importTitle);\n\t\t}\n\t\t// And to history\n\t\thistory.push(importTitle);\n\t\t// Save the updated story and history\n\t\tthis.saveStoryList(storyList);\n\t\tthis.addToHistory(history);\n\t}\n\treturn false;\n};\n\n//\nNavigatorWidget.prototype.handlePerformImportEvent = function(event) {\n\tvar self = this,\n\t\timportTiddler = this.wiki.getTiddler(event.param),\n\t\timportData,\n\t\timportReport = [];\n\timportReport.push($tw.language.getString(\"Import/Imported/Hint\") + \"\\n\");\n\t// If you need to modify the import tiddler payload then consider th-importing-tiddler instead\n\timportTiddler = $tw.hooks.invokeHook(\"th-before-importing\",importTiddler);\n\timportData = this.wiki.getTiddlerDataCached(event.param,{tiddlers: {}}),\n\t$tw.utils.each(importData.tiddlers,function(tiddlerFields) {\n\t\tvar title = tiddlerFields.title;\n\t\tif(title && importTiddler && importTiddler.fields[\"selection-\" + title] !== \"unchecked\") {\n\t\t\tif($tw.utils.hop(importTiddler.fields,[\"rename-\" + title])) {\n\t\t\t\tvar tiddler = new $tw.Tiddler(tiddlerFields,{title : importTiddler.fields[\"rename-\" + title]});\n\t\t\t} else {\n\t\t\t\tvar tiddler = new $tw.Tiddler(tiddlerFields);\n\t\t\t}\n\t\t\t// th-importing-tiddler doesn't allow user interaction by default\n\t\t\t// If you want to use the default UI then use: $:/core/modules/upgraders/ instead\n\t\t\ttiddler = $tw.hooks.invokeHook(\"th-importing-tiddler\",tiddler);\n\t\t\t// Add the tiddlers to the store\n\t\t\tself.wiki.addTiddler(tiddler);\n\t\t\timportReport.push(\"# [[\" + tiddler.fields.title + \"]]\");\n\t\t}\n\t});\n\t// Replace the $:/Import tiddler with an import report\n\tthis.wiki.addTiddler(new $tw.Tiddler({\n\t\ttitle: event.param,\n\t\ttext: importReport.join(\"\\n\"),\n\t\t\"status\": \"complete\"\n\t}));\n\t// Navigate to the $:/Import tiddler\n\tthis.addToHistory([event.param]);\n\t// Trigger an autosave\n\t$tw.rootWidget.dispatchEvent({type: \"tm-auto-save-wiki\"});\n};\n\nNavigatorWidget.prototype.handleFoldTiddlerEvent = function(event) {\n\tvar paramObject = event.paramObject || {};\n\tif(paramObject.foldedState) {\n\t\tvar foldedState = this.wiki.getTiddlerText(paramObject.foldedState,\"show\") === \"show\" ? \"hide\" : \"show\";\n\t\tthis.wiki.setText(paramObject.foldedState,\"text\",null,foldedState);\n\t}\n};\n\nNavigatorWidget.prototype.handleFoldOtherTiddlersEvent = function(event) {\n\tvar self = this,\n\t\tparamObject = event.paramObject || {},\n\t\tprefix = paramObject.foldedStatePrefix;\n\t$tw.utils.each(this.getStoryList(),function(title) {\n\t\tself.wiki.setText(prefix + title,\"text\",null,event.param === title ? \"show\" : \"hide\");\n\t});\n};\n\nNavigatorWidget.prototype.handleFoldAllTiddlersEvent = function(event) {\n\tvar self = this,\n\t\tparamObject = event.paramObject || {},\n\t\tprefix = paramObject.foldedStatePrefix || \"$:/state/folded/\";\n\t$tw.utils.each(this.getStoryList(),function(title) {\n\t\tself.wiki.setText(prefix + title,\"text\",null,\"hide\");\n\t});\n};\n\nNavigatorWidget.prototype.handleUnfoldAllTiddlersEvent = function(event) {\n\tvar self = this,\n\t\tparamObject = event.paramObject || {},\n\t\tprefix = paramObject.foldedStatePrefix;\n\t$tw.utils.each(this.getStoryList(),function(title) {\n\t\tself.wiki.setText(prefix + title,\"text\",null,\"show\");\n\t});\n};\n\nexports.navigator = NavigatorWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/parameters.js":{"title":"$:/core/modules/widgets/parameters.js","text":"/*\\\ntitle: $:/core/modules/widgets/parameters.js\ntype: application/javascript\nmodule-type: widget\n\nWidget for definition of transclusion parameters\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget,\n\tTranscludeWidget = require(\"$:/core/modules/widgets/transclude.js\").transclude;\n\nvar ParametersWidget = function(parseTreeNode,options) {\n\t// Initialise\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nParametersWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nParametersWidget.prototype.render = function(parent,nextSibling) {\n\t// Call the constructor\n\tWidget.call(this);\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nParametersWidget.prototype.execute = function() {\n\tvar self = this;\n\tthis.parametersDepth = Math.max(parseInt(this.getAttribute(\"$depth\",\"1\"),10) || 1,1);\n\t// Find the parent transclusions\n\tvar pointer = this.parentWidget,\n\t\tdepth = this.parametersDepth;\n\twhile(pointer) {\n\t\tif(pointer instanceof TranscludeWidget) {\n\t\t\tdepth--;\n\t\t\tif(depth <= 0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tpointer = pointer.parentWidget;\n\t}\n\t// Process each parameter\n\tif(pointer instanceof TranscludeWidget) {\n\t\t// Get the value for each defined parameter\n\t\t$tw.utils.each($tw.utils.getOrderedAttributesFromParseTreeNode(self.parseTreeNode),function(attr,index) {\n\t\t\tvar name = attr.name;\n\t\t\t// If the attribute name starts with $$ then reduce to a single dollar\n\t\t\tif(name.substr(0,2) === \"$$\") {\n\t\t\t\tname = name.substr(1);\n\t\t\t}\n\t\t\tvar value = pointer.getTransclusionParameter(name,index,self.getAttribute(attr.name,\"\"));\n\t\t\tself.setVariable(name,value);\n\t\t});\n\t\t// Assign any metaparameters\n\t\t$tw.utils.each(pointer.getTransclusionMetaParameters(),function(getValue,name) {\n\t\t\tvar variableName = self.getAttribute(\"$\" + name);\n\t\t\tif(variableName) {\n\t\t\t\tself.setVariable(variableName,getValue(name));\n\t\t\t}\n\t\t});\n\t} else {\n\t\t// There is no parent transclude. i.e. direct rendering.\n\t\t// We use default values only.\n\t\t$tw.utils.each($tw.utils.getOrderedAttributesFromParseTreeNode(self.parseTreeNode),function(attr,index) {\n\t\t\tvar name = attr.name;\n\t\t\t// If the attribute name starts with $$ then reduce to a single dollar\n\t\t\tif(name.substr(0,2) === \"$$\") {\n\t\t\t\tname = name.substr(1);\n\t\t\t}\n\t\t\tvar value = self.getAttribute(attr.name,\"\");\n\t\t\tself.setVariable(name,value);\n\t\t});\n\t}\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nParametersWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(Object.keys(changedAttributes).length) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.parameters = ParametersWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/password.js":{"title":"$:/core/modules/widgets/password.js","text":"/*\\\ntitle: $:/core/modules/widgets/password.js\ntype: application/javascript\nmodule-type: widget\n\nPassword widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar PasswordWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nPasswordWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nPasswordWidget.prototype.render = function(parent,nextSibling) {\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\t// Get the current password\n\tvar password = $tw.browser ? $tw.utils.getPassword(this.passwordName) || \"\" : \"\";\n\t// Create our element\n\tvar domNode = this.document.createElement(\"input\");\n\tdomNode.setAttribute(\"type\",\"password\");\n\tdomNode.setAttribute(\"value\",password);\n\t// Add a click event handler\n\t$tw.utils.addEventListeners(domNode,[\n\t\t{name: \"change\", handlerObject: this, handlerMethod: \"handleChangeEvent\"}\n\t]);\n\t// Insert the label into the DOM and render any children\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n};\n\nPasswordWidget.prototype.handleChangeEvent = function(event) {\n\tvar password = this.domNodes[0].value;\n\treturn $tw.utils.savePassword(this.passwordName,password);\n};\n\n/*\nCompute the internal state of the widget\n*/\nPasswordWidget.prototype.execute = function() {\n\t// Get the parameters from the attributes\n\tthis.passwordName = this.getAttribute(\"name\",\"\");\n\t// Make the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nPasswordWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.name) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports.password = PasswordWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/qualify.js":{"title":"$:/core/modules/widgets/qualify.js","text":"/*\\\ntitle: $:/core/modules/widgets/qualify.js\ntype: application/javascript\nmodule-type: widget\n\nQualify text to a variable \n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar QualifyWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nQualifyWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nQualifyWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nQualifyWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.qualifyName = this.getAttribute(\"name\");\n\tthis.qualifyTitle = this.getAttribute(\"title\");\n\t// Set context variable\n\tif(this.qualifyName) {\n\t\tthis.setVariable(this.qualifyName,this.qualifyTitle + \"-\" + this.getStateQualifier());\n\t}\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nQualifyWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.name || changedAttributes.title) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports.qualify = QualifyWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/radio.js":{"title":"$:/core/modules/widgets/radio.js","text":"/*\\\ntitle: $:/core/modules/widgets/radio.js\ntype: application/javascript\nmodule-type: widget\n\nSet a field or index at a given tiddler via radio buttons\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\nvar RadioWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nRadioWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nRadioWidget.prototype.render = function(parent,nextSibling) {\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\tvar isChecked = this.getValue() === this.radioValue;\n\t// Create our elements\n\tthis.labelDomNode = this.document.createElement(\"label\");\n\tthis.labelDomNode.setAttribute(\"class\",\n\t\t\"tc-radio \" + this.radioClass + (isChecked ? \" tc-radio-selected\" : \"\")\n\t);\n\tthis.inputDomNode = this.document.createElement(\"input\");\n\tthis.inputDomNode.setAttribute(\"type\",\"radio\");\n\tthis.assignAttributes(this.inputDomNode,{\n\t\tsourcePrefix: \"data-\",\n\t\tdestPrefix: \"data-\"\n\t});\n\tif(isChecked) {\n\t\tthis.inputDomNode.checked = true;\n\t}\n\tif(this.isDisabled === \"yes\") {\n\t\tthis.inputDomNode.setAttribute(\"disabled\",true);\n\t}\n\tthis.labelDomNode.appendChild(this.inputDomNode);\n\tthis.spanDomNode = this.document.createElement(\"span\");\n\tthis.labelDomNode.appendChild(this.spanDomNode);\n\t// Add a click event handler\n\t$tw.utils.addEventListeners(this.inputDomNode,[\n\t\t{name: \"change\", handlerObject: this, handlerMethod: \"handleChangeEvent\"}\n\t]);\n\t// Insert the label into the DOM and render any children\n\tparent.insertBefore(this.labelDomNode,nextSibling);\n\tthis.renderChildren(this.spanDomNode,null);\n\tthis.domNodes.push(this.labelDomNode);\n};\n\nRadioWidget.prototype.getValue = function() {\n\tvar value,\n\t\ttiddler = this.wiki.getTiddler(this.radioTitle);\n\tif(tiddler) {\n\t\tif(this.radioIndex) {\n\t\t\tvalue = this.wiki.extractTiddlerDataItem(this.radioTitle,this.radioIndex,this.radioDefault);\n\t\t} else {\n\t\t\tvalue = tiddler.getFieldString(this.radioField,this.radioDefault);\n\t\t}\n\t} else {\n\t\tvalue = this.radioDefault;\n\t}\n\treturn value;\n};\n\nRadioWidget.prototype.setValue = function() {\n\tif(this.radioIndex) {\n\t\tthis.wiki.setText(this.radioTitle,\"\",this.radioIndex,this.radioValue);\n\t} else {\n\t\tvar tiddler = this.wiki.getTiddler(this.radioTitle),\n\t\t\taddition = {};\n\t\taddition[this.radioField] = this.radioValue;\n\t\tthis.wiki.addTiddler(new $tw.Tiddler(this.wiki.getCreationFields(),{title: this.radioTitle},tiddler,addition,this.wiki.getModificationFields()));\n\t}\n};\n\nRadioWidget.prototype.handleChangeEvent = function(event) {\n\tif(this.inputDomNode.checked) {\n\t\tthis.setValue();\n\t}\n\t// Trigger actions\n\tif(this.radioActions) {\n\t\tthis.invokeActionString(this.radioActions,this,event,{\"actionValue\": this.radioValue});\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nRadioWidget.prototype.execute = function() {\n\t// Get the parameters from the attributes\n\tthis.radioTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.radioField = this.getAttribute(\"field\",\"text\");\n\tthis.radioIndex = this.getAttribute(\"index\");\n\tthis.radioValue = this.getAttribute(\"value\");\n\tthis.radioClass = this.getAttribute(\"class\",\"\");\n\tthis.radioDefault = this.getAttribute(\"default\");\n\tthis.isDisabled = this.getAttribute(\"disabled\",\"no\");\n\tthis.radioActions = this.getAttribute(\"actions\",\"\");\n\t// Make the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nRadioWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(($tw.utils.count(changedAttributes) > 0)) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else if(changedTiddlers[this.radioTitle]) {\n\t\tthis.inputDomNode.checked = this.getValue() === this.radioValue;\n\t\t$tw.utils.toggleClass(this.labelDomNode,\"tc-radio-selected\",this.inputDomNode.checked);\n\t\treturn this.refreshChildren(changedTiddlers);\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports.radio = RadioWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/range.js":{"title":"$:/core/modules/widgets/range.js","text":"/*\\\ntitle: $:/core/modules/widgets/range.js\ntype: application/javascript\nmodule-type: widget\n\nRange widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar RangeWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nRangeWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nRangeWidget.prototype.render = function(parent,nextSibling) {\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\t// Create our elements\n\tthis.inputDomNode = this.document.createElement(\"input\");\n\tthis.inputDomNode.setAttribute(\"type\",\"range\");\n\tthis.inputDomNode.setAttribute(\"class\",this.elementClass);\n\tif(this.minValue){\n\t\tthis.inputDomNode.setAttribute(\"min\", this.minValue);\n\t}\n\tif(this.maxValue){\n\t\tthis.inputDomNode.setAttribute(\"max\", this.maxValue);\n\t}\n\tif(this.increment){\n\t\tthis.inputDomNode.setAttribute(\"step\", this.increment);\n\t}\n\tif(this.isDisabled === \"yes\") {\n\t\tthis.inputDomNode.setAttribute(\"disabled\",true);\n\t}\n\tthis.inputDomNode.value = this.getValue();\n\tthis.assignAttributes(this.inputDomNode,{\n\t\tsourcePrefix: \"data-\",\n\t\tdestPrefix: \"data-\"\n\t});\n\t// Add a click event handler\n\t$tw.utils.addEventListeners(this.inputDomNode,[\n\t\t{name:\"mousedown\", handlerObject:this, handlerMethod:\"handleMouseDownEvent\"},\n\t\t{name:\"mouseup\",   handlerObject:this, handlerMethod:\"handleMouseUpEvent\"},\n\t\t{name:\"change\",    handlerObject:this, handlerMethod:\"handleChangeEvent\"},\n\t\t{name:\"input\",     handlerObject:this, handlerMethod:\"handleInputEvent\"},\n\t]);\n\t// Insert the label into the DOM and render any children\n\tparent.insertBefore(this.inputDomNode,nextSibling);\n\tthis.domNodes.push(this.inputDomNode);\n};\n\nRangeWidget.prototype.getValue = function() {\n\tvar tiddler = this.wiki.getTiddler(this.tiddlerTitle),\n\t\tfieldName = this.tiddlerField,\n\t\tvalue = this.defaultValue;\n\tif(tiddler) {\n\t\tif(this.tiddlerIndex) {\n\t\t\tvalue = this.wiki.extractTiddlerDataItem(tiddler,this.tiddlerIndex,this.defaultValue);\n\t\t} else {\n\t\t\tif($tw.utils.hop(tiddler.fields,fieldName)) {\n\t\t\t\tvalue = tiddler.fields[fieldName] || \"\";\n\t\t\t} else {\n\t\t\t\tvalue = this.defaultValue;\n\t\t\t}\n\t\t}\n\t}\n\treturn value;\n};\n\nRangeWidget.prototype.getActionVariables = function(options) {\n\toptions = options || {};\n\tvar hasChanged = (this.startValue !== this.inputDomNode.value) ? \"yes\" : \"no\";\n\t// Trigger actions. Use variables = {key:value, key:value ...}\n\t// the \"value\" is needed.\n\treturn $tw.utils.extend({\"actionValue\": this.inputDomNode.value, \"actionValueHasChanged\": hasChanged}, options);\n}\n\n// actionsStart\nRangeWidget.prototype.handleMouseDownEvent = function(event) {\n\tthis.mouseDown = true; // TODO remove once IE is gone.\n\tthis.startValue = this.inputDomNode.value; // TODO remove this line once IE is gone!\n\tthis.handleEvent(event);\n\t// Trigger actions\n\tif(this.actionsMouseDown) {\n\t\tvar variables = this.getActionVariables() // TODO this line will go into the function call below.\n\t\tthis.invokeActionString(this.actionsMouseDown,this,event,variables);\n\t}\n}\n\n// actionsStop\nRangeWidget.prototype.handleMouseUpEvent = function(event) {\n\tthis.mouseDown = false; // TODO remove once IE is gone.\n\tthis.handleEvent(event);\n\t// Trigger actions\n\tif(this.actionsMouseUp) {\n\t\tvar variables = this.getActionVariables()\n\t\tthis.invokeActionString(this.actionsMouseUp,this,event,variables);\n\t}\n\t// TODO remove the following if() once IE is gone!\n\tif ($tw.browser.isIE) {\n\t\tif (this.startValue !== this.inputDomNode.value) {\n\t\t\tthis.handleChangeEvent(event);\n\t\t\tthis.startValue = this.inputDomNode.value;\n\t\t}\n\t}\n}\n\nRangeWidget.prototype.handleChangeEvent = function(event) {\n\tif (this.mouseDown) {  // TODO refactor this function once IE is gone.\n\t\tthis.handleInputEvent(event);\n\t}\n};\n\nRangeWidget.prototype.handleInputEvent = function(event) {\n\tthis.handleEvent(event);\n\t// Trigger actions\n\tif(this.actionsInput) {\n\t\t// \"tiddler\" parameter may be missing. See .execute() below\n\t\tvar variables = this.getActionVariables({\"actionValueHasChanged\": \"yes\"}) // TODO this line will go into the function call below.\n\t\tthis.invokeActionString(this.actionsInput,this,event,variables);\n\t}\n};\n\nRangeWidget.prototype.handleEvent = function(event) {\n\tif(this.getValue() !== this.inputDomNode.value) {\n\t\tif(this.tiddlerIndex) {\n\t\t\tthis.wiki.setText(this.tiddlerTitle,\"\",this.tiddlerIndex,this.inputDomNode.value);\n\t\t} else {\n\t\t\tthis.wiki.setText(this.tiddlerTitle,this.tiddlerField,null,this.inputDomNode.value);\n\t\t}\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nRangeWidget.prototype.execute = function() {\n\t// TODO remove the next 1 lines once IE is gone!\n\tthis.mouseUp = true; // Needed for IE10\n\t// Get the parameters from the attributes\n\tthis.tiddlerTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.tiddlerField = this.getAttribute(\"field\",\"text\");\n\tthis.tiddlerIndex = this.getAttribute(\"index\");\n\tthis.minValue = this.getAttribute(\"min\");\n\tthis.maxValue = this.getAttribute(\"max\");\n\tthis.increment = this.getAttribute(\"increment\");\n\tthis.defaultValue = this.getAttribute(\"default\",\"\");\n\tthis.elementClass = this.getAttribute(\"class\",\"\");\n\tthis.isDisabled = this.getAttribute(\"disabled\",\"no\");\n\t// Actions since 5.1.23\n\t// Next 2 only fire once!\n\tthis.actionsMouseDown = this.getAttribute(\"actionsStart\",\"\");\n\tthis.actionsMouseUp = this.getAttribute(\"actionsStop\",\"\");\n\t// Input fires very often!\n\tthis.actionsInput = this.getAttribute(\"actions\",\"\");\n\t// Make the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nRangeWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif($tw.utils.count(changedAttributes) > 0) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\tvar refreshed = false;\n\t\tif(changedTiddlers[this.tiddlerTitle]) {\n\t\t\tvar value = this.getValue();\n\t\t\tif(this.inputDomNode.value !== value) {\n\t\t\t\tthis.inputDomNode.value = value;\n\t\t\t}\n\t\t\trefreshed = true;\n\t\t}\n\t\treturn this.refreshChildren(changedTiddlers) || refreshed;\n\t}\n};\n\nexports.range = RangeWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/raw.js":{"title":"$:/core/modules/widgets/raw.js","text":"/*\\\ntitle: $:/core/modules/widgets/raw.js\ntype: application/javascript\nmodule-type: widget\n\nRaw widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar RawWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nRawWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nRawWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.execute();\n\tvar div = this.document.createElement(\"div\");\n\tdiv.innerHTML=this.parseTreeNode.html;\n\tparent.insertBefore(div,nextSibling);\n\tthis.domNodes.push(div);\n};\n\n/*\nCompute the internal state of the widget\n*/\nRawWidget.prototype.execute = function() {\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nRawWidget.prototype.refresh = function(changedTiddlers) {\n\treturn false;\n};\n\nexports.raw = RawWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/reveal.js":{"title":"$:/core/modules/widgets/reveal.js","text":"/*\\\ntitle: $:/core/modules/widgets/reveal.js\ntype: application/javascript\nmodule-type: widget\n\nReveal widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar Popup = require(\"$:/core/modules/utils/dom/popup.js\");\n\nvar RevealWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nRevealWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nRevealWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar tag = this.parseTreeNode.isBlock ? \"div\" : \"span\";\n\tif(this.revealTag && $tw.config.htmlUnsafeElements.indexOf(this.revealTag) === -1) {\n\t\ttag = this.revealTag;\n\t}\n\tvar domNode = this.document.createElement(tag);\n\tthis.domNode = domNode;\n\tthis.assignDomNodeClasses();\n\tif(this.style) {\n\t\tdomNode.setAttribute(\"style\",this.style);\n\t}\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tif(!domNode.isTiddlyWikiFakeDom && this.type === \"popup\" && this.isOpen) {\n\t\tthis.positionPopup(domNode);\n\t\t$tw.utils.addClass(domNode,\"tc-popup\"); // Make sure that clicks don't dismiss popups within the revealed content\n\t}\n\tif(!this.isOpen) {\n\t\tdomNode.setAttribute(\"hidden\",\"true\");\n\t}\n\tthis.domNodes.push(domNode);\n};\n\nRevealWidget.prototype.positionPopup = function(domNode) {\n\tdomNode.style.position = \"absolute\";\n\tdomNode.style.zIndex = \"1000\";\n\tvar left,top;\n\tswitch(this.position) {\n\t\tcase \"left\":\n\t\t\tleft = this.popup.left - domNode.offsetWidth;\n\t\t\ttop = this.popup.top;\n\t\t\tbreak;\n\t\tcase \"above\":\n\t\t\tleft = this.popup.left;\n\t\t\ttop = this.popup.top - domNode.offsetHeight;\n\t\t\tbreak;\n\t\tcase \"aboveright\":\n\t\t\tleft = this.popup.left + this.popup.width;\n\t\t\ttop = this.popup.top + this.popup.height - domNode.offsetHeight;\n\t\t\tbreak;\n\t\tcase \"belowright\":\n\t\t\tleft = this.popup.left + this.popup.width;\n\t\t\ttop = this.popup.top + this.popup.height;\n\t\t\tbreak;\n\t\tcase \"right\":\n\t\t\tleft = this.popup.left + this.popup.width;\n\t\t\ttop = this.popup.top;\n\t\t\tbreak;\n\t\tcase \"belowleft\":\n\t\t\tleft = this.popup.left + this.popup.width - domNode.offsetWidth;\n\t\t\ttop = this.popup.top + this.popup.height;\n\t\t\tbreak;\n\t\tcase \"aboveleft\":\n\t\t\tleft = this.popup.left - domNode.offsetWidth;\n\t\t\ttop = this.popup.top - domNode.offsetHeight;\n\t\t\tbreak;\n\t\tdefault: // Below\n\t\t\tleft = this.popup.left;\n\t\t\ttop = this.popup.top + this.popup.height;\n\t\t\tbreak;\n\t}\n\tif(!this.positionAllowNegative) {\n\t\tleft = Math.max(0,left);\n\t\ttop = Math.max(0,top);\n\t}\n\tif (this.popup.absolute) {\n\t\t// Traverse the offsetParent chain and correct the offset to make it relative to the parent node.\n\t\tfor (var offsetParentDomNode = domNode.offsetParent; offsetParentDomNode; offsetParentDomNode = offsetParentDomNode.offsetParent) {\n\t\t\tleft -= offsetParentDomNode.offsetLeft;\n\t\t\ttop -= offsetParentDomNode.offsetTop;\n\t\t}\n\t}\n\tdomNode.style.left = left + \"px\";\n\tdomNode.style.top = top + \"px\";\n};\n\n/*\nCompute the internal state of the widget\n*/\nRevealWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.state = this.getAttribute(\"state\");\n\tthis.revealTag = this.getAttribute(\"tag\");\n\tthis.type = this.getAttribute(\"type\");\n\tthis.text = this.getAttribute(\"text\");\n\tthis.position = this.getAttribute(\"position\");\n\tthis.positionAllowNegative = this.getAttribute(\"positionAllowNegative\") === \"yes\";\n\t// class attribute handled in assignDomNodeClasses()\n\tthis.style = this.getAttribute(\"style\",\"\");\n\tthis[\"default\"] = this.getAttribute(\"default\",\"\");\n\tthis.animate = this.getAttribute(\"animate\",\"no\");\n\tthis.retain = this.getAttribute(\"retain\",\"no\");\n\tthis.openAnimation = this.animate === \"no\" ? undefined : \"open\";\n\tthis.closeAnimation = this.animate === \"no\" ? undefined : \"close\";\n\tthis.updatePopupPosition = this.getAttribute(\"updatePopupPosition\",\"no\") === \"yes\";\n\t// Compute the title of the state tiddler and read it\n\tthis.stateTiddlerTitle = this.state;\n\tthis.stateTitle = this.getAttribute(\"stateTitle\");\n\tthis.stateField = this.getAttribute(\"stateField\");\n\tthis.stateIndex = this.getAttribute(\"stateIndex\");\n\tthis.readState();\n\t// Construct the child widgets\n\tvar childNodes = this.isOpen ? this.parseTreeNode.children : [];\n\tthis.hasChildNodes = this.isOpen;\n\tthis.makeChildWidgets(childNodes);\n};\n\n/*\nRead the state tiddler\n*/\nRevealWidget.prototype.readState = function() {\n\t// Read the information from the state tiddler\n\tvar state,\n\t    defaultState = this[\"default\"];\n\tif(this.stateTitle) {\n\t\tvar stateTitleTiddler = this.wiki.getTiddler(this.stateTitle);\n\t\tif(this.stateField) {\n\t\t\tstate = stateTitleTiddler ? stateTitleTiddler.getFieldString(this.stateField) || defaultState : defaultState;\n\t\t} else if(this.stateIndex) {\n\t\t\tstate = stateTitleTiddler ? this.wiki.extractTiddlerDataItem(this.stateTitle,this.stateIndex) || defaultState : defaultState;\n\t\t} else if(stateTitleTiddler) {\n\t\t\tstate = this.wiki.getTiddlerText(this.stateTitle) || defaultState;\n\t\t} else {\n\t\t\tstate = defaultState;\n\t\t}\n\t} else {\n\t\tstate = this.stateTiddlerTitle ? this.wiki.getTextReference(this.state,this[\"default\"],this.getVariable(\"currentTiddler\")) : this[\"default\"];\n\t}\n\tif(state === null) {\n\t\tstate = this[\"default\"];\n\t}\n\tswitch(this.type) {\n\t\tcase \"popup\":\n\t\t\tthis.readPopupState(state);\n\t\t\tbreak;\n\t\tcase \"match\":\n\t\t\tthis.isOpen = this.text === state;\n\t\t\tbreak;\n\t\tcase \"nomatch\":\n\t\t\tthis.isOpen = this.text !== state;\n\t\t\tbreak;\n\t\tcase \"lt\":\n\t\t\tthis.isOpen = !!(this.compareStateText(state) < 0);\n\t\t\tbreak;\n\t\tcase \"gt\":\n\t\t\tthis.isOpen = !!(this.compareStateText(state) > 0);\n\t\t\tbreak;\n\t\tcase \"lteq\":\n\t\t\tthis.isOpen = !(this.compareStateText(state) > 0);\n\t\t\tbreak;\n\t\tcase \"gteq\":\n\t\t\tthis.isOpen = !(this.compareStateText(state) < 0);\n\t\t\tbreak;\n\t}\n};\n\nRevealWidget.prototype.compareStateText = function(state) {\n\treturn state.localeCompare(this.text,undefined,{numeric: true,sensitivity: \"case\"});\n};\n\nRevealWidget.prototype.readPopupState = function(state) {\n\tthis.popup = Popup.parseCoordinates(state);\n\t// Check if the state matches the location regexp\n\tif(this.popup) {\n\t\t// If so, we're open\n\t\tthis.isOpen = true;\n\t} else {\n\t\t// If not, we're closed\n\t\tthis.isOpen = false;\n\t}\n};\n\nRevealWidget.prototype.assignDomNodeClasses = function() {\n\tvar classes = this.getAttribute(\"class\",\"\").split(\" \");\n\tclasses.push(\"tc-reveal\");\n\tthis.domNode.className = classes.join(\" \");\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nRevealWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.state || changedAttributes.type || changedAttributes.text || changedAttributes.position || changedAttributes.positionAllowNegative || changedAttributes[\"default\"] || changedAttributes.animate || changedAttributes.stateTitle || changedAttributes.stateField || changedAttributes.stateIndex) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\tvar currentlyOpen = this.isOpen;\n\t\tthis.readState();\n\t\tif(this.isOpen !== currentlyOpen) {\n\t\t\tif(this.retain === \"yes\") {\n\t\t\t\tthis.updateState();\n\t\t\t} else {\n\t\t\t\tthis.refreshSelf();\n\t\t\t\treturn true;\n\t\t\t}\n\t\t} else if(this.type === \"popup\" && this.isOpen && this.updatePopupPosition && (changedTiddlers[this.state] || changedTiddlers[this.stateTitle])) {\n\t\t\tthis.positionPopup(this.domNode);\n\t\t}\n\t\tif(changedAttributes.style) {\n\t\t\tthis.domNode.style = this.getAttribute(\"style\",\"\");\n\t\t}\n\t\tif(changedAttributes[\"class\"]) {\n\t\t\tthis.assignDomNodeClasses();\n\t\t}\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\n/*\nCalled by refresh() to dynamically show or hide the content\n*/\nRevealWidget.prototype.updateState = function() {\n\tvar self = this;\n\t// Read the current state\n\tthis.readState();\n\t// Construct the child nodes if needed\n\tvar domNode = this.domNodes[0];\n\tif(this.isOpen && !this.hasChildNodes) {\n\t\tthis.hasChildNodes = true;\n\t\tthis.makeChildWidgets(this.parseTreeNode.children);\n\t\tthis.renderChildren(domNode,null);\n\t}\n\t// Animate our DOM node\n\tif(!domNode.isTiddlyWikiFakeDom && this.type === \"popup\" && this.isOpen) {\n\t\tthis.positionPopup(domNode);\n\t\t$tw.utils.addClass(domNode,\"tc-popup\"); // Make sure that clicks don't dismiss popups within the revealed content\n\n\t}\n\tif(this.isOpen) {\n\t\tdomNode.removeAttribute(\"hidden\");\n        $tw.anim.perform(this.openAnimation,domNode);\n\t} else {\n\t\t$tw.anim.perform(this.closeAnimation,domNode,{callback: function() {\n\t\t\t//make sure that the state hasn't changed during the close animation\n\t\t\tself.readState()\n\t\t\tif(!self.isOpen) {\n\t\t\t\tdomNode.setAttribute(\"hidden\",\"true\");\n\t\t\t}\n\t\t}});\n\t}\n};\n\nexports.reveal = RevealWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/scrollable.js":{"title":"$:/core/modules/widgets/scrollable.js","text":"/*\\\ntitle: $:/core/modules/widgets/scrollable.js\ntype: application/javascript\nmodule-type: widget\n\nScrollable widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar DEBOUNCE_INTERVAL = 100; // Delay after last scroll event before updating the bound tiddler\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar ScrollableWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nScrollableWidget.prototype = new Widget();\n\nScrollableWidget.prototype.cancelScroll = function() {\n\tif(this.idRequestFrame) {\n\t\tthis.cancelAnimationFrame.call(window,this.idRequestFrame);\n\t\tthis.idRequestFrame = null;\n\t}\n};\n\n/*\nHandle a scroll event\n*/\nScrollableWidget.prototype.handleScrollEvent = function(event) {\n\t// Pass the scroll event through if our offsetsize is larger than our scrollsize\n\tif(this.outerDomNode.scrollWidth <= this.outerDomNode.offsetWidth && this.outerDomNode.scrollHeight <= this.outerDomNode.offsetHeight && this.fallthrough === \"yes\") {\n\t\treturn true;\n\t}\n\tvar options = {};\n\tif($tw.utils.hop(event.paramObject,\"animationDuration\")) {\n\t\toptions.animationDuration = event.paramObject.animationDuration;\n\t}\n\tif(event.paramObject && event.paramObject.selector) {\n\t\tthis.scrollSelectorIntoView(null,event.paramObject.selector,null,options);\n\t} else {\n\t\tthis.scrollIntoView(event.target,null,options);\n\t}\n\treturn false; // Handled event\n};\n\n/*\nScroll an element into view\n*/\nScrollableWidget.prototype.scrollIntoView = function(element,callback,options) {\n\tvar duration = $tw.utils.hop(options,\"animationDuration\") ? parseInt(options.animationDuration) : $tw.utils.getAnimationDuration(),\n\t\tsrcWindow = element ? element.ownerDocument.defaultView : window;\n\tthis.cancelScroll();\n\tthis.startTime = Date.now();\n\tvar scrollPosition = {\n\t\tx: this.outerDomNode.scrollLeft,\n\t\ty: this.outerDomNode.scrollTop\n\t};\n\t// Get the client bounds of the element and adjust by the scroll position\n\tvar scrollableBounds = this.outerDomNode.getBoundingClientRect(),\n\t\tclientTargetBounds = element.getBoundingClientRect(),\n\t\tbounds = {\n\t\t\tleft: clientTargetBounds.left + scrollPosition.x - scrollableBounds.left,\n\t\t\ttop: clientTargetBounds.top + scrollPosition.y - scrollableBounds.top,\n\t\t\twidth: clientTargetBounds.width,\n\t\t\theight: clientTargetBounds.height\n\t\t};\n\t// We'll consider the horizontal and vertical scroll directions separately via this function\n\tvar getEndPos = function(targetPos,targetSize,currentPos,currentSize) {\n\t\t\t// If the target is already visible then stay where we are\n\t\t\tif(targetPos >= currentPos && (targetPos + targetSize) <= (currentPos + currentSize)) {\n\t\t\t\treturn currentPos;\n\t\t\t// If the target is above/left of the current view, then scroll to its top/left\n\t\t\t} else if(targetPos <= currentPos) {\n\t\t\t\treturn targetPos;\n\t\t\t// If the target is smaller than the window and the scroll position is too far up, then scroll till the target is at the bottom of the window\n\t\t\t} else if(targetSize < currentSize && currentPos < (targetPos + targetSize - currentSize)) {\n\t\t\t\treturn targetPos + targetSize - currentSize;\n\t\t\t// If the target is big, then just scroll to the top\n\t\t\t} else if(currentPos < targetPos) {\n\t\t\t\treturn targetPos;\n\t\t\t// Otherwise, stay where we are\n\t\t\t} else {\n\t\t\t\treturn currentPos;\n\t\t\t}\n\t\t},\n\t\tendX = getEndPos(bounds.left,bounds.width,scrollPosition.x,this.outerDomNode.offsetWidth),\n\t\tendY = getEndPos(bounds.top,bounds.height,scrollPosition.y,this.outerDomNode.offsetHeight);\n\t// Only scroll if necessary\n\tif(endX !== scrollPosition.x || endY !== scrollPosition.y) {\n\t\tvar self = this,\n\t\t\tdrawFrame;\n\t\tdrawFrame = function () {\n\t\t\tvar t;\n\t\t\tif(duration <= 0) {\n\t\t\t\tt = 1;\n\t\t\t} else {\n\t\t\t\tt = ((Date.now()) - self.startTime) / duration;\n\t\t\t}\n\t\t\tif(t >= 1) {\n\t\t\t\tself.cancelScroll();\n\t\t\t\tt = 1;\n\t\t\t}\n\t\t\tt = $tw.utils.slowInSlowOut(t);\n\t\t\tself.outerDomNode.scrollLeft = scrollPosition.x + (endX - scrollPosition.x) * t;\n\t\t\tself.outerDomNode.scrollTop = scrollPosition.y + (endY - scrollPosition.y) * t;\n\t\t\tif(t < 1) {\n\t\t\t\tself.idRequestFrame = self.requestAnimationFrame.call(srcWindow,drawFrame);\n\t\t\t}\n\t\t};\n\t\tdrawFrame();\n\t}\n};\n\nScrollableWidget.prototype.scrollSelectorIntoView = function(baseElement,selector,callback,options) {\n\tbaseElement = baseElement || document;\n\tvar element = $tw.utils.querySelectorSafe(selector,baseElement);\n\tif(element) {\n\t\tthis.scrollIntoView(element,callback,options);\n\t}\n};\n\n/*\nRender this widget into the DOM\n*/\nScrollableWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\tthis.scaleFactor = 1;\n\tthis.addEventListeners([\n\t\t{type: \"tm-scroll\", handler: \"handleScrollEvent\"}\n\t]);\n\tif($tw.browser) {\n\t\tthis.requestAnimationFrame = window.requestAnimationFrame ||\n\t\t\twindow.webkitRequestAnimationFrame ||\n\t\t\twindow.mozRequestAnimationFrame ||\n\t\t\tfunction(callback) {\n\t\t\t\treturn window.setTimeout(callback, 1000/60);\n\t\t\t};\n\t\tthis.cancelAnimationFrame = window.cancelAnimationFrame ||\n\t\t\twindow.webkitCancelAnimationFrame ||\n\t\t\twindow.webkitCancelRequestAnimationFrame ||\n\t\t\twindow.mozCancelAnimationFrame ||\n\t\t\twindow.mozCancelRequestAnimationFrame ||\n\t\t\tfunction(id) {\n\t\t\t\twindow.clearTimeout(id);\n\t\t\t};\n\t}\n\t// Remember parent\n\tthis.parentDomNode = parent;\n\t// Compute attributes and execute state\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Create elements\n\tthis.outerDomNode = this.document.createElement(\"div\");\n\t$tw.utils.setStyle(this.outerDomNode,[\n\t\t{overflowY: \"auto\"},\n\t\t{overflowX: \"auto\"},\n\t\t{webkitOverflowScrolling: \"touch\"}\n\t]);\n\tthis.innerDomNode = this.document.createElement(\"div\");\n\tthis.outerDomNode.appendChild(this.innerDomNode);\n\t// Assign classes\n\tthis.outerDomNode.className = this[\"class\"] || \"\";\n\t// Insert element\n\tparent.insertBefore(this.outerDomNode,nextSibling);\n\tthis.renderChildren(this.innerDomNode,null);\n\tthis.domNodes.push(this.outerDomNode);\n\t// If the scroll position is bound to a tiddler\n\tif(this.scrollableBind) {\n\t\t// After a delay for rendering, scroll to the bound position\n\t\tthis.updateScrollPositionFromBoundTiddler();\n\t\t// Set up event listener\n\t\tthis.currentListener = this.listenerFunction.bind(this);\n\t\tthis.outerDomNode.addEventListener(\"scroll\", this.currentListener);\n\t}\n};\n\nScrollableWidget.prototype.listenerFunction = function(event) {\n\tself = this;\n\tclearTimeout(this.timeout);\n\tthis.timeout = setTimeout(function() {\n\t\tvar existingTiddler = self.wiki.getTiddler(self.scrollableBind),\n\t\t\tnewTiddlerFields = {\n\t\t\t\ttitle: self.scrollableBind,\n\t\t\t\t\"scroll-left\": self.outerDomNode.scrollLeft.toString(),\n\t\t\t\t\"scroll-top\": self.outerDomNode.scrollTop.toString()\n\t\t\t};\n\t\tif(!existingTiddler || (existingTiddler.fields[\"title\"] !== newTiddlerFields[\"title\"]) || (existingTiddler.fields[\"scroll-left\"] !== newTiddlerFields[\"scroll-left\"] || existingTiddler.fields[\"scroll-top\"] !== newTiddlerFields[\"scroll-top\"])) {\n\t\t\tself.wiki.addTiddler(new $tw.Tiddler(existingTiddler,newTiddlerFields));\n\t\t}\n\t}, DEBOUNCE_INTERVAL);\n}\n\nScrollableWidget.prototype.updateScrollPositionFromBoundTiddler = function() {\n\t// Bail if we're running on the fakedom\n\tif(!this.outerDomNode.scrollTo) {\n\t\treturn;\n\t}\n\tvar tiddler = this.wiki.getTiddler(this.scrollableBind);\n\tif(tiddler) {\n\t\tvar scrollLeftTo = this.outerDomNode.scrollLeft;\n\t\tif(parseFloat(tiddler.fields[\"scroll-left\"]).toString() === tiddler.fields[\"scroll-left\"]) {\n\t\t\tscrollLeftTo = parseFloat(tiddler.fields[\"scroll-left\"]);\n\t\t}\n\t\tvar scrollTopTo = this.outerDomNode.scrollTop;\n\t\tif(parseFloat(tiddler.fields[\"scroll-top\"]).toString() === tiddler.fields[\"scroll-top\"]) {\n\t\t\tscrollTopTo = parseFloat(tiddler.fields[\"scroll-top\"]);\n\t\t}\n\t\tthis.outerDomNode.scrollTo({\n\t\t\ttop: scrollTopTo,\n\t\t\tleft: scrollLeftTo,\n\t\t\tbehavior: \"instant\"\n\t\t})\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nScrollableWidget.prototype.execute = function() {\n\t// Get attributes\n\tthis.scrollableBind = this.getAttribute(\"bind\");\n\tthis.fallthrough = this.getAttribute(\"fallthrough\",\"yes\");\n\tthis[\"class\"] = this.getAttribute(\"class\");\n\t// Make child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nScrollableWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes[\"class\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\t// If the bound tiddler has changed, update the eventListener and update scroll position\n\tif(changedAttributes[\"bind\"]) {\n\t\tif(this.currentListener) {\n\t\t\tthis.outerDomNode.removeEventListener(\"scroll\", this.currentListener, false);\n\t\t}\n\t\tthis.scrollableBind = this.getAttribute(\"bind\");\n\t\tthis.currentListener = this.listenerFunction.bind(this);\n\t\tthis.outerDomNode.addEventListener(\"scroll\", this.currentListener);\n\t}\n\t// Refresh children\n\tvar result = this.refreshChildren(changedTiddlers);\n\t// If the bound tiddler has changed, update scroll position\n\tif(changedAttributes[\"bind\"] || changedTiddlers[this.getAttribute(\"bind\")]) {\n\t\tthis.updateScrollPositionFromBoundTiddler();\n\t}\n\treturn result;\n};\n\nexports.scrollable = ScrollableWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/select.js":{"title":"$:/core/modules/widgets/select.js","text":"/*\\\ntitle: $:/core/modules/widgets/select.js\ntype: application/javascript\nmodule-type: widget\n\nSelect widget:\n\n```\n<$select tiddler=\"MyTiddler\" field=\"text\">\n<$list filter=\"[tag[chapter]]\">\n<option value=<<currentTiddler>>>\n<$view field=\"description\"/>\n</option>\n</$list>\n</$select>\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar SelectWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nSelectWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nSelectWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\t//Create element\n\tvar domNode = this.document.createElement(\"select\");\n\tif(this.selectClass) {\n\t\tdomNode.className = this.selectClass;\n\t}\n\t// Assign data- attributes\n\tthis.assignAttributes(domNode,{\n\t\tsourcePrefix: \"data-\",\n\t\tdestPrefix: \"data-\"\n\t});\n\tif(this.selectMultiple) {\n\t\tdomNode.setAttribute(\"multiple\",\"multiple\");\n\t}\n\tif(this.selectSize) {\n\t\tdomNode.setAttribute(\"size\",this.selectSize);\n\t}\n\tif(this.selectTabindex) {\n\t\tdomNode.setAttribute(\"tabindex\",this.selectTabindex);\n\t}\n\tif(this.selectTooltip) {\n\t\tdomNode.setAttribute(\"title\",this.selectTooltip);\n\t}\n\tthis.parentDomNode.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n\tthis.setSelectValue();\n\tif(this.selectFocus == \"yes\") {\n\t\tthis.getSelectDomNode().focus();\n\t}\n\t$tw.utils.addEventListeners(this.getSelectDomNode(),[\n\t\t{name: \"change\", handlerObject: this, handlerMethod: \"handleChangeEvent\"}\n\t]);\n};\n\n/*\nHandle a change event\n*/\nSelectWidget.prototype.handleChangeEvent = function(event) {\n\t// Get the new value and assign it to the tiddler\n\tif(this.selectMultiple == false) {\n\t\tvar value = this.getSelectDomNode().value;\n\t} else {\n\t\tvar value = this.getSelectValues()\n\t\t\t\tvalue = $tw.utils.stringifyList(value);\n\t}\n\tthis.wiki.setText(this.selectTitle,this.selectField,this.selectIndex,value);\n\t// Trigger actions\n\tif(this.selectActions) {\n\t\tthis.invokeActionString(this.selectActions,this,event);\n\t}\n};\n\n/*\nIf necessary, set the value of the select element to the current value\n*/\nSelectWidget.prototype.setSelectValue = function() {\n\tvar value = this.selectDefault;\n\t// Get the value\n\tif(this.selectIndex) {\n\t\tvalue = this.wiki.extractTiddlerDataItem(this.selectTitle,this.selectIndex,value);\n\t} else {\n\t\tvar tiddler = this.wiki.getTiddler(this.selectTitle);\n\t\tif(tiddler) {\n\t\t\tif(this.selectField === \"text\") {\n\t\t\t\t// Calling getTiddlerText() triggers lazy loading of skinny tiddlers\n\t\t\t\tvalue = this.wiki.getTiddlerText(this.selectTitle);\n\t\t\t} else {\n\t\t\t\tif($tw.utils.hop(tiddler.fields,this.selectField)) {\n\t\t\t\t\tvalue = tiddler.getFieldString(this.selectField);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif(this.selectField === \"title\") {\n\t\t\t\tvalue = this.selectTitle;\n\t\t\t}\n\t\t}\n\t}\n\t// Assign it to the select element if it's different than the current value\n\tif (this.selectMultiple) {\n\t\tvalue = value === undefined ? \"\" : value;\n\t\tvar select = this.getSelectDomNode();\n\t\tvar values = Array.isArray(value) ? value : $tw.utils.parseStringArray(value);\n\t\tfor(var i=0; i < select.children.length; i++){\n\t\t\tselect.children[i].selected = values.indexOf(select.children[i].value) !== -1\n\t\t}\n\t} else {\n\t\tvar domNode = this.getSelectDomNode();\n\t\tif(domNode.value !== value) {\n\t\t\tdomNode.value = value;\n\t\t}\n\t}\n};\n\n/*\nGet the DOM node of the select element\n*/\nSelectWidget.prototype.getSelectDomNode = function() {\n\treturn this.domNodes[0];\n};\n\n// Return an array of the selected opion values\n// select is an HTML select element\nSelectWidget.prototype.getSelectValues = function() {\n\tvar select, result, options, opt;\n\tselect = this.getSelectDomNode();\n\tresult = [];\n\toptions = select && select.options;\n\tfor (var i=0; i<options.length; i++) {\n\t\topt = options[i];\n\t\tif (opt.selected) {\n\t\t\tresult.push(opt.value || opt.text);\n\t\t}\n\t}\n\treturn result;\n}\n\n/*\nCompute the internal state of the widget\n*/\nSelectWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.selectActions = this.getAttribute(\"actions\");\n\tthis.selectTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.selectField = this.getAttribute(\"field\",\"text\");\n\tthis.selectIndex = this.getAttribute(\"index\");\n\tthis.selectClass = this.getAttribute(\"class\");\n\tthis.selectDefault = this.getAttribute(\"default\");\n\tthis.selectMultiple = this.getAttribute(\"multiple\", false);\n\tthis.selectSize = this.getAttribute(\"size\");\n\tthis.selectTabindex = this.getAttribute(\"tabindex\");\n\tthis.selectTooltip = this.getAttribute(\"tooltip\");\n\tthis.selectFocus = this.getAttribute(\"focus\");\n\t// Make the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nSelectWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\t// If we're using a different tiddler/field/index then completely refresh ourselves\n\tif(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.tooltip || changedAttributes.tabindex) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\tif(changedAttributes.class) {\n\t\t\tthis.selectClass = this.getAttribute(\"class\");\n\t\t\tthis.getSelectDomNode().setAttribute(\"class\",this.selectClass); \n\t\t}\n\t\tthis.assignAttributes(this.getSelectDomNode(),{\n\t\t\tchangedAttributes: changedAttributes,\n\t\t\tsourcePrefix: \"data-\",\n\t\t\tdestPrefix: \"data-\"\n\t\t});\n\t\tvar childrenRefreshed = this.refreshChildren(changedTiddlers);\n\t\t// If the target tiddler value has changed, just update setting and refresh the children\n\t\tif(changedTiddlers[this.selectTitle] || childrenRefreshed) {\n\t\t\tthis.setSelectValue();\n\t\t} \n\t\treturn childrenRefreshed;\n\t}\n};\n\nexports.select = SelectWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/setmultiplevariables.js":{"title":"$:/core/modules/widgets/setmultiplevariables.js","text":"/*\\\ntitle: $:/core/modules/widgets/setmultiplevariables.js\ntype: application/javascript\nmodule-type: widget\n\nWidget to set multiple variables at once from a list of names and a list of values\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar SetMultipleVariablesWidget = function(parseTreeNode,options) {\n    this.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nSetMultipleVariablesWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nSetMultipleVariablesWidget.prototype.render = function(parent,nextSibling) {\n    this.parentDomNode = parent;\n    this.computeAttributes();\n    this.execute();\n    this.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nSetMultipleVariablesWidget.prototype.execute = function() {\n    // Setup our variables\n    this.setVariables();\n    // Construct the child widgets\n    this.makeChildWidgets();\n};\n\n\nSetMultipleVariablesWidget.prototype.setVariables = function() {\n    // Set the variables\n    var self = this,\n        filterNames = this.getAttribute(\"$names\",\"\"),\n        filterValues = this.getAttribute(\"$values\",\"\");\n    this.variableNames = [];\n    this.variableValues = [];\n    if(filterNames && filterValues) {\n        this.variableNames = this.wiki.filterTiddlers(filterNames,this);\n        this.variableValues = this.wiki.filterTiddlers(filterValues,this);\n        $tw.utils.each(this.variableNames,function(varname,index) {\n            self.setVariable(varname,self.variableValues[index]);\n        });\n    }\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nSetMultipleVariablesWidget.prototype.refresh = function(changedTiddlers) {\n    var filterNames = this.getAttribute(\"$names\",\"\"),\n        filterValues = this.getAttribute(\"$values\",\"\"),\n        variableNames = this.wiki.filterTiddlers(filterNames,this),\n        variableValues = this.wiki.filterTiddlers(filterValues,this);\n    if(!$tw.utils.isArrayEqual(this.variableNames,variableNames) || !$tw.utils.isArrayEqual(this.variableValues,variableValues)) {\n        this.refreshSelf();\n        return true;\n    }\n    return this.refreshChildren(changedTiddlers);\n};\n\nexports[\"setmultiplevariables\"] = SetMultipleVariablesWidget;\n\n})();\n        ","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/set.js":{"title":"$:/core/modules/widgets/set.js","text":"/*\\\ntitle: $:/core/modules/widgets/set.js\ntype: application/javascript\nmodule-type: widget\n\nSet variable widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar SetWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nSetWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nSetWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nSetWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.setName = this.getAttribute(\"name\",\"currentTiddler\");\n\tthis.setFilter = this.getAttribute(\"filter\");\n\tthis.setSelect = this.getAttribute(\"select\");\n\tthis.setTiddler = this.getAttribute(\"tiddler\");\n\tthis.setSubTiddler = this.getAttribute(\"subtiddler\");\n\tthis.setField = this.getAttribute(\"field\");\n\tthis.setIndex = this.getAttribute(\"index\");\n\tthis.setValue = this.getAttribute(\"value\");\n\tthis.setEmptyValue = this.getAttribute(\"emptyValue\");\n\t// Set context variable\n\tif(this.parseTreeNode.isMacroDefinition) {\n\t\tthis.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,true);\n\t} else if(this.parseTreeNode.isFunctionDefinition) {\n\t\tthis.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,undefined,{isFunctionDefinition: true});\n\t} else if(this.parseTreeNode.isProcedureDefinition) {\n\t\tthis.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,undefined,{isProcedureDefinition: true, configTrimWhiteSpace: this.parseTreeNode.configTrimWhiteSpace});\n\t} else if(this.parseTreeNode.isWidgetDefinition) {\n\t\tthis.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,undefined,{isWidgetDefinition: true, configTrimWhiteSpace: this.parseTreeNode.configTrimWhiteSpace});\n\t} else {\n\t\tthis.setVariable(this.setName,this.getValue());\n\t}\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nGet the value to be assigned\n*/\nSetWidget.prototype.getValue = function() {\n\tvar value = this.setValue;\n\tif(this.setTiddler) {\n\t\tvar tiddler;\n\t\tif(this.setSubTiddler) {\n\t\t\ttiddler = this.wiki.getSubTiddler(this.setTiddler,this.setSubTiddler);\n\t\t} else {\n\t\t\ttiddler = this.wiki.getTiddler(this.setTiddler);\n\t\t}\n\t\tif(!tiddler) {\n\t\t\tvalue = this.setEmptyValue;\n\t\t} else if(this.setField) {\n\t\t\tvalue = tiddler.getFieldString(this.setField) || this.setEmptyValue;\n\t\t} else if(this.setIndex) {\n\t\t\tvalue = this.wiki.extractTiddlerDataItem(this.setTiddler,this.setIndex,this.setEmptyValue);\n\t\t} else {\n\t\t\tvalue = tiddler.fields.text || this.setEmptyValue ;\n\t\t}\n\t} else if(this.setFilter) {\n\t\tvar results = this.wiki.filterTiddlers(this.setFilter,this);\n\t\tif(this.setValue == null) {\n\t\t\tvar select;\n\t\t\tif(this.setSelect) {\n\t\t\t\tselect = parseInt(this.setSelect,10);\n\t\t\t}\n\t\t\tif(select !== undefined) {\n\t\t\t\tvalue = results[select] || \"\";\n\t\t\t} else {\n\t\t\t\tvalue = $tw.utils.stringifyList(results);\n\t\t\t}\n\t\t}\n\t\tif(results.length === 0 && this.setEmptyValue !== undefined) {\n\t\t\tvalue = this.setEmptyValue;\n\t\t}\n\t} else if(!value && this.setEmptyValue) {\n\t\tvalue = this.setEmptyValue;\n\t}\n\treturn value || \"\";\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nSetWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.name || changedAttributes.filter || changedAttributes.select || changedAttributes.tiddler || (this.setTiddler && changedTiddlers[this.setTiddler]) || changedAttributes.field || changedAttributes.index || changedAttributes.value || changedAttributes.emptyValue ||\n\t   (this.setFilter && this.getValue() != this.variables[this.setName].value)) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports.setvariable = SetWidget;\nexports.set = SetWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/slot.js":{"title":"$:/core/modules/widgets/slot.js","text":"/*\\\ntitle: $:/core/modules/widgets/slot.js\ntype: application/javascript\nmodule-type: widget\n\nWidget for definition of slots within transcluded content. The values provided by the translusion are passed to the slot.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget,\n\tTranscludeWidget = require(\"$:/core/modules/widgets/transclude.js\").transclude;\n\nvar SlotWidget = function(parseTreeNode,options) {\n\t// Initialise\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nSlotWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nSlotWidget.prototype.render = function(parent,nextSibling) {\n\t// Call the constructor\n\tWidget.call(this);\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nSlotWidget.prototype.execute = function() {\n\tvar self = this;\n\tthis.slotName = this.getAttribute(\"$name\");\n\tthis.slotDepth = parseInt(this.getAttribute(\"$depth\",\"1\"),10) || 1;\n\t// Find the parent transclusions\n\tvar pointer = this.parentWidget,\n\t\tdepth = this.slotDepth;\n\twhile(pointer) {\n\t\tif(pointer instanceof TranscludeWidget && pointer.hasVisibleSlots()) {\n\t\t\tdepth--;\n\t\t\tif(depth <= 0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tpointer = pointer.parentWidget;\n\t}\n\tvar parseTreeNodes = [{type: \"text\", attributes: {text: {type: \"string\", value: \"Missing slot reference!\"}}}];\n\tif(pointer instanceof TranscludeWidget) {\n\t\t// Get the parse tree nodes comprising the slot contents\n\t\tparseTreeNodes = pointer.getTransclusionSlotFill(this.slotName,this.parseTreeNode.children);\n\t}\n\t// Construct the child widgets\n\tthis.makeChildWidgets(parseTreeNodes);\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nSlotWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes[\"$name\"] || changedAttributes[\"$depth\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.slot = SlotWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/testcase.js":{"title":"$:/core/modules/widgets/testcase.js","text":"/*\\\ntitle: $:/core/modules/widgets/testcase.js\ntype: application/javascript\nmodule-type: widget\n\nWidget to display a test case\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar TestCaseWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nTestCaseWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nTestCaseWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Create container DOM node\n\tvar domNode = this.document.createElement(\"div\");\n\tthis.domNodes.push(domNode);\n\tparent.insertBefore(domNode,nextSibling);\n\t// Render the children into a hidden DOM node\n\tvar parser = {\n\t\ttree: [{\n\t\t\ttype: \"widget\",\n\t\t\tattributes: {},\n\t\t\torderedAttributes: [],\n\t\t\tchildren: this.parseTreeNode.children || []\n\t\t}]\n\t};\n\tthis.contentRoot = this.wiki.makeWidget(parser,{\n\t\tdocument: $tw.fakeDocument,\n\t\tparentWidget: this\n\t});\n\tthis.contentContainer = $tw.fakeDocument.createElement(\"div\");\n\tthis.contentRoot.render(this.contentContainer,null);\n\t// Create a wiki\n\tthis.testcaseWiki = new $tw.Wiki();\n\t// Always load the core plugin\n\tvar loadTiddler = function(title) {\n\t\tvar tiddler = self.wiki.getTiddler(title);\n\t\tif(tiddler) {\n\t\t\tself.testcaseWiki.addTiddler(tiddler);\n\t\t}\n\t}\n\tloadTiddler(\"$:/core\");\n\tloadTiddler(\"$:/plugins/tiddlywiki/codemirror\");\n\t// Load tiddlers from child data widgets\n\tvar tiddlers = [];\n\tthis.findChildrenDataWidgets(this.contentRoot.children,\"data\",function(widget) {\n\t\tArray.prototype.push.apply(tiddlers,widget.readDataTiddlerValues());\n\t});\n\tvar jsonPayload = JSON.stringify(tiddlers);\n\tthis.testcaseWiki.addTiddlers(tiddlers);\n\t// Unpack plugin tiddlers\n\tthis.testcaseWiki.readPluginInfo();\n\tthis.testcaseWiki.registerPluginTiddlers(\"plugin\");\n\tthis.testcaseWiki.unpackPluginTiddlers();\n\tthis.testcaseWiki.addIndexersToWiki();\n\t// Generate a `transclusion` variable that depends on the values of the payload tiddlers so that the template can easily make unique state tiddlers\n\tthis.setVariable(\"transclusion\",$tw.utils.hashString(jsonPayload));\n\t// Generate a `payloadTiddlers` variable that contains the payload in JSON format\n\tthis.setVariable(\"payloadTiddlers\",jsonPayload);\n\t// Only run the tests if the testcase output and expected results were specified, and those tiddlers actually exist in the wiki\n\tvar shouldRunTests = false;\n\tif(this.testcaseTestOutput && this.testcaseWiki.tiddlerExists(this.testcaseTestOutput) && this.testcaseTestExpectedResult && this.testcaseWiki.tiddlerExists(this.testcaseTestExpectedResult)) {\n\t\tshouldRunTests = true;\n\t}\n\t// Render the test rendering if required\n\tif(shouldRunTests) {\n\t\tvar testcaseOutputContainer = $tw.fakeDocument.createElement(\"div\");\n\t\tvar testcaseOutputWidget = this.testcaseWiki.makeTranscludeWidget(this.testcaseTestOutput,{\n\t\t\tdocument: $tw.fakeDocument,\n\t\t\tparseAsInline: false,\n\t\t\tparentWidget: this,\n\t\t\tvariables: {\n\t\t\t\tcurrentTiddler: this.testcaseTestOutput\n\t\t\t}\n\t\t});\n\t\ttestcaseOutputWidget.render(testcaseOutputContainer);\n\t}\n\t// Clear changes queue\n\tthis.testcaseWiki.clearTiddlerEventQueue();\n\t// Run the actions if provided\n\tif(this.testcaseWiki.tiddlerExists(this.testcaseTestActions)) {\n\t\ttestcaseOutputWidget.invokeActionString(this.testcaseWiki.getTiddlerText(this.testcaseTestActions));\n\t\ttestcaseOutputWidget.refresh(this.testcaseWiki.changedTiddlers,testcaseOutputContainer);\n\t}\n\t// Set up the test result variables\n\tvar testResult = \"\",\n\t\toutputHTML = \"\",\n\t\texpectedHTML = \"\";\n\tif(shouldRunTests) {\n\t\toutputHTML = testcaseOutputContainer.children[0].innerHTML;\n\t\texpectedHTML = this.testcaseWiki.getTiddlerText(this.testcaseTestExpectedResult);\n\t\tif(outputHTML === expectedHTML) {\n\t\t\ttestResult = \"pass\";\n\t\t} else {\n\t\t\ttestResult = \"fail\";\n\t\t}\n\t\tthis.setVariable(\"outputHTML\",outputHTML);\n\t\tthis.setVariable(\"expectedHTML\",expectedHTML);\n\t\tthis.setVariable(\"testResult\",testResult);\n\t\tthis.setVariable(\"currentTiddler\",this.testcaseTestOutput);\n\t}\n\t// Don't display anything if testHideIfPass is \"yes\" and the tests have passed\n\tif(this.testcaseHideIfPass === \"yes\" && testResult !== \"fail\") {\n\t\treturn;\n\t}\n\t// Render the page root template of the subwiki\n\tvar rootWidget = this.testcaseWiki.makeTranscludeWidget(this.testcaseTemplate,{\n\t\tdocument: this.document,\n\t\tparseAsInline: false,\n\t\tparentWidget: this\n\t});\n\trootWidget.render(domNode);\n\t// Trap changes in the wiki and refresh the rendering\n\tthis.testcaseWiki.addEventListener(\"change\",function(changes) {\n\t\trootWidget.refresh(changes,domNode);\n\t});\n};\n\n/*\nCompute the internal state of the widget\n*/\nTestCaseWidget.prototype.execute = function() {\n\tthis.testcaseTemplate = this.getAttribute(\"template\",\"$:/core/ui/testcases/DefaultTemplate\");\n\tthis.testcaseTestOutput = this.getAttribute(\"testOutput\");\n\tthis.testcaseTestActions = this.getAttribute(\"testActions\");\n\tthis.testcaseTestExpectedResult = this.getAttribute(\"testExpectedResult\");\n\tthis.testcaseHideIfPass = this.getAttribute(\"testHideIfPass\");\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nTestCaseWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif($tw.utils.count(changedAttributes) > 0) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.contentRoot.refresh(changedTiddlers);\n\t}\n};\n\nexports[\"testcase\"] = TestCaseWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/text.js":{"title":"$:/core/modules/widgets/text.js","text":"/*\\\ntitle: $:/core/modules/widgets/text.js\ntype: application/javascript\nmodule-type: widget\n\nText node widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar TextNodeWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nTextNodeWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nTextNodeWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar text = this.getAttribute(\"text\",this.parseTreeNode.text || \"\");\n\ttext = text.replace(/\\r/mg,\"\");\n\tvar textNode = this.document.createTextNode(text);\n\tparent.insertBefore(textNode,nextSibling);\n\tthis.domNodes.push(textNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nTextNodeWidget.prototype.execute = function() {\n\t// Nothing to do for a text node\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nTextNodeWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.text) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n};\n\nexports.text = TextNodeWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/tiddler.js":{"title":"$:/core/modules/widgets/tiddler.js","text":"/*\\\ntitle: $:/core/modules/widgets/tiddler.js\ntype: application/javascript\nmodule-type: widget\n\nTiddler widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar TiddlerWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nTiddlerWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nTiddlerWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nTiddlerWidget.prototype.execute = function() {\n\tthis.tiddlerState = this.computeTiddlerState();\n\tthis.setVariable(\"currentTiddler\",this.tiddlerState.currentTiddler);\n\tthis.setVariable(\"missingTiddlerClass\",this.tiddlerState.missingTiddlerClass);\n\tthis.setVariable(\"shadowTiddlerClass\",this.tiddlerState.shadowTiddlerClass);\n\tthis.setVariable(\"systemTiddlerClass\",this.tiddlerState.systemTiddlerClass);\n\tthis.setVariable(\"tiddlerTagClasses\",this.tiddlerState.tiddlerTagClasses);\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nCompute the tiddler state flags\n*/\nTiddlerWidget.prototype.computeTiddlerState = function() {\n\t// Get our parameters\n\tthis.tiddlerTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\t// Compute the state\n\tvar state = {\n\t\tcurrentTiddler: this.tiddlerTitle || \"\",\n\t\tmissingTiddlerClass: (this.wiki.tiddlerExists(this.tiddlerTitle) || this.wiki.isShadowTiddler(this.tiddlerTitle)) ? \"tc-tiddler-exists\" : \"tc-tiddler-missing\",\n\t\tshadowTiddlerClass: this.wiki.isShadowTiddler(this.tiddlerTitle) ? \"tc-tiddler-shadow\" : \"\",\n\t\tsystemTiddlerClass: this.wiki.isSystemTiddler(this.tiddlerTitle) ? \"tc-tiddler-system\" : \"\",\n\t\ttiddlerTagClasses: this.getTagClasses()\n\t};\n\t// Compute a simple hash to make it easier to detect changes\n\tstate.hash = state.currentTiddler + state.missingTiddlerClass + state.shadowTiddlerClass + state.systemTiddlerClass + state.tiddlerTagClasses;\n\treturn state;\n};\n\n/*\nCreate a string of CSS classes derived from the tags of the current tiddler\n*/\nTiddlerWidget.prototype.getTagClasses = function() {\n\tvar tiddler = this.wiki.getTiddler(this.tiddlerTitle);\n\tif(tiddler) {\n\t\tvar tags = [];\n\t\t$tw.utils.each(tiddler.fields.tags,function(tag) {\n\t\t\ttags.push(\"tc-tagged-\" + encodeURIComponent(tag));\n\t\t});\n\t\treturn tags.join(\" \");\n\t} else {\n\t\treturn \"\";\n\t}\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nTiddlerWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes(),\n\t\tnewTiddlerState = this.computeTiddlerState();\n\tif(changedAttributes.tiddler || newTiddlerState.hash !== this.tiddlerState.hash) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports.tiddler = TiddlerWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/transclude.js":{"title":"$:/core/modules/widgets/transclude.js","text":"/*\\\ntitle: $:/core/modules/widgets/transclude.js\ntype: application/javascript\nmodule-type: widget\n\nTransclude widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar TranscludeWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nTranscludeWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nTranscludeWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\ttry {\n\t\tthis.renderChildren(parent,nextSibling);\n\t} catch(error) {\n\t\tif(error instanceof $tw.utils.TranscludeRecursionError) {\n\t\t\t// We were infinite looping.\n\t\t\t// We need to try and abort as much of the loop as we can, so we will keep \"throwing\" upward until we find a transclusion that has a different signature.\n\t\t\t// Hopefully that will land us just outside where the loop began. That's where we want to issue an error.\n\t\t\t// Rendering widgets beneath this point may result in a freezing browser if they explode exponentially.\n\t\t\tvar transcludeSignature = this.getVariable(\"transclusion\");\n\t\t\tif(this.getAncestorCount() > $tw.utils.TranscludeRecursionError.MAX_WIDGET_TREE_DEPTH - 50) {\n\t\t\t\t// For the first fifty transcludes we climb up, we simply collect signatures.\n\t\t\t\t// We're assuming that those first 50 will likely include all transcludes involved in the loop.\n\t\t\t\terror.signatures[transcludeSignature] = true;\n\t\t\t} else if(!error.signatures[transcludeSignature]) {\n\t\t\t\t// Now that we're past the first 50, let's look for the first signature that wasn't in the loop. That'll be where we print the error and resume rendering.\n\t\t\t\tthis.children = [this.makeChildWidget({type: \"error\", attributes: {\n\t\t\t\t\t\"$message\": {type: \"string\", value: $tw.language.getString(\"Error/RecursiveTransclusion\")}\n\t\t\t\t}})];\n\t\t\t\tthis.renderChildren(parent,nextSibling);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tthrow error;\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nTranscludeWidget.prototype.execute = function() {\n\t// Get our attributes, string parameters, and slot values into properties of the widget object\n\tthis.collectAttributes();\n\tthis.collectStringParameters();\n\tthis.collectSlotFillParameters();\n\t// Determine whether we're being used in inline or block mode\n\tvar parseAsInline = !this.parseTreeNode.isBlock;\n\tif(this.transcludeMode === \"inline\") {\n\t\tparseAsInline = true;\n\t} else if(this.transcludeMode === \"block\") {\n\t\tparseAsInline = false;\n\t}\n\t// Set 'thisTiddler'\n\tthis.setVariable(\"thisTiddler\",this.transcludeTitle);\n\tvar parseTreeNodes, target;\n\t// Process the transclusion according to the output type\n\tswitch(this.transcludeOutput || \"text/html\") {\n\t\tcase \"text/html\":\n\t\t\t// Return the parse tree nodes of the target\n\t\t\ttarget = this.parseTransclusionTarget(parseAsInline);\n\t\t\tthis.parseAsInline = target.parseAsInline;\n\t\t\tparseTreeNodes = target.parseTreeNodes;\n\t\t\tbreak;\n\t\tcase \"text/raw\":\n\t\t\t// Just return the raw text\n\t\t\ttarget = this.getTransclusionTarget();\n\t\t\tparseTreeNodes = [{type: \"text\", text: target.text}];\n\t\t\tbreak;\n\t\tdefault:\n\t\t\t// \"text/plain\" is the plain text result of wikifying the text\n\t\t\ttarget = this.parseTransclusionTarget(parseAsInline);\n\t\t\tvar widgetNode = this.wiki.makeWidget(target.parser,{\n\t\t\t\tparentWidget: this,\n\t\t\t\tdocument: $tw.fakeDocument\n\t\t\t});\n\t\t\tvar container = $tw.fakeDocument.createElement(\"div\");\n\t\t\twidgetNode.render(container,null);\n\t\t\tparseTreeNodes = [{type: \"text\", text: container.textContent}];\n\t\t\tbreak;\n\t}\n\tthis.sourceText = target.text;\n\tthis.parserType = target.type;\n\t// Set the legacy transclusion context variables only if we're not transcluding a variable\n\tif(!this.transcludeVariable) {\n\t\tvar recursionMarker = this.makeRecursionMarker();\n\t\tthis.setVariable(\"transclusion\",recursionMarker);\n\t}\n\t// Construct the child widgets\n\tthis.makeChildWidgets(parseTreeNodes);\n};\n\n/*\nCollect the attributes we need, in the process determining whether we're being used in legacy mode\n*/\nTranscludeWidget.prototype.collectAttributes = function() {\n\tvar self = this;\n\t// Detect legacy mode\n\tthis.legacyMode = true;\n\t$tw.utils.each(this.attributes,function(value,name) {\n\t\tif(name.charAt(0) === \"$\") {\n\t\t\tself.legacyMode = false;\n\t\t}\n\t});\n\t// Get the attributes for the appropriate mode\n\tif(this.legacyMode) {\n\t\tthis.transcludeTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\t\tthis.transcludeSubTiddler = this.getAttribute(\"subtiddler\");\n\t\tthis.transcludeField = this.getAttribute(\"field\");\n\t\tthis.transcludeIndex = this.getAttribute(\"index\");\n\t\tthis.transcludeMode = this.getAttribute(\"mode\");\n\t\tthis.recursionMarker = this.getAttribute(\"recursionMarker\",\"yes\");\n\t} else {\n\t\tthis.transcludeVariable = this.getAttribute(\"$variable\");\n\t\tthis.transcludeVariableIsFunction = false;\n\t\tthis.transcludeType = this.getAttribute(\"$type\");\n\t\tthis.transcludeOutput = this.getAttribute(\"$output\",\"text/html\");\n\t\tthis.transcludeTitle = this.getAttribute(\"$tiddler\",this.getVariable(\"currentTiddler\"));\n\t\tthis.transcludeSubTiddler = this.getAttribute(\"$subtiddler\");\n\t\tthis.transcludeField = this.getAttribute(\"$field\");\n\t\tthis.transcludeIndex = this.getAttribute(\"$index\");\n\t\tthis.transcludeMode = this.getAttribute(\"$mode\");\n\t\tthis.recursionMarker = this.getAttribute(\"$recursionMarker\",\"yes\");\n\t}\n};\n\n/*\nCollect string parameters\n*/\nTranscludeWidget.prototype.collectStringParameters = function() {\n\tvar self = this;\n\tthis.stringParametersByName = Object.create(null);\n\tif(!this.legacyMode) {\n\t\t$tw.utils.each(this.attributes,function(value,name) {\n\t\t\tif(name.charAt(0) === \"$\") {\n\t\t\t\tif(name.charAt(1) === \"$\") {\n\t\t\t\t\t// Attributes starting $$ represent parameters starting with a single $\n\t\t\t\t\tname = name.slice(1);\n\t\t\t\t} else {\n\t\t\t\t\t// Attributes starting with a single $ are reserved for the widget\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tself.stringParametersByName[name] = value;\n\t\t});\n\t}\n};\n\n/*\nCollect slot value parameters\n*/\nTranscludeWidget.prototype.collectSlotFillParameters = function() {\n\tvar self = this;\n\tthis.slotFillParseTrees = Object.create(null);\n\tif(this.legacyMode) {\n\t\tthis.slotFillParseTrees[\"ts-missing\"] = this.parseTreeNode.children;\n\t} else {\n\t\tthis.slotFillParseTrees[\"ts-raw\"] = this.parseTreeNode.children;\n\t\tvar noFillWidgetsFound = true,\n\t\t\tsearchParseTreeNodes = function(nodes) {\n\t\t\t\t$tw.utils.each(nodes,function(node) {\n\t\t\t\t\tif(node.type === \"fill\") {\n\t\t\t\t\t\tif(node.attributes[\"$name\"] && node.attributes[\"$name\"].type === \"string\") {\n\t\t\t\t\t\t\tvar slotValueName = node.attributes[\"$name\"].value;\n\t\t\t\t\t\t\tself.slotFillParseTrees[slotValueName] = node.children || [];\n\t\t\t\t\t\t}\n\t\t\t\t\t\tnoFillWidgetsFound = false;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsearchParseTreeNodes(node.children);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t};\n\t\tsearchParseTreeNodes(this.parseTreeNode.children);\n\t\tif(noFillWidgetsFound) {\n\t\t\tthis.slotFillParseTrees[\"ts-missing\"] = this.parseTreeNode.children;\n\t\t}\n\t}\n};\n\n/*\nGet transcluded details as an object {text:,type:}\n*/\nTranscludeWidget.prototype.getTransclusionTarget = function() {\n\tvar self = this;\n\tvar text;\n\t// Return the text and type of the target\n\tif(this.hasAttribute(\"$variable\")) {\n\t\tif(this.transcludeVariable) {\n\t\t\t// Transcluding a variable\n\t\t\tvar variableInfo = this.getVariableInfo(this.transcludeVariable,{params: this.getOrderedTransclusionParameters()});\n\t\t\tthis.transcludeVariableIsFunction = variableInfo.srcVariable && variableInfo.srcVariable.isFunctionDefinition;\n\t\t\ttext = variableInfo.text;\n\t\t\tthis.transcludeFunctionResult = text;\n\t\t\treturn {\n\t\t\t\ttext: variableInfo.text,\n\t\t\t\ttype: this.transcludeType\n\t\t\t};\n\t\t}\n\t} else {\n\t\t// Transcluding a text reference\n\t\tvar parserInfo = this.wiki.getTextReferenceParserInfo(\n\t\t\t\t\t\tthis.transcludeTitle,\n\t\t\t\t\t\tthis.transcludeField,\n\t\t\t\t\t\tthis.transcludeIndex,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsubTiddler: this.transcludeSubTiddler,\n\t\t\t\t\t\t\tdefaultType: this.transcludeType\n\t\t\t\t\t\t});\n\t\treturn {\n\t\t\ttext: parserInfo.text,\n\t\t\ttype: parserInfo.type\n\t\t};\n\t}\n};\n\n/*\nGet transcluded parse tree nodes as an object {text:,type:,parseTreeNodes:,parseAsInline:}\n*/\nTranscludeWidget.prototype.parseTransclusionTarget = function(parseAsInline) {\n\tvar self = this;\n\tvar parser;\n\t// Get the parse tree\n\tif(this.hasAttribute(\"$variable\")) {\n\t\tif(this.transcludeVariable) {\n\t\t\t// Transcluding a variable\n\t\t\tvar variableInfo = this.getVariableInfo(this.transcludeVariable,{params: this.getOrderedTransclusionParameters()}),\n\t\t\t\tsrcVariable = variableInfo && variableInfo.srcVariable;\n\t\t\tif(srcVariable && srcVariable.isFunctionDefinition) {\n\t\t\t\tthis.transcludeVariableIsFunction = true;\n\t\t\t\tthis.transcludeFunctionResult = (variableInfo.resultList ? variableInfo.resultList[0] : variableInfo.text) || \"\";\n\t\t\t}\n\t\t\tif(variableInfo.text) {\n\t\t\t\tif(srcVariable && srcVariable.isFunctionDefinition) {\n\t\t\t\t\tparser = {\n\t\t\t\t\t\ttree: [{\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: this.transcludeFunctionResult\n\t\t\t\t\t\t}],\n\t\t\t\t\t\tsource: this.transcludeFunctionResult,\n\t\t\t\t\t\ttype: \"text/vnd.tiddlywiki\"\n\t\t\t\t\t};\n\t\t\t\t\tif(parseAsInline) {\n\t\t\t\t\t\tparser.tree[0] = {\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: this.transcludeFunctionResult\n\t\t\t\t\t\t};\n\t\t\t\t\t} else {\n\t\t\t\t\t\tparser.tree[0] = {\n\t\t\t\t\t\t\ttype: \"element\",\n\t\t\t\t\t\t\ttag: \"p\",\n\t\t\t\t\t\t\tchildren: [{\n\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\ttext: this.transcludeFunctionResult\n\t\t\t\t\t\t\t}]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tvar cacheKey = (parseAsInline ? \"inlineParser\" : \"blockParser\") + (this.transcludeType || \"\");\n\t\t\t\t\tif(variableInfo.isCacheable && srcVariable[cacheKey]) {\n\t\t\t\t\t\tparser = srcVariable[cacheKey];\n\t\t\t\t\t} else {\n\t\t\t\t\t\tparser = this.wiki.parseText(this.transcludeType,variableInfo.text || \"\",{parseAsInline: parseAsInline, configTrimWhiteSpace: srcVariable && srcVariable.configTrimWhiteSpace});\n\t\t\t\t\t\tif(variableInfo.isCacheable) {\n\t\t\t\t\t\t\tsrcVariable[cacheKey] = parser;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(parser) {\n\t\t\t\t\t// Add parameters widget for procedures and custom widgets\n\t\t\t\t\tif(srcVariable && (srcVariable.isProcedureDefinition || srcVariable.isWidgetDefinition)) {\n\t\t\t\t\t\tparser = {\n\t\t\t\t\t\t\ttree: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\ttype: \"parameters\",\n\t\t\t\t\t\t\t\t\tchildren: parser.tree\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\tsource: parser.source,\n\t\t\t\t\t\t\ttype: parser.type\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$tw.utils.each(srcVariable.params,function(param) {\n\t\t\t\t\t\t\tvar name = param.name;\n\t\t\t\t\t\t\t// Parameter names starting with dollar must be escaped to double dollars\n\t\t\t\t\t\t\tif(name.charAt(0) === \"$\") {\n\t\t\t\t\t\t\t\tname = \"$\" + name;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$tw.utils.addAttributeToParseTreeNode(parser.tree[0],name,param[\"default\"])\n\t\t\t\t\t\t});\n\t\t\t\t\t} else if(srcVariable && !srcVariable.isFunctionDefinition) {\n\t\t\t\t\t\t// For macros and ordinary variables, wrap the parse tree in a vars widget assigning the parameters to variables named \"__paramname__\"\n\t\t\t\t\t\tparser = {\n\t\t\t\t\t\t\ttree: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\ttype: \"vars\",\n\t\t\t\t\t\t\t\t\tchildren: parser.tree\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\tsource: parser.source,\n\t\t\t\t\t\t\ttype: parser.type\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$tw.utils.each(variableInfo.params,function(param) {\n\t\t\t\t\t\t\t$tw.utils.addAttributeToParseTreeNode(parser.tree[0],\"__\" + param.name + \"__\",param.value)\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// Transcluding a text reference\n\t\tparser = this.wiki.parseTextReference(\n\t\t\t\t\t\tthis.transcludeTitle,\n\t\t\t\t\t\tthis.transcludeField,\n\t\t\t\t\t\tthis.transcludeIndex,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tparseAsInline: parseAsInline,\n\t\t\t\t\t\t\tsubTiddler: this.transcludeSubTiddler,\n\t\t\t\t\t\t\tdefaultType: this.transcludeType\n\t\t\t\t\t\t});\n\t}\n\t// Return the parse tree\n\treturn {\n\t\tparser: parser,\n\t\tparseTreeNodes: parser ? parser.tree : (this.slotFillParseTrees[\"ts-missing\"] || []),\n\t\tparseAsInline: parseAsInline,\n\t\ttext: parser && parser.source,\n\t\ttype: parser && parser.type\n\t};\n};\n\n/*\nFetch all the string parameters as an ordered array of {name:, value:} where the name is optional\n*/\nTranscludeWidget.prototype.getOrderedTransclusionParameters = function() {\n\tvar result = [];\n\t// Collect the parameters\n\tfor(var name in this.stringParametersByName) {\n\t\tvar value = this.stringParametersByName[name];\n\t\tresult.push({name: name, value: value});\n\t}\n\t// Sort numerical parameter names first\n\tresult.sort(function(a,b) {\n\t\tvar aIsNumeric = !isNaN(a.name),\n\t\t\tbIsNumeric = !isNaN(b.name);\n\t\tif(aIsNumeric && bIsNumeric) {\n\t\t\treturn a.name - b.name;\n\t\t} else if(aIsNumeric) {\n\t\t\treturn -1;\n\t\t} else if(bIsNumeric) {\n\t\t\treturn 1;\n\t\t} else {\n\t\t\treturn a.name === b.name ? 0 : (a.name < b.name ? -1 : 1);\n\t\t}\n\t});\n\t// Remove names from numerical parameters\n\t$tw.utils.each(result,function(param,index) {\n\t\tif(!isNaN(param.name)) {\n\t\t\tdelete param.name;\n\t\t}\n\t});\n\treturn result;\n};\n\n/*\nFetch the value of a parameter\n*/\nTranscludeWidget.prototype.getTransclusionParameter = function(name,index,defaultValue) {\n\tif(name in this.stringParametersByName) {\n\t\treturn this.stringParametersByName[name];\n\t} else {\n\t\tvar name = \"\" + index;\n\t\tif(name in this.stringParametersByName) {\n\t\t\treturn this.stringParametersByName[name];\n\t\t}\n\t}\n\treturn defaultValue;\n};\n\n/*\nGet one of the special parameters to be provided by the parameters widget\n*/\nTranscludeWidget.prototype.getTransclusionMetaParameters = function() {\n\tvar self = this;\n\treturn {\n\t\t\"parseMode\": function() {\n\t\t\treturn self.parseAsInline ? \"inline\" : \"block\";\n\t\t},\n\t\t\"parseTreeNodes\": function() {\n\t\t\treturn JSON.stringify(self.parseTreeNode.children || []);\n\t\t},\n\t\t\"slotFillParseTreeNodes\": function() {\n\t\t\treturn JSON.stringify(self.slotFillParseTrees);\n\t\t},\n\t\t\"params\": function() {\n\t\t\treturn JSON.stringify(self.stringParametersByName);\n\t\t}\n\t};\n};\n\n/*\nFetch the value of a slot\n*/\nTranscludeWidget.prototype.getTransclusionSlotFill = function(name,defaultParseTreeNodes) {\n\tif(name && this.slotFillParseTrees[name] && this.slotFillParseTrees[name].length > 0) {\n\t\treturn this.slotFillParseTrees[name];\n\t} else {\n\t\treturn defaultParseTreeNodes || [];\n\t}\n};\n\n/*\nReturn whether this transclusion should be visible to the slot widget\n*/\nTranscludeWidget.prototype.hasVisibleSlots = function() {\n\treturn this.getAttribute(\"$fillignore\",\"no\") === \"no\";\n}\n\n/*\nCompose a string comprising the title, field and/or index to identify this transclusion for recursion detection\n*/\nTranscludeWidget.prototype.makeRecursionMarker = function() {\n\tvar output = [];\n\toutput.push(\"{\");\n\toutput.push(this.getVariable(\"currentTiddler\",{defaultValue: \"\"}));\n\toutput.push(\"|\");\n\toutput.push(this.transcludeTitle || \"\");\n\toutput.push(\"|\");\n\toutput.push(this.transcludeField || \"\");\n\toutput.push(\"|\");\n\toutput.push(this.transcludeIndex || \"\");\n\toutput.push(\"|\");\n\toutput.push(this.transcludeSubTiddler || \"\");\n\toutput.push(\"}\");\n\treturn output.join(\"\");\n};\n\nTranscludeWidget.prototype.parserNeedsRefresh = function() {\n\t// Doesn't need to consider transcluded variables because a parent variable can't change once a widget has been created\n\tvar parserInfo = this.wiki.getTextReferenceParserInfo(this.transcludeTitle,this.transcludeField,this.transcludeIndex,{subTiddler:this.transcludeSubTiddler});\n\treturn (this.sourceText === undefined || parserInfo.sourceText !== this.sourceText || parserInfo.parserType !== this.parserType)\n};\n\nTranscludeWidget.prototype.functionNeedsRefresh = function() {\n\tvar oldResult = this.transcludeFunctionResult;\n\tvar variableInfo = this.getVariableInfo(this.transcludeVariable,{params: this.getOrderedTransclusionParameters()});\n\tvar newResult = (variableInfo.resultList ? variableInfo.resultList[0] : variableInfo.text) || \"\";\n\treturn oldResult !== newResult;\n}\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nTranscludeWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(($tw.utils.count(changedAttributes) > 0) || (this.transcludeVariableIsFunction && this.functionNeedsRefresh()) || (!this.transcludeVariable && changedTiddlers[this.transcludeTitle] && this.parserNeedsRefresh())) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports.transclude = TranscludeWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/vars.js":{"title":"$:/core/modules/widgets/vars.js","text":"/*\\\ntitle: $:/core/modules/widgets/vars.js\ntype: application/javascript\nmodule-type: widget\n\nThis widget allows multiple variables to be set in one go:\n\n```\n\\define helloworld() Hello world!\n<$vars greeting=\"Hi\" me={{!!title}} sentence=<<helloworld>>>\n  <<greeting>>! I am <<me>> and I say: <<sentence>>\n</$vars>\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar VarsWidget = function(parseTreeNode,options) {\n\t// Initialise\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nVarsWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nVarsWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nVarsWidget.prototype.execute = function() {\n\t// Parse variables\n\tvar self = this;\n\t$tw.utils.each(this.attributes,function(val,key) {\n\t\tif(key.charAt(0) !== \"$\") {\n\t\t\tself.setVariable(key,val);\n\t\t}\n\t});\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nVarsWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif($tw.utils.count(changedAttributes) > 0) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports[\"vars\"] = VarsWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/view.js":{"title":"$:/core/modules/widgets/view.js","text":"/*\\\ntitle: $:/core/modules/widgets/view.js\ntype: application/javascript\nmodule-type: widget\n\nView widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar ViewWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nViewWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nViewWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tif(this.text) {\n\t\tvar textNode = this.document.createTextNode(this.text);\n\t\tparent.insertBefore(textNode,nextSibling);\n\t\tthis.domNodes.push(textNode);\n\t} else {\n\t\tthis.makeChildWidgets();\n\t\tthis.renderChildren(parent,nextSibling);\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nViewWidget.prototype.execute = function() {\n\t// Get parameters from our attributes\n\tthis.viewTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.viewSubtiddler = this.getAttribute(\"subtiddler\");\n\tthis.viewField = this.getAttribute(\"field\",\"text\");\n\tthis.viewIndex = this.getAttribute(\"index\");\n\tthis.viewFormat = this.getAttribute(\"format\",\"text\");\n\tthis.viewTemplate = this.getAttribute(\"template\",\"\");\n\tthis.viewMode = this.getAttribute(\"mode\",\"block\");\n\tswitch(this.viewFormat) {\n\t\tcase \"htmlwikified\":\n\t\t\tthis.text = this.getValueAsHtmlWikified(this.viewMode);\n\t\t\tbreak;\n\t\tcase \"plainwikified\":\n\t\t\tthis.text = this.getValueAsPlainWikified(this.viewMode);\n\t\t\tbreak;\n\t\tcase \"htmlencodedplainwikified\":\n\t\t\tthis.text = this.getValueAsHtmlEncodedPlainWikified(this.viewMode);\n\t\t\tbreak;\n\t\tcase \"htmlencoded\":\n\t\t\tthis.text = this.getValueAsHtmlEncoded();\n\t\t\tbreak;\n\t\tcase \"htmltextencoded\":\n\t\t\tthis.text = this.getValueAsHtmlTextEncoded();\n\t\t\tbreak;\n\t\tcase \"urlencoded\":\n\t\t\tthis.text = this.getValueAsUrlEncoded();\n\t\t\tbreak;\n\t\tcase \"doubleurlencoded\":\n\t\t\tthis.text = this.getValueAsDoubleUrlEncoded();\n\t\t\tbreak;\n\t\tcase \"date\":\n\t\t\tthis.text = this.getValueAsDate(this.viewTemplate);\n\t\t\tbreak;\n\t\tcase \"relativedate\":\n\t\t\tthis.text = this.getValueAsRelativeDate();\n\t\t\tbreak;\n\t\tcase \"stripcomments\":\n\t\t\tthis.text = this.getValueAsStrippedComments();\n\t\t\tbreak;\n\t\tcase \"jsencoded\":\n\t\t\tthis.text = this.getValueAsJsEncoded();\n\t\t\tbreak;\n\t\tdefault: // \"text\"\n\t\t\tthis.text = this.getValueAsText();\n\t\t\tbreak;\n\t}\n};\n\n/*\nThe various formatter functions are baked into this widget for the moment. Eventually they will be replaced by macro functions\n*/\n\n/*\nRetrieve the value of the widget. Options are:\nasString: Optionally return the value as a string\n*/\nViewWidget.prototype.getValue = function(options) {\n\toptions = options || {};\n\tvar value = options.asString ? \"\" : undefined;\n\tif(this.viewIndex) {\n\t\tvalue = this.wiki.extractTiddlerDataItem(this.viewTitle,this.viewIndex);\n\t} else {\n\t\tvar tiddler;\n\t\tif(this.viewSubtiddler) {\n\t\t\ttiddler = this.wiki.getSubTiddler(this.viewTitle,this.viewSubtiddler);\n\t\t} else {\n\t\t\ttiddler = this.wiki.getTiddler(this.viewTitle);\n\t\t}\n\t\tif(tiddler) {\n\t\t\tif(this.viewField === \"text\" && !this.viewSubtiddler) {\n\t\t\t\t// Calling getTiddlerText() triggers lazy loading of skinny tiddlers\n\t\t\t\tvalue = this.wiki.getTiddlerText(this.viewTitle);\n\t\t\t} else {\n\t\t\t\tif($tw.utils.hop(tiddler.fields,this.viewField)) {\n\t\t\t\t\tif(options.asString) {\n\t\t\t\t\t\tvalue = tiddler.getFieldString(this.viewField);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvalue = tiddler.fields[this.viewField];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif(this.viewField === \"title\") {\n\t\t\t\tvalue = this.viewTitle;\n\t\t\t}\n\t\t}\n\t}\n\treturn value;\n};\n\nViewWidget.prototype.getValueAsText = function() {\n\treturn this.getValue({asString: true});\n};\n\nViewWidget.prototype.getValueAsHtmlWikified = function(mode) {\n\treturn this.wiki.renderText(\"text/html\",\"text/vnd.tiddlywiki\",this.getValueAsText(),{\n\t\tparseAsInline: mode !== \"block\",\n\t\tparentWidget: this\n\t});\n};\n\nViewWidget.prototype.getValueAsPlainWikified = function(mode) {\n\treturn this.wiki.renderText(\"text/plain\",\"text/vnd.tiddlywiki\",this.getValueAsText(),{\n\t\tparseAsInline: mode !== \"block\",\n\t\tparentWidget: this\n\t});\n};\n\nViewWidget.prototype.getValueAsHtmlEncodedPlainWikified = function(mode) {\n\treturn $tw.utils.htmlEncode(this.wiki.renderText(\"text/plain\",\"text/vnd.tiddlywiki\",this.getValueAsText(),{\n\t\tparseAsInline: mode !== \"block\",\n\t\tparentWidget: this\n\t}));\n};\n\nViewWidget.prototype.getValueAsHtmlEncoded = function() {\n\treturn $tw.utils.htmlEncode(this.getValueAsText());\n};\n\nViewWidget.prototype.getValueAsHtmlTextEncoded = function() {\n\treturn $tw.utils.htmlTextEncode(this.getValueAsText());\n};\n\nViewWidget.prototype.getValueAsUrlEncoded = function() {\n\treturn $tw.utils.encodeURIComponentExtended(this.getValueAsText());\n};\n\nViewWidget.prototype.getValueAsDoubleUrlEncoded = function() {\n\treturn $tw.utils.encodeURIComponentExtended($tw.utils.encodeURIComponentExtended(this.getValueAsText()));\n};\n\nViewWidget.prototype.getValueAsDate = function(format) {\n\tformat = format || \"YYYY MM DD 0hh:0mm\";\n\tvar value = $tw.utils.parseDate(this.getValue());\n\tif(value && $tw.utils.isDate(value) && value.toString() !== \"Invalid Date\") {\n\t\treturn $tw.utils.formatDateString(value,format);\n\t} else {\n\t\treturn \"\";\n\t}\n};\n\nViewWidget.prototype.getValueAsRelativeDate = function(format) {\n\tvar value = $tw.utils.parseDate(this.getValue());\n\tif(value && $tw.utils.isDate(value) && value.toString() !== \"Invalid Date\") {\n\t\treturn $tw.utils.getRelativeDate((new Date()) - (new Date(value))).description;\n\t} else {\n\t\treturn \"\";\n\t}\n};\n\nViewWidget.prototype.getValueAsStrippedComments = function() {\n\tvar lines = this.getValueAsText().split(\"\\n\"),\n\t\tout = [];\n\tfor(var line=0; line<lines.length; line++) {\n\t\tvar text = lines[line];\n\t\tif(!/^\\s*\\/\\/#/.test(text)) {\n\t\t\tout.push(text);\n\t\t}\n\t}\n\treturn out.join(\"\\n\");\n};\n\nViewWidget.prototype.getValueAsJsEncoded = function() {\n\treturn $tw.utils.stringify(this.getValueAsText());\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nViewWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.template || changedAttributes.format || changedTiddlers[this.viewTitle]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n};\n\nexports.view = ViewWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/widget.js":{"title":"$:/core/modules/widgets/widget.js","text":"/*\\\ntitle: $:/core/modules/widgets/widget.js\ntype: application/javascript\nmodule-type: widget\n\nWidget base class\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nCreate a widget object for a parse tree node\n\tparseTreeNode: reference to the parse tree node to be rendered\n\toptions: see below\nOptions include:\n\twiki: mandatory reference to wiki associated with this render tree\n\tparentWidget: optional reference to a parent renderer node for the context chain\n\tdocument: optional document object to use instead of global document\n*/\nvar Widget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInitialise widget properties. These steps are pulled out of the constructor so that we can reuse them in subclasses\n*/\nWidget.prototype.initialise = function(parseTreeNode,options) {\n\t// Bail if parseTreeNode is undefined, meaning  that the widget constructor was called without any arguments so that it can be subclassed\n\tif(parseTreeNode === undefined) {\n\t\treturn;\n\t}\n\toptions = options || {};\n\t// Save widget info\n\tthis.parseTreeNode = parseTreeNode;\n\tthis.wiki = options.wiki;\n\tthis.parentWidget = options.parentWidget;\n\tthis.variables = Object.create(this.parentWidget ? this.parentWidget.variables : null);\n\tthis.document = options.document;\n\tthis.attributes = {};\n\tthis.children = [];\n\tthis.domNodes = [];\n\tthis.eventListeners = {};\n\t// Hashmap of the widget classes\n\tif(!this.widgetClasses) {\n\t\t// Get widget classes\n\t\tWidget.prototype.widgetClasses = $tw.modules.applyMethods(\"widget\");\n\t\t// Process any subclasses\n\t\t$tw.modules.forEachModuleOfType(\"widget-subclass\",function(title,module) {\n\t\t\tif(module.baseClass) {\n\t\t\t\tvar baseClass = Widget.prototype.widgetClasses[module.baseClass];\n\t\t\t\tif(!baseClass) {\n\t\t\t\t\tthrow \"Module '\" + title + \"' is attemping to extend a non-existent base class '\" + module.baseClass + \"'\";\n\t\t\t\t}\n\t\t\t\tvar subClass = module.constructor;\n\t\t\t\tsubClass.prototype = new baseClass();\n\t\t\t\t$tw.utils.extend(subClass.prototype,module.prototype);\n\t\t\t\tWidget.prototype.widgetClasses[module.name || module.baseClass] = subClass;\n\t\t\t}\n\t\t});\n\t}\n};\n\n/*\nRender this widget into the DOM\n*/\nWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nWidget.prototype.execute = function() {\n\tthis.makeChildWidgets();\n};\n\n/*\nSet the value of a context variable\nname: name of the variable\nvalue: value of the variable\nparams: array of {name:, default:} for each parameter\nisMacroDefinition: true if the variable is set via a \\define macro pragma (and hence should have variable substitution performed)\noptions includes:\n\tisProcedureDefinition: true if the variable is set via a \\procedure pragma (and hence should not have variable substitution performed)\n\tisFunctionDefinition: true if the variable is set via a \\function pragma (and hence should not have variable substitution performed)\n\tisWidgetDefinition: true if the variable is set via a \\widget pragma (and hence should not have variable substitution performed)\n*/\nWidget.prototype.setVariable = function(name,value,params,isMacroDefinition,options) {\n\toptions = options || {};\n\tthis.variables[name] = {\n\t\tvalue: value,\n\t\tparams: params,\n\t\tisMacroDefinition: !!isMacroDefinition,\n\t\tisFunctionDefinition: !!options.isFunctionDefinition,\n\t\tisProcedureDefinition: !!options.isProcedureDefinition,\n\t\tisWidgetDefinition: !!options.isWidgetDefinition,\n\t\tconfigTrimWhiteSpace: !!options.configTrimWhiteSpace\n\t};\n};\n\n/*\nGet the prevailing value of a context variable\nname: name of variable\noptions: see below\nOptions include\n\nparams: array of {name:, value:} for each parameter\ndefaultValue: default value if the variable is not defined\nsource: optional source iterator for evaluating function invocations\nallowSelfAssigned: if true, includes the current widget in the context chain instead of just the parent\n\nReturns an object with the following fields:\n\nparams: array of {name:,value:} or {value:} of parameters to be applied\ntext: text of variable, with parameters properly substituted\nresultList: result of variable evaluation as an array\nsrcVariable: reference to the object defining the variable\n*/\nWidget.prototype.getVariableInfo = function(name,options) {\n\toptions = options || {};\n\tvar self = this,\n\t\tactualParams = options.params || [],\n\t\tvariable;\n\tif(options.allowSelfAssigned) {\n\t\tvariable = this.variables[name];\n\t} else {\n\t\tvariable = this.parentWidget && this.parentWidget.variables[name];\n\t}\n\t// Check for the variable defined in the parent widget (or an ancestor in the prototype chain)\n\tif(variable) {\n\t\tvar originalValue = variable.value,\n\t\t\tvalue = originalValue,\n\t\t\tparams = [],\n\t\t\tresultList = [value];\n\t\t// Only substitute parameter and variable references if this variable was defined with the \\define pragma\n\t\tif(variable.isMacroDefinition) {\n\t\t\tparams = self.resolveVariableParameters(variable.params,actualParams);\n\t\t\t// Substitute any parameters specified in the definition\n\t\t\t$tw.utils.each(params,function(param) {\n\t\t\t\tvalue = $tw.utils.replaceString(value,new RegExp(\"\\\\$\" + $tw.utils.escapeRegExp(param.name) + \"\\\\$\",\"mg\"),param.value);\n\t\t\t});\n\t\t\tvalue = self.substituteVariableReferences(value,options);\n\t\t\tresultList = [value];\n\t\t} else if(variable.isFunctionDefinition) {\n\t\t\t// Function evaluations\n\t\t\tparams = self.resolveVariableParameters(variable.params,actualParams);\n\t\t\tvar variables = options.variables || Object.create(null);\n\t\t\t// Apply default parameter values\n\t\t\t$tw.utils.each(variable.params,function(param,index) {\n\t\t\t\tif(param[\"default\"]) {\n\t\t\t\t\tvariables[param.name] = param[\"default\"];\n\t\t\t\t}\n\t\t\t});\n\t\t\t// Parameters are an array of {value:} or {name:, value:} pairs\n\t\t\t$tw.utils.each(params,function(param) {\n\t\t\t\tvariables[param.name] = param.value;\n\t\t\t});\n\t\t\tresultList = this.wiki.filterTiddlers(value,this.makeFakeWidgetWithVariables(variables),options.source);\n\t\t\tvalue = resultList[0] || \"\";\n\t\t} else {\n\t\t\tparams = variable.params;\n\t\t}\n\t\treturn {\n\t\t\ttext: value,\n\t\t\tparams: params,\n\t\t\tresultList: resultList,\n\t\t\tsrcVariable: variable,\n\t\t\tisCacheable: originalValue === value\n\t\t};\n\t}\n\t// If the variable doesn't exist in the parent widget then look for a macro module\n\tvar text = this.evaluateMacroModule(name,actualParams);\n\tif(text === undefined) {\n\t\ttext = options.defaultValue;\n\t}\n\treturn {\n\t\ttext: text,\n\t\tresultList: [text]\n\t};\n};\n\n/*\nSimplified version of getVariableInfo() that just returns the text\n*/\nWidget.prototype.getVariable = function(name,options) {\n\treturn this.getVariableInfo(name,options).text;\n};\n\n/*\nMaps actual parameters onto formal parameters, returning an array of {name:,value:} objects\nformalParams - Array of {name:,default:} (default value is optional)\nactualParams - Array of string values or {name:,value:} (name is optional)\n*/\nWidget.prototype.resolveVariableParameters = function(formalParams,actualParams) {\n\tformalParams = formalParams || [];\n\tactualParams = actualParams || [];\n\tvar nextAnonParameter = 0, // Next candidate anonymous parameter in macro call\n\t\tparamInfo, paramValue,\n\t\tresults = [];\n\t// Step through each of the parameters in the macro definition\n\tfor(var p=0; p<formalParams.length; p++) {\n\t\t// Check if we've got a macro call parameter with the same name\n\t\tparamInfo = formalParams[p];\n\t\tparamValue = undefined;\n\t\tfor(var m=0; m<actualParams.length; m++) {\n\t\t\tif(typeof actualParams[m] !== \"string\" && actualParams[m].name === paramInfo.name) {\n\t\t\t\tparamValue = actualParams[m].value;\n\t\t\t}\n\t\t}\n\t\t// If not, use the next available anonymous macro call parameter\n\t\twhile(nextAnonParameter < actualParams.length && actualParams[nextAnonParameter].name) {\n\t\t\tnextAnonParameter++;\n\t\t}\n\t\tif(paramValue === undefined && nextAnonParameter < actualParams.length) {\n\t\t\tvar param = actualParams[nextAnonParameter++];\n\t\t\tparamValue = typeof param === \"string\" ? param : param.value;\n\t\t}\n\t\t// If we've still not got a value, use the default, if any\n\t\tparamValue = paramValue || paramInfo[\"default\"] || \"\";\n\t\t// Store the parameter name and value\n\t\tresults.push({name: paramInfo.name, value: paramValue});\n\t}\n\treturn results;\n};\n\nWidget.prototype.substituteVariableReferences = function(text,options) {\n\tvar self = this;\n\treturn (text || \"\").replace(/\\$\\(([^\\)\\$]+)\\)\\$/g,function(match,p1,offset,string) {\n\t\treturn options.variables && options.variables[p1] || (self.getVariable(p1,{defaultValue: \"\"}));\n\t});\n};\n\nWidget.prototype.evaluateMacroModule = function(name,actualParams,defaultValue) {\n\tif($tw.utils.hop($tw.macros,name)) {\n\t\tvar macro = $tw.macros[name],\n\t\t\targs = [];\n\t\tif(macro.params.length > 0) {\n\t\t\tvar nextAnonParameter = 0, // Next candidate anonymous parameter in macro call\n\t\t\t\tparamInfo, paramValue;\n\t\t\t// Step through each of the parameters in the macro definition\n\t\t\tfor(var p=0; p<macro.params.length; p++) {\n\t\t\t\t// Check if we've got a macro call parameter with the same name\n\t\t\t\tparamInfo = macro.params[p];\n\t\t\t\tparamValue = undefined;\n\t\t\t\tfor(var m=0; m<actualParams.length; m++) {\n\t\t\t\t\tif(actualParams[m].name === paramInfo.name) {\n\t\t\t\t\t\tparamValue = actualParams[m].value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// If not, use the next available anonymous macro call parameter\n\t\t\t\twhile(nextAnonParameter < actualParams.length && actualParams[nextAnonParameter].name) {\n\t\t\t\t\tnextAnonParameter++;\n\t\t\t\t}\n\t\t\t\tif(paramValue === undefined && nextAnonParameter < actualParams.length) {\n\t\t\t\t\tparamValue = actualParams[nextAnonParameter++].value;\n\t\t\t\t}\n\t\t\t\t// If we've still not got a value, use the default, if any\n\t\t\t\tparamValue = paramValue || paramInfo[\"default\"] || \"\";\n\t\t\t\t// Save the parameter\n\t\t\t\targs.push(paramValue);\n\t\t\t}\n\t\t}\n\t\telse for(var i=0; i<actualParams.length; ++i) {\n\t\t\targs.push(actualParams[i].value);\n\t\t}\n\t\treturn (macro.run.apply(this,args) || \"\").toString();\n\t} else {\n\t\treturn defaultValue;\n\t}\n};\n\n/*\nCheck whether a given context variable value exists in the parent chain\n*/\nWidget.prototype.hasVariable = function(name,value) {\n\tvar node = this;\n\twhile(node) {\n\t\tif($tw.utils.hop(node.variables,name) && node.variables[name].value === value) {\n\t\t\treturn true;\n\t\t}\n\t\tnode = node.parentWidget;\n\t}\n\treturn false;\n};\n\n/*\nConstruct a qualifying string based on a hash of concatenating the values of a given variable in the parent chain\n*/\nWidget.prototype.getStateQualifier = function(name) {\n\tthis.qualifiers = this.qualifiers || Object.create(null);\n\tname = name || \"transclusion\";\n\tif(this.qualifiers[name]) {\n\t\treturn this.qualifiers[name];\n\t} else {\n\t\tvar output = [],\n\t\t\tnode = this;\n\t\twhile(node && node.parentWidget) {\n\t\t\tif($tw.utils.hop(node.parentWidget.variables,name)) {\n\t\t\t\toutput.push(node.getVariable(name));\n\t\t\t}\n\t\t\tnode = node.parentWidget;\n\t\t}\n\t\tvar value = $tw.utils.hashString(output.join(\"\"));\n\t\tthis.qualifiers[name] = value;\n\t\treturn value;\n\t}\n};\n\n/*\nMake a fake widget with specified variables, suitable for variable lookup in filters\n*/\nWidget.prototype.makeFakeWidgetWithVariables = function(variables) {\n\tvar self = this,\n\t\tvariables = variables || {};\n\treturn {\n\t\tgetVariable: function(name,opts) {\n\t\t\tif($tw.utils.hop(variables,name)) {\n\t\t\t\treturn variables[name];\n\t\t\t} else {\n\t\t\t\topts = opts || {};\n\t\t\t\topts.variables = variables;\n\t\t\t\treturn self.getVariable(name,opts);\n\t\t\t};\n\t\t},\n\t\tgetVariableInfo: function(name,opts) {\n\t\t\tif($tw.utils.hop(variables,name)) {\n\t\t\t\treturn {\n\t\t\t\t\ttext: variables[name]\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\topts = opts || {};\n\t\t\t\topts.variables = $tw.utils.extend({},variables,opts.variables);\n\t\t\t\treturn self.getVariableInfo(name,opts);\n\t\t\t};\n\t\t},\n\t\tmakeFakeWidgetWithVariables: self.makeFakeWidgetWithVariables,\n\t\tresolveVariableParameters: self.resolveVariableParameters,\n\t\twiki: self.wiki\n\t};\n};\n\n/*\nCompute the current values of the attributes of the widget. Returns a hashmap of the names of the attributes that have changed.\nOptions include:\nfilterFn: only include attributes where filterFn(name) returns true\n*/\nWidget.prototype.computeAttributes = function(options) {\n\toptions = options || {};\n\tvar changedAttributes = {},\n\t\tself = this;\n\t$tw.utils.each(this.parseTreeNode.attributes,function(attribute,name) {\n\t\tif(options.filterFn) {\n\t\t\tif(!options.filterFn(name)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tvar value = self.computeAttribute(attribute);\n\t\tif(self.attributes[name] !== value) {\n\t\t\tself.attributes[name] = value;\n\t\t\tchangedAttributes[name] = true;\n\t\t}\n\t});\n\treturn changedAttributes;\n};\n\nWidget.prototype.computeAttribute = function(attribute) {\n\tvar self = this,\n\t\tvalue;\n\tif(attribute.type === \"filtered\") {\n\t\tvalue = this.wiki.filterTiddlers(attribute.filter,this)[0] || \"\";\n\t} else if(attribute.type === \"indirect\") {\n\t\tvalue = this.wiki.getTextReference(attribute.textReference,\"\",this.getVariable(\"currentTiddler\")) || \"\";\n\t} else if(attribute.type === \"macro\") {\n\t\tvar variableInfo = this.getVariableInfo(attribute.value.name,{params: attribute.value.params});\n\t\tvalue = variableInfo.text;\n\t} else if(attribute.type === \"substituted\") {\n\t\tvalue = this.wiki.getSubstitutedText(attribute.rawValue,this) || \"\";\n\t} else { // String attribute\n\t\tvalue = attribute.value;\n\t}\n\treturn value;\n};\n\n/*\nCheck for the presence of an evaluated attribute on the widget. Note that attributes set to a missing variable (ie attr=<<missing>>) will be treated as missing\n*/\nWidget.prototype.hasAttribute = function(name) {\n\treturn $tw.utils.hop(this.attributes,name);\n};\n\n/*\nCheck for the presence of a raw attribute on the widget parse tree node. Note that attributes set to a missing variable (ie attr=<<missing>>) will NOT be treated as missing\n*/\nWidget.prototype.hasParseTreeNodeAttribute = function(name) {\n\treturn $tw.utils.hop(this.parseTreeNode.attributes,name);\n};\n\n/*\nGet the value of an attribute\n*/\nWidget.prototype.getAttribute = function(name,defaultText) {\n\tif($tw.utils.hop(this.attributes,name)) {\n\t\treturn this.attributes[name];\n\t} else {\n\t\treturn defaultText;\n\t}\n};\n\n/*\nAssign the common attributes of the widget to a domNode\noptions include:\nsourcePrefix: prefix of attributes that are to be directly assigned (defaults to the empty string meaning all attributes)\ndestPrefix: prefix to be applied to attribute names that are to be directly assigned (defaults to the emtpy string which means no prefix is added)\nchangedAttributes: hashmap by attribute name of attributes to process (if missing, process all attributes)\nexcludeEventAttributes: ignores attributes whose name would begin with \"on\"\n*/\nWidget.prototype.assignAttributes = function(domNode,options) {\n\toptions = options || {};\n\tvar self = this,\n\t\tchangedAttributes = options.changedAttributes || this.attributes,\n\t\tsourcePrefix = options.sourcePrefix || \"\",\n\t\tdestPrefix = options.destPrefix || \"\",\n\t\tEVENT_ATTRIBUTE_PREFIX = \"on\";\n\tvar assignAttribute = function(name,value) {\n\t\t// Process any CSS custom properties\n\t\tif(name.substr(0,2) === \"--\" && name.length > 2) {\n\t\t\tdomNode.style.setProperty(name,value);\n\t\t\treturn;\n\t\t}\n\t\t// Process any style attributes before considering sourcePrefix and destPrefix\n\t\tif(name.substr(0,6) === \"style.\" && name.length > 6) {\n\t\t\tdomNode.style[$tw.utils.unHyphenateCss(name.substr(6))] = value;\n\t\t\treturn;\n\t\t}\n\t\t// Check if the sourcePrefix is a match\n\t\tif(name.substr(0,sourcePrefix.length) === sourcePrefix) {\n\t\t\tname = destPrefix + name.substr(sourcePrefix.length);\n\t\t} else {\n\t\t\tvalue = undefined;\n\t\t}\n\t\t// Check for excluded attribute names\n\t\tif(options.excludeEventAttributes && name.substr(0,2).toLowerCase() === EVENT_ATTRIBUTE_PREFIX) {\n\t\t\tvalue = undefined;\n\t\t}\n\t\tif(value !== undefined) {\n\t\t\t// Handle the xlink: namespace\n\t\t\tvar namespace = null;\n\t\t\tif(name.substr(0,6) === \"xlink:\" && name.length > 6) {\n\t\t\t\tnamespace = \"http://www.w3.org/1999/xlink\";\n\t\t\t\tname = name.substr(6);\n\t\t\t}\n\t\t\t// Setting certain attributes can cause a DOM error (eg xmlns on the svg element)\n\t\t\ttry {\n\t\t\t\tdomNode.setAttributeNS(namespace,name,value);\n\t\t\t} catch(e) {\n\t\t\t}\n\t\t}\n\t};\n\t// If the parse tree node has the orderedAttributes property then use that order\n\tif(this.parseTreeNode.orderedAttributes) {\n\t\t$tw.utils.each(this.parseTreeNode.orderedAttributes,function(attribute,index) {\n\t\t\tif(attribute.name in changedAttributes) {\n\t\t\t\tassignAttribute(attribute.name,self.getAttribute(attribute.name));\n\t\t\t}\n\t\t});\n\t// Otherwise update each changed attribute irrespective of order\n\t} else {\n\t\t$tw.utils.each(changedAttributes,function(value,name) {\n\t\t\tassignAttribute(name,self.getAttribute(name));\n\t\t});\t\n\t}\n};\n\n/*\nGet the number of ancestor widgets for this widget\n*/\nWidget.prototype.getAncestorCount = function() {\n\tif(this.ancestorCount === undefined) {\n\t\tif(this.parentWidget) {\n\t\t\tthis.ancestorCount = this.parentWidget.getAncestorCount() + 1;\n\t\t} else {\n\t\t\tthis.ancestorCount = 0;\n\t\t}\n\t}\n\treturn this.ancestorCount;\n};\n\n/*\nMake child widgets correspondng to specified parseTreeNodes\n*/\nWidget.prototype.makeChildWidgets = function(parseTreeNodes,options) {\n\toptions = options || {};\n\tthis.children = [];\n\tvar self = this;\n\t// Check for too much recursion\n\tif(this.getAncestorCount() > $tw.utils.TranscludeRecursionError.MAX_WIDGET_TREE_DEPTH) {\n\t\tthrow new $tw.utils.TranscludeRecursionError();\n\t} else {\n\t\t// Create set variable widgets for each variable\n\t\t$tw.utils.each(options.variables,function(value,name) {\n\t\t\tvar setVariableWidget = {\n\t\t\t\ttype: \"set\",\n\t\t\t\tattributes: {\n\t\t\t\t\tname: {type: \"string\", value: name},\n\t\t\t\t\tvalue: {type: \"string\", value: value}\n\t\t\t\t},\n\t\t\t\tchildren: parseTreeNodes\n\t\t\t};\n\t\t\tparseTreeNodes = [setVariableWidget];\n\t\t});\n\t\t// Create the child widgets\n\t\t$tw.utils.each(parseTreeNodes || (this.parseTreeNode && this.parseTreeNode.children),function(childNode) {\n\t\t\tself.children.push(self.makeChildWidget(childNode));\n\t\t});\n\t}\n};\n\n/*\nConstruct the widget object for a parse tree node\noptions include:\n\tvariables: optional hashmap of variables to wrap around the widget\n*/\nWidget.prototype.makeChildWidget = function(parseTreeNode,options) {\n\tvar self = this;\n\toptions = options || {};\n\t// Check whether this node type is defined by a custom widget definition\n\tvar variableDefinitionName = \"$\" + parseTreeNode.type;\n\tif(this.variables[variableDefinitionName]) {\n\t\tvar isOverrideable = function() {\n\t\t\t\t// Widget is overrideable if its name contains a period, or if it is an existing JS widget and we're not in safe mode\n\t\t\t\treturn parseTreeNode.type.indexOf(\".\") !== -1 || (!!self.widgetClasses[parseTreeNode.type] && !$tw.safeMode);\n\t\t\t};\n\t\tif(!parseTreeNode.isNotRemappable && isOverrideable()) { \n\t\t\tvar variableInfo = this.getVariableInfo(variableDefinitionName,{allowSelfAssigned: true});\n\t\t\tif(variableInfo && variableInfo.srcVariable && variableInfo.srcVariable.value && variableInfo.srcVariable.isWidgetDefinition) {\n\t\t\t\tvar newParseTreeNode = {\n\t\t\t\t\ttype: \"transclude\",\n\t\t\t\t\tchildren: parseTreeNode.children,\n\t\t\t\t\tisBlock: parseTreeNode.isBlock\n\t\t\t\t};\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(newParseTreeNode,\"$variable\",variableDefinitionName);\n\t\t\t\t$tw.utils.each(parseTreeNode.attributes,function(attr,name) {\n\t\t\t\t\t// If the attribute starts with a dollar then add an extra dollar so that it doesn't clash with the $xxx attributes of transclude\n\t\t\t\t\tname = name.charAt(0) === \"$\" ? \"$\" + name : name;\n\t\t\t\t\t$tw.utils.addAttributeToParseTreeNode(newParseTreeNode,$tw.utils.extend({},attr,{name: name}));\n\t\t\t\t});\n\t\t\t\tparseTreeNode = newParseTreeNode;\n\t\t\t}\n\t\t}\n\t}\n\t// Get the widget class for this node type\n\tvar WidgetClass = this.widgetClasses[parseTreeNode.type];\n\tif(!WidgetClass) {\n\t\tWidgetClass = this.widgetClasses.text;\n\t\tparseTreeNode = {type: \"text\", text: \"Undefined widget '\" + parseTreeNode.type + \"'\"};\n\t}\n\t// Create set variable widgets for each variable\n\t$tw.utils.each(options.variables,function(value,name) {\n\t\tvar setVariableWidget = {\n\t\t\ttype: \"set\",\n\t\t\tattributes: {\n\t\t\t\tname: {type: \"string\", value: name},\n\t\t\t\tvalue: {type: \"string\", value: value}\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\tparseTreeNode\n\t\t\t]\n\t\t};\n\t\tparseTreeNode = setVariableWidget;\n\t});\n\treturn new WidgetClass(parseTreeNode,{\n\t\twiki: this.wiki,\n\t\tparentWidget: this,\n\t\tdocument: this.document\n\t});\n};\n\n/*\nGet the next sibling of this widget\n*/\nWidget.prototype.nextSibling = function() {\n\tif(this.parentWidget) {\n\t\tvar index = this.parentWidget.children.indexOf(this);\n\t\tif(index !== -1 && index < this.parentWidget.children.length-1) {\n\t\t\treturn this.parentWidget.children[index+1];\n\t\t}\n\t}\n\treturn null;\n};\n\n/*\nGet the previous sibling of this widget\n*/\nWidget.prototype.previousSibling = function() {\n\tif(this.parentWidget) {\n\t\tvar index = this.parentWidget.children.indexOf(this);\n\t\tif(index !== -1 && index > 0) {\n\t\t\treturn this.parentWidget.children[index-1];\n\t\t}\n\t}\n\treturn null;\n};\n\n/*\nRender the children of this widget into the DOM\n*/\nWidget.prototype.renderChildren = function(parent,nextSibling) {\n\tvar children = this.children;\n\tfor(var i = 0; i < children.length; i++) {\n\t\tchildren[i].render(parent,nextSibling);\n\t};\n};\n\n/*\nAdd a list of event listeners from an array [{type:,handler:},...]\n*/\nWidget.prototype.addEventListeners = function(listeners) {\n\tvar self = this;\n\t$tw.utils.each(listeners,function(listenerInfo) {\n\t\tself.addEventListener(listenerInfo.type,listenerInfo.handler);\n\t});\n};\n\n/*\nAdd an event listener\n*/\nWidget.prototype.addEventListener = function(type,handler) {\n\tvar self = this;\n\tif(typeof handler === \"string\") { // The handler is a method name on this widget\n\t\tthis.eventListeners[type] = function(event) {\n\t\t\treturn self[handler].call(self,event);\n\t\t};\n\t} else { // The handler is a function\n\t\tthis.eventListeners[type] = function(event) {\n\t\t\treturn handler.call(self,event);\n\t\t};\n\t}\n};\n\n/*\nDispatch an event to a widget. If the widget doesn't handle the event then it is also dispatched to the parent widget\n*/\nWidget.prototype.dispatchEvent = function(event) {\n\tevent.widget = event.widget || this;\n\t// Dispatch the event if this widget handles it\n\tvar listener = this.eventListeners[event.type];\n\tif(listener) {\n\t\t// Don't propagate the event if the listener returned false\n\t\tif(!listener(event)) {\n\t\t\treturn false;\n\t\t}\n\t}\n\t// Dispatch the event to the parent widget\n\tif(this.parentWidget) {\n\t\treturn this.parentWidget.dispatchEvent(event);\n\t}\n\treturn true;\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nWidget.prototype.refresh = function(changedTiddlers) {\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nRebuild a previously rendered widget\n*/\nWidget.prototype.refreshSelf = function() {\n\tvar nextSibling = this.findNextSiblingDomNode();\n\tthis.removeChildDomNodes();\n\tthis.render(this.parentDomNode,nextSibling);\n};\n\n/*\nRefresh all the children of a widget\n*/\nWidget.prototype.refreshChildren = function(changedTiddlers) {\n\tvar children = this.children,\n\t\trefreshed = false;\n\tfor (var i = 0; i < children.length; i++) {\n\t\trefreshed = children[i].refresh(changedTiddlers) || refreshed;\n\t}\n\treturn refreshed;\n};\n\n/*\nFind the next sibling in the DOM to this widget. This is done by scanning the widget tree through all next siblings and their descendents that share the same parent DOM node\n*/\nWidget.prototype.findNextSiblingDomNode = function(startIndex) {\n\t// Refer to this widget by its index within its parents children\n\tvar parent = this.parentWidget,\n\t\tindex = startIndex !== undefined ? startIndex : parent.children.indexOf(this);\nif(index === -1) {\n\tthrow \"node not found in parents children\";\n}\n\t// Look for a DOM node in the later siblings\n\twhile(++index < parent.children.length) {\n\t\tvar domNode = parent.children[index].findFirstDomNode();\n\t\tif(domNode) {\n\t\t\treturn domNode;\n\t\t}\n\t}\n\t// Go back and look for later siblings of our parent if it has the same parent dom node\n\tvar grandParent = parent.parentWidget;\n\tif(grandParent && parent.parentDomNode === this.parentDomNode) {\n\t\tindex = grandParent.children.indexOf(parent);\n\t\tif(index !== -1) {\n\t\t\treturn parent.findNextSiblingDomNode(index);\n\t\t}\n\t}\n\treturn null;\n};\n\n/*\nFind the first DOM node generated by a widget or its children\n*/\nWidget.prototype.findFirstDomNode = function() {\n\t// Return the first dom node of this widget, if we've got one\n\tif(this.domNodes.length > 0) {\n\t\treturn this.domNodes[0];\n\t}\n\t// Otherwise, recursively call our children\n\tfor(var t=0; t<this.children.length; t++) {\n\t\tvar domNode = this.children[t].findFirstDomNode();\n\t\tif(domNode) {\n\t\t\treturn domNode;\n\t\t}\n\t}\n\treturn null;\n};\n\n/*\nRemove any DOM nodes created by this widget or its children\n*/\nWidget.prototype.removeChildDomNodes = function() {\n\t// If this widget has directly created DOM nodes, delete them and exit. This assumes that any child widgets are contained within the created DOM nodes, which would normally be the case\n\tif(this.domNodes.length > 0) {\n\t\t$tw.utils.each(this.domNodes,function(domNode) {\n\t\t\tdomNode.parentNode.removeChild(domNode);\n\t\t});\n\t\tthis.domNodes = [];\n\t} else {\n\t\t// Otherwise, ask the child widgets to delete their DOM nodes\n\t\t$tw.utils.each(this.children,function(childWidget) {\n\t\t\tchildWidget.removeChildDomNodes();\n\t\t});\n\t}\n};\n\n/*\nInvoke the action widgets that are descendents of the current widget.\n*/\nWidget.prototype.invokeActions = function(triggeringWidget,event) {\n\tvar handled = false;\n\t// For each child widget\n\tfor(var t=0; t<this.children.length; t++) {\n\t\tvar child = this.children[t],\n\t\t\tchildIsActionWidget = !!child.invokeAction,\n\t\t\tactionRefreshPolicy = child.getVariable(\"tv-action-refresh-policy\"); // Default is \"once\"\n\t\t// Refresh the child if required\n\t\tif(childIsActionWidget || actionRefreshPolicy === \"always\") {\n\t\t\tchild.refreshSelf();\n\t\t}\n\t\t// Invoke the child if it is an action widget\n\t\tif(childIsActionWidget) {\n\t\t\tif(child.invokeAction(triggeringWidget,event)) {\n\t\t\t\thandled = true;\n\t\t\t}\n\t\t}\n\t\t// Propagate through through the child if it permits it\n\t\tif(child.allowActionPropagation() && child.invokeActions(triggeringWidget,event)) {\n\t\t\thandled = true;\n\t\t}\n\t}\n\treturn handled;\n};\n\n/*\nInvoke the action widgets defined in a string\n*/\nWidget.prototype.invokeActionString = function(actions,triggeringWidget,event,variables) {\n\tactions = actions || \"\";\n\tvar parser = this.wiki.parseText(\"text/vnd.tiddlywiki\",actions,{\n\t\t\tparentWidget: this,\n\t\t\tdocument: this.document\n\t\t}),\n\t\twidgetNode = this.wiki.makeWidget(parser,{\n\t\t\tparentWidget: this,\n\t\t\tdocument: this.document,\n\t\t\tvariables: variables\n\t\t});\n\tvar container = this.document.createElement(\"div\");\n\twidgetNode.render(container,null);\n\treturn widgetNode.invokeActions(this,event);\n};\n\n/*\nExecute action tiddlers by tag\n*/\nWidget.prototype.invokeActionsByTag = function(tag,event,variables) {\n\tvar self = this;\n\t$tw.utils.each(self.wiki.filterTiddlers(\"[all[shadows+tiddlers]tag[\" + tag + \"]!has[draft.of]]\"),function(title) {\n\t\tself.invokeActionString(self.wiki.getTiddlerText(title),self,event,variables);\n\t});\n};\n\nWidget.prototype.allowActionPropagation = function() {\n\treturn true;\n};\n\n/*\nFind child <$data> widgets recursively. The tag name allows aliased versions of the widget to be found too\n*/\nWidget.prototype.findChildrenDataWidgets = function(children,tag,callback) {\n\tvar self = this;\n\t$tw.utils.each(children,function(child) {\n\t\tif(child.dataWidgetTag === tag) {\n\t\t\tcallback(child);\n\t\t}\n\t\tif(child.children) {\n\t\t\tself.findChildrenDataWidgets(child.children,tag,callback);\n\t\t}\n\t});\n};\n\n/*\nEvaluate a variable with parameters. This is a static convenience method that attempts to evaluate a variable as a function, returning an array of strings\n*/\nWidget.evaluateVariable  = function(widget,name,options) {\n\tvar result;\n\tif(widget.getVariableInfo) {\n\t\tvar variableInfo = widget.getVariableInfo(name,options);\n\t\tresult = variableInfo.resultList || [variableInfo.text];\n\t} else {\n\t\tresult = [widget.getVariable(name)];\n\t}\n\treturn result;\n};\n\nexports.widget = Widget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/widgets/wikify.js":{"title":"$:/core/modules/widgets/wikify.js","text":"/*\\\ntitle: $:/core/modules/widgets/wikify.js\ntype: application/javascript\nmodule-type: widget\n\nWidget to wikify text into a variable\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar WikifyWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nWikifyWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nWikifyWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nWikifyWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.wikifyName = this.getAttribute(\"name\");\n\tthis.wikifyText = this.getAttribute(\"text\");\n\tthis.wikifyType = this.getAttribute(\"type\");\n\tthis.wikifyMode = this.getAttribute(\"mode\",\"block\");\n\tthis.wikifyOutput = this.getAttribute(\"output\",\"text\");\n\t// Create the parse tree\n\tthis.wikifyParser = this.wiki.parseText(this.wikifyType,this.wikifyText,{\n\t\t\tparseAsInline: this.wikifyMode === \"inline\"\n\t\t});\n\t// Create the widget tree \n\tthis.wikifyWidgetNode = this.wiki.makeWidget(this.wikifyParser,{\n\t\t\tdocument: $tw.fakeDocument,\n\t\t\tparentWidget: this\n\t\t});\n\t// Render the widget tree to the container\n\tthis.wikifyContainer = $tw.fakeDocument.createElement(\"div\");\n\tthis.wikifyWidgetNode.render(this.wikifyContainer,null);\n\tthis.wikifyResult = this.getResult();\n\t// Set context variable\n\tthis.setVariable(this.wikifyName,this.wikifyResult);\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nReturn the result string\n*/\nWikifyWidget.prototype.getResult = function() {\n\tvar result;\n\tswitch(this.wikifyOutput) {\n\t\tcase \"text\":\n\t\t\tresult = this.wikifyContainer.textContent;\n\t\t\tbreak;\n\t\tcase \"formattedtext\":\n\t\t\tresult = this.wikifyContainer.formattedTextContent;\n\t\t\tbreak;\n\t\tcase \"html\":\n\t\t\tresult = this.wikifyContainer.innerHTML;\n\t\t\tbreak;\n\t\tcase \"parsetree\":\n\t\t\tresult = JSON.stringify(this.wikifyParser.tree,0,$tw.config.preferences.jsonSpaces);\n\t\t\tbreak;\n\t\tcase \"widgettree\":\n\t\t\tresult = JSON.stringify(this.getWidgetTree(),0,$tw.config.preferences.jsonSpaces);\n\t\t\tbreak;\n\t}\n\treturn result;\n};\n\n/*\nReturn a string of the widget tree\n*/\nWikifyWidget.prototype.getWidgetTree = function() {\n\tvar copyNode = function(widgetNode,resultNode) {\n\t\t\tvar type = widgetNode.parseTreeNode.type;\n\t\t\tresultNode.type = type;\n\t\t\tswitch(type) {\n\t\t\t\tcase \"element\":\n\t\t\t\t\tresultNode.tag = widgetNode.parseTreeNode.tag;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"text\":\n\t\t\t\t\tresultNode.text = widgetNode.parseTreeNode.text;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif(Object.keys(widgetNode.attributes || {}).length > 0) {\n\t\t\t\tresultNode.attributes = {};\n\t\t\t\t$tw.utils.each(widgetNode.attributes,function(attr,attrName) {\n\t\t\t\t\tresultNode.attributes[attrName] = widgetNode.getAttribute(attrName);\n\t\t\t\t});\n\t\t\t}\n\t\t\tif(Object.keys(widgetNode.children || {}).length > 0) {\n\t\t\t\tresultNode.children = [];\n\t\t\t\t$tw.utils.each(widgetNode.children,function(widgetChildNode) {\n\t\t\t\t\tvar node = {};\n\t\t\t\t\tresultNode.children.push(node);\n\t\t\t\t\tcopyNode(widgetChildNode,node);\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\tresults = {};\n\tcopyNode(this.wikifyWidgetNode,results);\n\treturn results;\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nWikifyWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\t// Refresh ourselves entirely if any of our attributes have changed\n\tif(changedAttributes.name || changedAttributes.text || changedAttributes.type || changedAttributes.mode || changedAttributes.output) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\t// Refresh the widget tree\n\t\tif(this.wikifyWidgetNode.refresh(changedTiddlers)) {\n\t\t\t// Check if there was any change\n\t\t\tvar result = this.getResult();\n\t\t\tif(result !== this.wikifyResult) {\n\t\t\t\t// If so, save the change\n\t\t\t\tthis.wikifyResult = result;\n\t\t\t\tthis.setVariable(this.wikifyName,this.wikifyResult);\n\t\t\t\t// Refresh each of our child widgets\n\t\t\t\t$tw.utils.each(this.children,function(childWidget) {\n\t\t\t\t\tchildWidget.refreshSelf();\n\t\t\t\t});\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\t// Just refresh the children\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports.wikify = WikifyWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/core/modules/wiki-bulkops.js":{"title":"$:/core/modules/wiki-bulkops.js","text":"/*\\\ntitle: $:/core/modules/wiki-bulkops.js\ntype: application/javascript\nmodule-type: wikimethod\n\nBulk tiddler operations such as rename.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nRename a tiddler, and relink any tags or lists that reference it.\n*/\nfunction renameTiddler(fromTitle,toTitle,options) {\n\tfromTitle = (fromTitle || \"\").trim();\n\ttoTitle = (toTitle || \"\").trim();\n\toptions = options || {};\n\tif(fromTitle && toTitle && fromTitle !== toTitle) {\n\t\t// Rename the tiddler itself\n\t\tvar oldTiddler = this.getTiddler(fromTitle),\n\t\t\tnewTiddler = new $tw.Tiddler(oldTiddler,{title: toTitle},this.getModificationFields());\n\t\tnewTiddler = $tw.hooks.invokeHook(\"th-renaming-tiddler\",newTiddler,oldTiddler);\n\t\tthis.addTiddler(newTiddler);\n\t\tthis.deleteTiddler(fromTitle);\n\t\t// Rename any tags or lists that reference it\n\t\tthis.relinkTiddler(fromTitle,toTitle,options)\n\t}\n}\n\n/*\nRelink any tags or lists that reference a given tiddler\n*/\nfunction relinkTiddler(fromTitle,toTitle,options) {\n\tvar self = this;\n\tfromTitle = (fromTitle || \"\").trim();\n\ttoTitle = (toTitle || \"\").trim();\n\toptions = options || {};\n\tif(fromTitle && toTitle && fromTitle !== toTitle) {\n\t\tthis.each(function(tiddler,title) {\n\t\t\tvar type = tiddler.fields.type || \"\";\n\t\t\t// Don't touch plugins or JavaScript modules\n\t\t\tif(!tiddler.fields[\"plugin-type\"] && type !== \"application/javascript\") {\n\t\t\t\tvar tags = tiddler.fields.tags ? tiddler.fields.tags.slice(0) : undefined,\n\t\t\t\t\tlist = tiddler.fields.list ? tiddler.fields.list.slice(0) : undefined,\n\t\t\t\t\tisModified = false,\n\t\t\t\t\tprocessList = function(listField) {\n\t\t\t\t\t\tif(listField && listField.indexOf(fromTitle) !== -1) {\n\t\t\t\t\t\t\t// Remove any existing instances of the toTitle\n\t\t\t\t\t\t\tvar p = listField.indexOf(toTitle);\n\t\t\t\t\t\t\twhile(p !== -1) {\n\t\t\t\t\t\t\t\tlistField.splice(p,1);\n\t\t\t\t\t\t\t\tp = listField.indexOf(toTitle);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// Replace the fromTitle with toTitle\n\t\t\t\t\t\t\t$tw.utils.each(listField,function (title,index) {\n\t\t\t\t\t\t\t\tif(title === fromTitle) {\n\t\t\t\t\t\t\t\t\tlistField[index] = toTitle;\n\t\t\t\t\t\t\t\t\tisModified = true;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\tif(!options.dontRenameInTags) {\n\t\t\t\t\t// Rename tags\n\t\t\t\t\tprocessList(tags);\n\t\t\t\t}\n\t\t\t\tif(!options.dontRenameInLists) {\n\t\t\t\t\t// Rename lists\n\t\t\t\t\tprocessList(list);\n\t\t\t\t}\n\t\t\t\tif(isModified) {\n\t\t\t\t\tvar newTiddler = new $tw.Tiddler(tiddler,{tags: tags, list: list},self.getModificationFields())\n\t\t\t\t\tnewTiddler = $tw.hooks.invokeHook(\"th-relinking-tiddler\",newTiddler,tiddler);\n\t\t\t\t\tself.addTiddler(newTiddler);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n};\n\nexports.renameTiddler = renameTiddler;\nexports.relinkTiddler = relinkTiddler;\n\n})();\n","type":"application/javascript","module-type":"wikimethod"},"$:/core/modules/wiki.js":{"title":"$:/core/modules/wiki.js","text":"/*\\\ntitle: $:/core/modules/wiki.js\ntype: application/javascript\nmodule-type: wikimethod\n\nExtension methods for the $tw.Wiki object\n\nAdds the following properties to the wiki object:\n\n* `eventListeners` is a hashmap by type of arrays of listener functions\n* `changedTiddlers` is a hashmap describing changes to named tiddlers since wiki change events were last dispatched. Each entry is a hashmap containing two fields:\n\tmodified: true/false\n\tdeleted: true/false\n* `changeCount` is a hashmap by tiddler title containing a numerical index that starts at zero and is incremented each time a tiddler is created changed or deleted\n* `caches` is a hashmap by tiddler title containing a further hashmap of named cache objects. Caches are automatically cleared when a tiddler is modified or deleted\n* `globalCache` is a hashmap by cache name of cache objects that are cleared whenever any tiddler change occurs\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nvar USER_NAME_TITLE = \"$:/status/UserName\",\n\tTIMESTAMP_DISABLE_TITLE = \"$:/config/TimestampDisable\";\n\n/*\nAdd available indexers to this wiki\n*/\nexports.addIndexersToWiki = function() {\n\tvar self = this;\n\t$tw.utils.each($tw.modules.applyMethods(\"indexer\"),function(Indexer,name) {\n\t\tself.addIndexer(new Indexer(self),name);\n\t});\n};\n\n/*\nGet the value of a text reference. Text references can have any of these forms:\n\t<tiddlertitle>\n\t<tiddlertitle>!!<fieldname>\n\t!!<fieldname> - specifies a field of the current tiddlers\n\t<tiddlertitle>##<index>\n*/\nexports.getTextReference = function(textRef,defaultText,currTiddlerTitle) {\n\tvar tr = $tw.utils.parseTextReference(textRef),\n\t\ttitle = tr.title || currTiddlerTitle;\n\tif(tr.field) {\n\t\tvar tiddler = this.getTiddler(title);\n\t\tif(tr.field === \"title\") { // Special case so we can return the title of a non-existent tiddler\n\t\t\treturn title || defaultText;\n\t\t} else if(tiddler && $tw.utils.hop(tiddler.fields,tr.field)) {\n\t\t\treturn tiddler.getFieldString(tr.field);\n\t\t} else {\n\t\t\treturn defaultText;\n\t\t}\n\t} else if(tr.index) {\n\t\treturn this.extractTiddlerDataItem(title,tr.index,defaultText);\n\t} else {\n\t\treturn this.getTiddlerText(title,defaultText);\n\t}\n};\n\nexports.setTextReference = function(textRef,value,currTiddlerTitle) {\n\tvar tr = $tw.utils.parseTextReference(textRef),\n\t\ttitle = tr.title || currTiddlerTitle;\n\tthis.setText(title,tr.field,tr.index,value);\n};\n\nexports.setText = function(title,field,index,value,options) {\n\toptions = options || {};\n\tvar creationFields = options.suppressTimestamp ? {} : this.getCreationFields(),\n\t\tmodificationFields = options.suppressTimestamp ? {} : this.getModificationFields();\n\t// Check if it is a reference to a tiddler field\n\tif(index) {\n\t\tvar data = this.getTiddlerData(title,Object.create(null));\n\t\tif(value !== undefined) {\n\t\t\tdata[index] = value;\n\t\t} else {\n\t\t\tdelete data[index];\n\t\t}\n\t\tthis.setTiddlerData(title,data,{},{suppressTimestamp: options.suppressTimestamp});\n\t} else {\n\t\tvar tiddler = this.getTiddler(title),\n\t\t\tfields = {title: title};\n\t\tfields[field || \"text\"] = value;\n\t\tthis.addTiddler(new $tw.Tiddler(creationFields,tiddler,fields,modificationFields));\n\t}\n};\n\nexports.deleteTextReference = function(textRef,currTiddlerTitle) {\n\tvar tr = $tw.utils.parseTextReference(textRef),\n\t\ttitle,tiddler,fields;\n\t// Check if it is a reference to a tiddler\n\tif(tr.title && !tr.field) {\n\t\tthis.deleteTiddler(tr.title);\n\t// Else check for a field reference\n\t} else if(tr.field) {\n\t\ttitle = tr.title || currTiddlerTitle;\n\t\ttiddler = this.getTiddler(title);\n\t\tif(tiddler && $tw.utils.hop(tiddler.fields,tr.field)) {\n\t\t\tfields = Object.create(null);\n\t\t\tfields[tr.field] = undefined;\n\t\t\tthis.addTiddler(new $tw.Tiddler(tiddler,fields,this.getModificationFields()));\n\t\t}\n\t}\n};\n\nexports.addEventListener = function(type,listener) {\n\tthis.eventListeners = this.eventListeners || {};\n\tthis.eventListeners[type] = this.eventListeners[type]  || [];\n\tthis.eventListeners[type].push(listener);\n};\n\nexports.removeEventListener = function(type,listener) {\n\tvar listeners = this.eventListeners[type];\n\tif(listeners) {\n\t\tvar p = listeners.indexOf(listener);\n\t\tif(p !== -1) {\n\t\t\tlisteners.splice(p,1);\n\t\t}\n\t}\n};\n\nexports.dispatchEvent = function(type /*, args */) {\n\tvar args = Array.prototype.slice.call(arguments,1),\n\t\tlisteners = this.eventListeners[type];\n\tif(listeners) {\n\t\tfor(var p=0; p<listeners.length; p++) {\n\t\t\tvar listener = listeners[p];\n\t\t\tlistener.apply(listener,args);\n\t\t}\n\t}\n};\n\n/*\nCauses a tiddler to be marked as changed, incrementing the change count, and triggers event handlers.\nThis method should be called after the changes it describes have been made to the wiki.tiddlers[] array.\n\ttitle: Title of tiddler\n\tisDeleted: defaults to false (meaning the tiddler has been created or modified),\n\t\ttrue if the tiddler has been deleted\n*/\nexports.enqueueTiddlerEvent = function(title,isDeleted) {\n\t// Record the touch in the list of changed tiddlers\n\tthis.changedTiddlers = this.changedTiddlers || Object.create(null);\n\tthis.changedTiddlers[title] = this.changedTiddlers[title] || Object.create(null);\n\tthis.changedTiddlers[title][isDeleted ? \"deleted\" : \"modified\"] = true;\n\t// Increment the change count\n\tthis.changeCount = this.changeCount || Object.create(null);\n\tif($tw.utils.hop(this.changeCount,title)) {\n\t\tthis.changeCount[title]++;\n\t} else {\n\t\tthis.changeCount[title] = 1;\n\t}\n\t// Trigger events\n\tthis.eventListeners = this.eventListeners || {};\n\tif(!this.eventsTriggered) {\n\t\tvar self = this;\n\t\t$tw.utils.nextTick(function() {\n\t\t\tvar changes = self.changedTiddlers;\n\t\t\tself.changedTiddlers = Object.create(null);\n\t\t\tself.eventsTriggered = false;\n\t\t\tif($tw.utils.count(changes) > 0) {\n\t\t\t\tself.dispatchEvent(\"change\",changes);\n\t\t\t}\n\t\t});\n\t\tthis.eventsTriggered = true;\n\t}\n};\n\nexports.getSizeOfTiddlerEventQueue = function() {\n\treturn $tw.utils.count(this.changedTiddlers);\n};\n\nexports.clearTiddlerEventQueue = function() {\n\tthis.changedTiddlers = Object.create(null);\n\tthis.changeCount = Object.create(null);\n};\n\nexports.getChangeCount = function(title) {\n\tthis.changeCount = this.changeCount || Object.create(null);\n\tif($tw.utils.hop(this.changeCount,title)) {\n\t\treturn this.changeCount[title];\n\t} else {\n\t\treturn 0;\n\t}\n};\n\n/*\nGenerate an unused title from the specified base\noptions.prefix must be a string\n*/\nexports.generateNewTitle = function(baseTitle,options) {\n\toptions = options || {};\n\tvar title = baseTitle,\n\t\ttemplate = options.template || \"\",\n\t\t// test if .startCount is a positive integer. If not set to 0\n\t\tc = (parseInt(options.startCount,10) > 0) ? parseInt(options.startCount,10) : 0,\n\t\tprefix = (typeof(options.prefix) === \"string\") ? options.prefix : \" \";\n\n\tif (template) {\n\t\t// \"count\" is important to avoid an endless loop in while(...)!!\n\t\ttemplate = (/\\$count:?(\\d+)?\\$/i.test(template)) ? template : template + \"$count$\";\n\t\t// .formatTitleString() expects strings as input\n\t\ttitle = $tw.utils.formatTitleString(template,{\"base\":baseTitle,\"separator\":prefix,\"counter\":c+\"\"});\n\t\twhile(this.tiddlerExists(title) || this.isShadowTiddler(title) || this.findDraft(title)) {\n\t\t\ttitle = $tw.utils.formatTitleString(template,{\"base\":baseTitle,\"separator\":prefix,\"counter\":(++c)+\"\"});\n\t\t}\n\t} else {\n\t\tif (c > 0) {\n\t\t\ttitle = baseTitle + prefix + c;\n\t\t}\n\t\twhile(this.tiddlerExists(title) || this.isShadowTiddler(title) || this.findDraft(title)) {\n\t\t\ttitle = baseTitle + prefix + (++c);\n\t\t}\n\t}\n\treturn title;\n};\n\nexports.isSystemTiddler = function(title) {\n\treturn title && title.indexOf(\"$:/\") === 0;\n};\n\nexports.isTemporaryTiddler = function(title) {\n\treturn title && title.indexOf(\"$:/temp/\") === 0;\n};\n\nexports.isVolatileTiddler = function(title) {\n\treturn title && title.indexOf(\"$:/temp/volatile/\") === 0;\n};\n\nexports.isImageTiddler = function(title) {\n\tvar tiddler = this.getTiddler(title);\n\tif(tiddler) {\n\t\tvar contentTypeInfo = $tw.config.contentTypeInfo[tiddler.fields.type || \"text/vnd.tiddlywiki\"];\n\t\treturn !!contentTypeInfo && contentTypeInfo.flags.indexOf(\"image\") !== -1;\n\t} else {\n\t\treturn null;\n\t}\n};\n\nexports.isBinaryTiddler = function(title) {\n\tvar tiddler = this.getTiddler(title);\n\tif(tiddler) {\n\t\tvar contentTypeInfo = $tw.config.contentTypeInfo[tiddler.fields.type || \"text/vnd.tiddlywiki\"];\n\t\treturn !!contentTypeInfo && contentTypeInfo.encoding === \"base64\";\n\t} else {\n\t\treturn null;\n\t}\n};\n\n/*\nLike addTiddler() except it will silently reject any plugin tiddlers that are older than the currently loaded version. Returns true if the tiddler was imported\n*/\nexports.importTiddler = function(tiddler) {\n\tvar existingTiddler = this.getTiddler(tiddler.fields.title);\n\t// Check if we're dealing with a plugin\n\tif(tiddler && tiddler.hasField(\"plugin-type\") && tiddler.hasField(\"version\") && existingTiddler && existingTiddler.hasField(\"plugin-type\") && existingTiddler.hasField(\"version\")) {\n\t\t// Reject the incoming plugin if it is older\n\t\tif(!$tw.utils.checkVersions(tiddler.fields.version,existingTiddler.fields.version)) {\n\t\t\treturn false;\n\t\t}\n\t}\n\t// Fall through to adding the tiddler\n\tthis.addTiddler(tiddler);\n\treturn true;\n};\n\n/*\nReturn a hashmap of the fields that should be set when a tiddler is created\n*/\nexports.getCreationFields = function() {\n\tif(this.getTiddlerText(TIMESTAMP_DISABLE_TITLE,\"\").toLowerCase() !== \"yes\") {\n\t\tvar fields = {\n\t\t\t\tcreated: new Date()\n\t\t\t},\n\t\t\tcreator = this.getTiddlerText(USER_NAME_TITLE);\n\t\tif(creator) {\n\t\t\tfields.creator = creator;\n\t\t}\n\t\treturn fields;\n\t} else {\n\t\treturn {};\n\t}\n};\n\n/*\nReturn a hashmap of the fields that should be set when a tiddler is modified\n*/\nexports.getModificationFields = function() {\n\tif(this.getTiddlerText(TIMESTAMP_DISABLE_TITLE,\"\").toLowerCase() !== \"yes\") {\n\t\tvar fields = Object.create(null),\n\t\t\tmodifier = this.getTiddlerText(USER_NAME_TITLE);\n\t\tfields.modified = new Date();\n\t\tif(modifier) {\n\t\t\tfields.modifier = modifier;\n\t\t}\n\t\treturn fields;\n\t} else {\n\t\treturn {};\n\t}\n};\n\n/*\nReturn a sorted array of tiddler titles.  Options include:\nsortField: field to sort by\nexcludeTag: tag to exclude\nincludeSystem: whether to include system tiddlers (defaults to false)\n*/\nexports.getTiddlers = function(options) {\n\toptions = options || Object.create(null);\n\tvar self = this,\n\t\tsortField = options.sortField || \"title\",\n\t\ttiddlers = [], t, titles = [];\n\tthis.each(function(tiddler,title) {\n\t\tif(options.includeSystem || !self.isSystemTiddler(title)) {\n\t\t\tif(!options.excludeTag || !tiddler.hasTag(options.excludeTag)) {\n\t\t\t\ttiddlers.push(tiddler);\n\t\t\t}\n\t\t}\n\t});\n\ttiddlers.sort(function(a,b) {\n\t\tvar aa = a.fields[sortField].toLowerCase() || \"\",\n\t\t\tbb = b.fields[sortField].toLowerCase() || \"\";\n\t\tif(aa < bb) {\n\t\t\treturn -1;\n\t\t} else {\n\t\t\tif(aa > bb) {\n\t\t\t\treturn 1;\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n\tfor(t=0; t<tiddlers.length; t++) {\n\t\ttitles.push(tiddlers[t].fields.title);\n\t}\n\treturn titles;\n};\n\nexports.countTiddlers = function(excludeTag) {\n\tvar tiddlers = this.getTiddlers({excludeTag: excludeTag});\n\treturn $tw.utils.count(tiddlers);\n};\n\n/*\nReturns a function iterator(callback) that iterates through the specified titles, and invokes the callback with callback(tiddler,title)\n*/\nexports.makeTiddlerIterator = function(titles) {\n\tvar self = this;\n\tif(!$tw.utils.isArray(titles)) {\n\t\ttitles = Object.keys(titles);\n\t} else {\n\t\ttitles = titles.slice(0);\n\t}\n\treturn function(callback) {\n\t\ttitles.forEach(function(title) {\n\t\t\tcallback(self.getTiddler(title),title);\n\t\t});\n\t};\n};\n\n/*\nSort an array of tiddler titles by a specified field\n\ttitles: array of titles (sorted in place)\n\tsortField: name of field to sort by\n\tisDescending: true if the sort should be descending\n\tisCaseSensitive: true if the sort should consider upper and lower case letters to be different\n*/\nexports.sortTiddlers = function(titles,sortField,isDescending,isCaseSensitive,isNumeric,isAlphaNumeric) {\n\tvar self = this;\n\tif(sortField === \"title\") {\n\t\tif(!isNumeric && !isAlphaNumeric) {\n\t\t\tif(isCaseSensitive) {\n\t\t\t\tif(isDescending) {\n\t\t\t\t\ttitles.sort(function(a,b) {\n\t\t\t\t\t\treturn b.localeCompare(a);\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\ttitles.sort(function(a,b) {\n\t\t\t\t\t\treturn a.localeCompare(b);\n\t\t\t\t\t});\n\t\t\t\t}\t\n\t\t\t} else {\n\t\t\t\tif(isDescending) {\n\t\t\t\t\ttitles.sort(function(a,b) {\n\t\t\t\t\t\treturn b.toLowerCase().localeCompare(a.toLowerCase());\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\ttitles.sort(function(a,b) {\n\t\t\t\t\t\treturn a.toLowerCase().localeCompare(b.toLowerCase());\n\t\t\t\t\t});\n\t\t\t\t}\t\n\t\t\t}\n\t\t} else {\n\t\t\ttitles.sort(function(a,b) {\n\t\t\t\tvar x,y;\n\t\t\t\tif(isNumeric) {\n\t\t\t\t\tx = Number(a);\n\t\t\t\t\ty = Number(b);\n\t\t\t\t\tif(isNaN(x)) {\n\t\t\t\t\t\tif(isNaN(y)) {\n\t\t\t\t\t\t\t// If neither value is a number then fall through to a textual comparison\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn isDescending ? -1 : 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif(isNaN(y)) {\n\t\t\t\t\t\t\treturn isDescending ? 1 : -1;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn isDescending ? y - x :  x - y;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(isAlphaNumeric) {\n\t\t\t\t\treturn isDescending ? b.localeCompare(a,undefined,{numeric: true,sensitivity: \"base\"}) : a.localeCompare(b,undefined,{numeric: true,sensitivity: \"base\"});\n\t\t\t\t}\n\t\t\t\tif(!isCaseSensitive) {\n\t\t\t\t\ta = a.toLowerCase();\n\t\t\t\t\tb = b.toLowerCase();\n\t\t\t\t}\n\t\t\t\treturn isDescending ? b.localeCompare(a) : a.localeCompare(b);\n\t\t\t});\n\t\t}\n\t} else {\n\t\ttitles.sort(function(a,b) {\n\t\t\tvar x,y;\n\t\t\tif(sortField !== \"title\") {\n\t\t\t\tvar tiddlerA = self.getTiddler(a),\n\t\t\t\t\ttiddlerB = self.getTiddler(b);\n\t\t\t\tif(tiddlerA) {\n\t\t\t\t\ta = tiddlerA.fields[sortField] || \"\";\n\t\t\t\t} else {\n\t\t\t\t\ta = \"\";\n\t\t\t\t}\n\t\t\t\tif(tiddlerB) {\n\t\t\t\t\tb = tiddlerB.fields[sortField] || \"\";\n\t\t\t\t} else {\n\t\t\t\t\tb = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(isNumeric) {\n\t\t\t\tx = Number(a);\n\t\t\t\ty = Number(b);\n\t\t\t\tif(isNaN(x)) {\n\t\t\t\t\tif(isNaN(y)) {\n\t\t\t\t\t\t// If neither value is a number then fall through to a textual comparison\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn isDescending ? -1 : 1;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif(isNaN(y)) {\n\t\t\t\t\t\treturn isDescending ? 1 : -1;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn isDescending ? y - x :  x - y;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(Object.prototype.toString.call(a) === \"[object Date]\" && Object.prototype.toString.call(b) === \"[object Date]\") {\n\t\t\t\treturn isDescending ? b - a : a - b;\n\t\t\t}\n\t\t\ta = String(a);\n\t\t\tb = String(b);\n\t\t\tif(isAlphaNumeric) {\n\t\t\t\treturn isDescending ? b.localeCompare(a,undefined,{numeric: true,sensitivity: \"base\"}) : a.localeCompare(b,undefined,{numeric: true,sensitivity: \"base\"});\n\t\t\t}\n\t\t\tif(!isCaseSensitive) {\n\t\t\t\ta = a.toLowerCase();\n\t\t\t\tb = b.toLowerCase();\n\t\t\t}\n\t\t\treturn isDescending ? b.localeCompare(a) : a.localeCompare(b);\n\t\t});\n\t}\n};\n\n/*\nFor every tiddler invoke a callback(title,tiddler) with `this` set to the wiki object. Options include:\nsortField: field to sort by\nexcludeTag: tag to exclude\nincludeSystem: whether to include system tiddlers (defaults to false)\n*/\nexports.forEachTiddler = function(/* [options,]callback */) {\n\tvar arg = 0,\n\t\toptions = arguments.length >= 2 ? arguments[arg++] : {},\n\t\tcallback = arguments[arg++],\n\t\ttitles = this.getTiddlers(options),\n\t\tt, tiddler;\n\tfor(t=0; t<titles.length; t++) {\n\t\ttiddler = this.getTiddler(titles[t]);\n\t\tif(tiddler) {\n\t\t\tcallback.call(this,tiddler.fields.title,tiddler);\n\t\t}\n\t}\n};\n\n/*\nReturn an array of tiddler titles that are directly linked within the given parse tree\n */\nexports.extractLinks = function(parseTreeRoot) {\n\t// Count up the links\n\tvar links = [],\n\t\tcheckParseTree = function(parseTree) {\n\t\t\tfor(var t=0; t<parseTree.length; t++) {\n\t\t\t\tvar parseTreeNode = parseTree[t];\n\t\t\t\tif(parseTreeNode.type === \"link\" && parseTreeNode.attributes.to && parseTreeNode.attributes.to.type === \"string\") {\n\t\t\t\t\tvar value = parseTreeNode.attributes.to.value;\n\t\t\t\t\tif(links.indexOf(value) === -1) {\n\t\t\t\t\t\tlinks.push(value);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(parseTreeNode.children) {\n\t\t\t\t\tcheckParseTree(parseTreeNode.children);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\tcheckParseTree(parseTreeRoot);\n\treturn links;\n};\n\n/*\nReturn an array of tiddler titles that are directly linked from the specified tiddler\n*/\nexports.getTiddlerLinks = function(title) {\n\tvar self = this;\n\t// We'll cache the links so they only get computed if the tiddler changes\n\treturn this.getCacheForTiddler(title,\"links\",function() {\n\t\t// Parse the tiddler\n\t\tvar parser = self.parseTiddler(title);\n\t\tif(parser) {\n\t\t\treturn self.extractLinks(parser.tree);\n\t\t}\n\t\treturn [];\n\t});\n};\n\n/*\nReturn an array of tiddler titles that link to the specified tiddler\n*/\nexports.getTiddlerBacklinks = function(targetTitle) {\n\tvar self = this,\n\t\tbackIndexer = this.getIndexer(\"BackIndexer\"),\n\t\tbacklinks = backIndexer && backIndexer.subIndexers.link.lookup(targetTitle);\n\n\tif(!backlinks) {\n\t\tbacklinks = [];\n\t\tthis.forEachTiddler(function(title,tiddler) {\n\t\t\tvar links = self.getTiddlerLinks(title);\n\t\t\tif(links.indexOf(targetTitle) !== -1) {\n\t\t\t\tbacklinks.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn backlinks;\n};\n\n\n/*\nReturn an array of tiddler titles that are directly transcluded within the given parse tree. `title` is the tiddler being parsed, we will ignore its self-referential transclusions, only return\n */\nexports.extractTranscludes = function(parseTreeRoot, title) {\n\t// Count up the transcludes\n\tvar transcludes = [],\n\t\tcheckParseTree = function(parseTree, parentNode) {\n\t\t\tfor(var t=0; t<parseTree.length; t++) {\n\t\t\t\tvar parseTreeNode = parseTree[t];\n\t\t\t\tif(parseTreeNode.type === \"transclude\") {\n\t\t\t\t\tif(parseTreeNode.attributes.$tiddler) {\n\t\t\t\t\t\tif(parseTreeNode.attributes.$tiddler.type === \"string\") {\n\t\t\t\t\t\t\tvar value;\n\t\t\t\t\t\t\t// if it is Transclusion with Templates like `{{Index||$:/core/ui/TagTemplate}}`, the `$tiddler` will point to the template. We need to find the actual target tiddler from parent node\n\t\t\t\t\t\t\tif(parentNode && parentNode.type === \"tiddler\" && parentNode.attributes.tiddler && parentNode.attributes.tiddler.type === \"string\") {\n\t\t\t\t\t\t\t\t// Empty value (like `{{!!field}}`) means self-referential transclusion.\n\t\t\t\t\t\t\t\tvalue = parentNode.attributes.tiddler.value || title;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tvalue = parseTreeNode.attributes.$tiddler.value;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if(parseTreeNode.attributes.tiddler) {\n\t\t\t\t\t\tif (parseTreeNode.attributes.tiddler.type === \"string\") {\n\t\t\t\t\t\t\t// Old transclude widget usage\n\t\t\t\t\t\t\tvalue = parseTreeNode.attributes.tiddler.value;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if(parseTreeNode.attributes.$field && parseTreeNode.attributes.$field.type === \"string\") {\n\t\t\t\t\t\t// Empty value (like `<$transclude $field='created'/>`) means self-referential transclusion. \n\t\t\t\t\t\tvalue = title;\n\t\t\t\t\t} else if(parseTreeNode.attributes.field && parseTreeNode.attributes.field.type === \"string\") {\n\t\t\t\t\t\t// Old usage with Empty value (like `<$transclude field='created'/>`)\n\t\t\t\t\t\tvalue = title;\n\t\t\t\t\t}\n\t\t\t\t\t// Deduplicate the result.\n\t\t\t\t\tif(value && transcludes.indexOf(value) === -1) {\n\t\t\t\t\t\t$tw.utils.pushTop(transcludes,value);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(parseTreeNode.children) {\n\t\t\t\t\tcheckParseTree(parseTreeNode.children,parseTreeNode);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\tcheckParseTree(parseTreeRoot);\n\treturn transcludes;\n};\n\n\n/*\nReturn an array of tiddler titles that are transcluded from the specified tiddler\n*/\nexports.getTiddlerTranscludes = function(title) {\n\tvar self = this;\n\t// We'll cache the transcludes so they only get computed if the tiddler changes\n\treturn this.getCacheForTiddler(title,\"transcludes\",function() {\n\t\t// Parse the tiddler\n\t\tvar parser = self.parseTiddler(title);\n\t\tif(parser) {\n\t\t\t// this will ignore self-referential transclusions from `title`\n\t\t\treturn self.extractTranscludes(parser.tree,title);\n\t\t}\n\t\treturn [];\n\t});\n};\n\n/*\nReturn an array of tiddler titles that transclude to the specified tiddler\n*/\nexports.getTiddlerBacktranscludes = function(targetTitle) {\n\tvar self = this,\n\t\tbackIndexer = this.getIndexer(\"BackIndexer\"),\n\t\tbacktranscludes = backIndexer && backIndexer.subIndexers.transclude.lookup(targetTitle);\n\n\tif(!backtranscludes) {\n\t\tbacktranscludes = [];\n\t}\n\treturn backtranscludes;\n};\n\n/*\nReturn a hashmap of tiddler titles that are referenced but not defined. Each value is the number of times the missing tiddler is referenced\n*/\nexports.getMissingTitles = function() {\n\tvar self = this,\n\t\tmissing = [];\n// We should cache the missing tiddler list, even if we recreate it every time any tiddler is modified\n\tthis.forEachTiddler(function(title,tiddler) {\n\t\tvar links = self.getTiddlerLinks(title);\n\t\t$tw.utils.each(links,function(link) {\n\t\t\tif((!self.tiddlerExists(link) && !self.isShadowTiddler(link)) && missing.indexOf(link) === -1) {\n\t\t\t\tmissing.push(link);\n\t\t\t}\n\t\t});\n\t});\n\treturn missing;\n};\n\nexports.getOrphanTitles = function() {\n\tvar self = this,\n\t\torphans = this.getTiddlers();\n\tthis.forEachTiddler(function(title,tiddler) {\n\t\tvar links = self.getTiddlerLinks(title);\n\t\t$tw.utils.each(links,function(link) {\n\t\t\tvar p = orphans.indexOf(link);\n\t\t\tif(p !== -1) {\n\t\t\t\torphans.splice(p,1);\n\t\t\t}\n\t\t});\n\t});\n\treturn orphans; // Todo\n};\n\n/*\nRetrieves a list of the tiddler titles that are tagged with a given tag\n*/\nexports.getTiddlersWithTag = function(tag) {\n\t// Try to use the indexer\n\tvar self = this,\n\t\ttagIndexer = this.getIndexer(\"TagIndexer\"),\n\t\tresults = tagIndexer && tagIndexer.subIndexers[3].lookup(tag);\n\tif(!results) {\n\t\t// If not available, perform a manual scan\n\t\tresults = this.getGlobalCache(\"taglist-\" + tag,function() {\n\t\t\tvar tagmap = self.getTagMap();\n\t\t\treturn self.sortByList(tagmap[tag],tag);\n\t\t});\n\t}\n\treturn results;\n};\n\n/*\nGet a hashmap by tag of arrays of tiddler titles\n*/\nexports.getTagMap = function() {\n\tvar self = this;\n\treturn this.getGlobalCache(\"tagmap\",function() {\n\t\tvar tags = Object.create(null),\n\t\t\tstoreTags = function(tagArray,title) {\n\t\t\t\tif(tagArray) {\n\t\t\t\t\tfor(var index=0; index<tagArray.length; index++) {\n\t\t\t\t\t\tvar tag = tagArray[index];\n\t\t\t\t\t\tif($tw.utils.hop(tags,tag)) {\n\t\t\t\t\t\t\ttags[tag].push(title);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttags[tag] = [title];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\ttitle, tiddler;\n\t\t// Collect up all the tags\n\t\tself.eachShadow(function(tiddler,title) {\n\t\t\tif(!self.tiddlerExists(title)) {\n\t\t\t\ttiddler = self.getTiddler(title);\n\t\t\t\tstoreTags(tiddler.fields.tags,title);\n\t\t\t}\n\t\t});\n\t\tself.each(function(tiddler,title) {\n\t\t\tstoreTags(tiddler.fields.tags,title);\n\t\t});\n\t\treturn tags;\n\t});\n};\n\n/*\nLookup a given tiddler and return a list of all the tiddlers that include it in the specified list field\n*/\nexports.findListingsOfTiddler = function(targetTitle,fieldName) {\n\tfieldName = fieldName || \"list\";\n\tvar wiki = this;\n\tvar listings = this.getGlobalCache(\"listings-\" + fieldName,function() {\n\t\tvar listings = Object.create(null);\n\t\twiki.each(function(tiddler,title) {\n\t\t\tvar list = $tw.utils.parseStringArray(tiddler.fields[fieldName]);\n\t\t\tif(list) {\n\t\t\t\tfor(var i = 0; i < list.length; i++) {\n\t\t\t\t\tvar listItem = list[i],\n\t\t\t\t\t\tlisting = listings[listItem] || [];\n\t\t\t\t\tif (listing.indexOf(title) === -1) {\n\t\t\t\t\t\tlisting.push(title);\n\t\t\t\t\t}\n\t\t\t\t\tlistings[listItem] = listing;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\treturn listings;\n\t});\n\treturn listings[targetTitle] || [];\n};\n\n/*\nSorts an array of tiddler titles according to an ordered list\n*/\nexports.sortByList = function(array,listTitle) {\n\tvar self = this,\n\t\treplacedTitles = Object.create(null);\n\t// Given a title, this function will place it in the correct location\n\t// within titles.\n\tfunction moveItemInList(title) {\n\t\tif(!$tw.utils.hop(replacedTitles, title)) {\n\t\t\treplacedTitles[title] = true;\n\t\t\tvar newPos = -1,\n\t\t\t\ttiddler = self.getTiddler(title);\n\t\t\tif(tiddler) {\n\t\t\t\tvar beforeTitle = tiddler.fields[\"list-before\"],\n\t\t\t\t\tafterTitle = tiddler.fields[\"list-after\"];\n\t\t\t\tif(beforeTitle === \"\") {\n\t\t\t\t\tnewPos = 0;\n\t\t\t\t} else if(afterTitle === \"\") {\n\t\t\t\t\tnewPos = titles.length;\n\t\t\t\t} else if(beforeTitle) {\n\t\t\t\t\t// if this title is placed relative\n\t\t\t\t\t// to another title, make sure that\n\t\t\t\t\t// title is placed before we place\n\t\t\t\t\t// this one.\n\t\t\t\t\tmoveItemInList(beforeTitle);\n\t\t\t\t\tnewPos = titles.indexOf(beforeTitle);\n\t\t\t\t} else if(afterTitle) {\n\t\t\t\t\t// Same deal\n\t\t\t\t\tmoveItemInList(afterTitle);\n\t\t\t\t\tnewPos = titles.indexOf(afterTitle);\n\t\t\t\t\tif(newPos >= 0) {\n\t\t\t\t\t\t++newPos;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// If a new position is specified, let's move it\n\t\t\t\tif (newPos !== -1) {\n\t\t\t\t\t// get its current Pos, and make sure\n\t\t\t\t\t// sure that it's _actually_ in the list\n\t\t\t\t\t// and that it would _actually_ move\n\t\t\t\t\t// (#4275) We don't bother calling\n\t\t\t\t\t//         indexOf unless we have a new\n\t\t\t\t\t//         position to work with\n\t\t\t\t\tvar currPos = titles.indexOf(title);\n\t\t\t\t\tif(currPos >= 0 && newPos !== currPos) {\n\t\t\t\t\t\t// move it!\n\t\t\t\t\t\ttitles.splice(currPos,1);\n\t\t\t\t\t\tif(newPos >= currPos) {\n\t\t\t\t\t\t\tnewPos--;\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttitles.splice(newPos,0,title);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tvar list = this.getTiddlerList(listTitle);\n\tif(!array || array.length === 0) {\n\t\treturn [];\n\t} else {\n\t\tvar titles = [], t, title;\n\t\t// First place any entries that are present in the list\n\t\tfor(t=0; t<list.length; t++) {\n\t\t\ttitle = list[t];\n\t\t\tif(array.indexOf(title) !== -1) {\n\t\t\t\ttitles.push(title);\n\t\t\t}\n\t\t}\n\t\t// Then place any remaining entries\n\t\tfor(t=0; t<array.length; t++) {\n\t\t\ttitle = array[t];\n\t\t\tif(list.indexOf(title) === -1) {\n\t\t\t\ttitles.push(title);\n\t\t\t}\n\t\t}\n\t\t// Finally obey the list-before and list-after fields of each tiddler in turn\n\t\tvar sortedTitles = titles.slice(0);\n\t\tfor(t=0; t<sortedTitles.length; t++) {\n\t\t\ttitle = sortedTitles[t];\n\t\t\tmoveItemInList(title);\n\t\t}\n\t\treturn titles;\n\t}\n};\n\nexports.getSubTiddler = function(title,subTiddlerTitle) {\n\tvar bundleInfo = this.getPluginInfo(title) || this.getTiddlerDataCached(title);\n\tif(bundleInfo && bundleInfo.tiddlers) {\n\t\tvar subTiddler = bundleInfo.tiddlers[subTiddlerTitle];\n\t\tif(subTiddler) {\n\t\t\treturn new $tw.Tiddler(subTiddler);\n\t\t}\n\t}\n\treturn null;\n};\n\n/*\nRetrieve a tiddler as a JSON string of the fields\n*/\nexports.getTiddlerAsJson = function(title) {\n\tvar tiddler = this.getTiddler(title);\n\tif(tiddler) {\n\t\tvar fields = Object.create(null);\n\t\t$tw.utils.each(tiddler.fields,function(value,name) {\n\t\t\tfields[name] = tiddler.getFieldString(name);\n\t\t});\n\t\treturn JSON.stringify(fields);\n\t} else {\n\t\treturn JSON.stringify({title: title});\n\t}\n};\n\nexports.getTiddlersAsJson = function(filter,spaces) {\n\tvar tiddlers = this.filterTiddlers(filter),\n\t\tspaces = (spaces === undefined) ? $tw.config.preferences.jsonSpaces : spaces,\n\t\tdata = [];\n\tfor(var t=0;t<tiddlers.length; t++) {\n\t\tvar tiddler = this.getTiddler(tiddlers[t]);\n\t\tif(tiddler) {\n\t\t\tvar fields = new Object();\n\t\t\tfor(var field in tiddler.fields) {\n\t\t\t\tfields[field] = tiddler.getFieldString(field);\n\t\t\t}\n\t\t\tdata.push(fields);\n\t\t}\n\t}\n\treturn JSON.stringify(data,null,spaces);\n};\n\n/*\nGet the content of a tiddler as a JavaScript object. How this is done depends on the type of the tiddler:\n\napplication/json: the tiddler JSON is parsed into an object\napplication/x-tiddler-dictionary: the tiddler is parsed as sequence of name:value pairs\n\nOther types currently just return null.\n\ntitleOrTiddler: string tiddler title or a tiddler object\ndefaultData: default data to be returned if the tiddler is missing or doesn't contain data\n\nNote that the same value is returned for repeated calls for the same tiddler data. The value is frozen to prevent modification; otherwise modifications would be visible to all callers\n*/\nexports.getTiddlerDataCached = function(titleOrTiddler,defaultData) {\n\tvar self = this,\n\t\ttiddler = titleOrTiddler;\n\tif(!(tiddler instanceof $tw.Tiddler)) {\n\t\ttiddler = this.getTiddler(tiddler);\n\t}\n\tif(tiddler) {\n\t\treturn this.getCacheForTiddler(tiddler.fields.title,\"data\",function() {\n\t\t\t// Return the frozen value\n\t\t\tvar value = self.getTiddlerData(tiddler.fields.title,undefined);\n\t\t\t$tw.utils.deepFreeze(value);\n\t\t\treturn value;\n\t\t}) || defaultData;\n\t} else {\n\t\treturn defaultData;\n\t}\n};\n\n/*\nAlternative, uncached version of getTiddlerDataCached(). The return value can be mutated freely and reused\n*/\nexports.getTiddlerData = function(titleOrTiddler,defaultData) {\n\tvar tiddler = titleOrTiddler,\n\t\tdata;\n\tif(!(tiddler instanceof $tw.Tiddler)) {\n\t\ttiddler = this.getTiddler(tiddler);\n\t}\n\tif(tiddler && tiddler.fields.text) {\n\t\tswitch(tiddler.fields.type) {\n\t\t\tcase \"application/json\":\n\t\t\t\t// JSON tiddler\n\t\t\t\treturn $tw.utils.parseJSONSafe(tiddler.fields.text,defaultData);\n\t\t\tcase \"application/x-tiddler-dictionary\":\n\t\t\t\treturn $tw.utils.parseFields(tiddler.fields.text);\n\t\t}\n\t}\n\treturn defaultData;\n};\n\n/*\nExtract an indexed field from within a data tiddler\n*/\nexports.extractTiddlerDataItem = function(titleOrTiddler,index,defaultText) {\n\tvar data = this.getTiddlerDataCached(titleOrTiddler,Object.create(null)),\n\t\ttext;\n\tif(data && $tw.utils.hop(data,index)) {\n\t\ttext = data[index];\n\t}\n\tif(typeof text === \"string\" || typeof text === \"number\") {\n\t\treturn text.toString();\n\t} else {\n\t\treturn defaultText;\n\t}\n};\n\n/*\nSet a tiddlers content to a JavaScript object. Currently this is done by setting the tiddler's type to \"application/json\" and setting the text to the JSON text of the data.\ntitle: title of tiddler\ndata: object that can be serialised to JSON\nfields: optional hashmap of additional tiddler fields to be set\noptions: optional hashmap of options including:\n\tsuppressTimestamp: if true, don't set the creation/modification timestamps\n*/\nexports.setTiddlerData = function(title,data,fields,options) {\n\toptions = options || {};\n\tvar existingTiddler = this.getTiddler(title),\n\t\tcreationFields = options.suppressTimestamp ? {} : this.getCreationFields(),\n\t\tmodificationFields = options.suppressTimestamp ? {} : this.getModificationFields(),\n\t\tnewFields = {\n\t\t\ttitle: title\n\t\t};\n\tif(existingTiddler && existingTiddler.fields.type === \"application/x-tiddler-dictionary\") {\n\t\tnewFields.text = $tw.utils.makeTiddlerDictionary(data);\n\t} else {\n\t\tnewFields.type = \"application/json\";\n\t\tnewFields.text = JSON.stringify(data,null,$tw.config.preferences.jsonSpaces);\n\t}\n\tthis.addTiddler(new $tw.Tiddler(creationFields,existingTiddler,fields,newFields,modificationFields));\n};\n\n/*\nReturn the content of a tiddler as an array containing each line\n*/\nexports.getTiddlerList = function(title,field,index) {\n\tif(index) {\n\t\treturn $tw.utils.parseStringArray(this.extractTiddlerDataItem(title,index,\"\"));\n\t}\n\tfield = field || \"list\";\n\tvar tiddler = this.getTiddler(title);\n\tif(tiddler) {\n\t\treturn ($tw.utils.parseStringArray(tiddler.fields[field]) || []).slice(0);\n\t}\n\treturn [];\n};\n\n// Return a named global cache object. Global cache objects are cleared whenever a tiddler change occurs\nexports.getGlobalCache = function(cacheName,initializer) {\n\tthis.globalCache = this.globalCache || Object.create(null);\n\tif($tw.utils.hop(this.globalCache,cacheName)) {\n\t\treturn this.globalCache[cacheName];\n\t} else {\n\t\tthis.globalCache[cacheName] = initializer();\n\t\treturn this.globalCache[cacheName];\n\t}\n};\n\nexports.clearGlobalCache = function() {\n\tthis.globalCache = Object.create(null);\n};\n\n// Return the named cache object for a tiddler. If the cache doesn't exist then the initializer function is invoked to create it\nexports.getCacheForTiddler = function(title,cacheName,initializer) {\n\tthis.caches = this.caches || Object.create(null);\n\tvar caches = this.caches[title];\n\tif(caches && caches[cacheName] !== undefined) {\n\t\treturn caches[cacheName];\n\t} else {\n\t\tif(!caches) {\n\t\t\tcaches = Object.create(null);\n\t\t\tthis.caches[title] = caches;\n\t\t}\n\t\tcaches[cacheName] = initializer();\n\t\treturn caches[cacheName];\n\t}\n};\n\n// Clear all caches associated with a particular tiddler, or, if the title is null, clear all the caches for all the tiddlers\nexports.clearCache = function(title) {\n\tif(title) {\n\t\tthis.caches = this.caches || Object.create(null);\n\t\tif($tw.utils.hop(this.caches,title)) {\n\t\t\tdelete this.caches[title];\n\t\t}\n\t} else {\n\t\tthis.caches = Object.create(null);\n\t}\n};\n\nexports.initParsers = function(moduleType) {\n\t// Install the parser modules\n\t$tw.Wiki.parsers = {};\n\tvar self = this;\n\t$tw.modules.forEachModuleOfType(\"parser\",function(title,module) {\n\t\tfor(var f in module) {\n\t\t\tif($tw.utils.hop(module,f)) {\n\t\t\t\t$tw.Wiki.parsers[f] = module[f]; // Store the parser class\n\t\t\t}\n\t\t}\n\t});\n\t// Use the generic binary parser for any binary types not registered so far\n\tif($tw.Wiki.parsers[\"application/octet-stream\"]) {\n\t\tObject.keys($tw.config.contentTypeInfo).forEach(function(type) {\n\t\t\tif(!$tw.utils.hop($tw.Wiki.parsers,type) && $tw.config.contentTypeInfo[type].encoding === \"base64\") {\n\t\t\t\t$tw.Wiki.parsers[type] = $tw.Wiki.parsers[\"application/octet-stream\"];\n\t\t\t}\n\t\t});\n\t}\n};\n\n/*\nParse a block of text of a specified MIME type\n\ttype: content type of text to be parsed\n\ttext: text\n\toptions: see below\nOptions include:\n\tparseAsInline: if true, the text of the tiddler will be parsed as an inline run\n\t_canonical_uri: optional string of the canonical URI of this content\n*/\nexports.parseText = function(type,text,options) {\n\ttext = text || \"\";\n\toptions = options || {};\n\t// Select a parser\n\tvar Parser = $tw.Wiki.parsers[type];\n\tif(!Parser && $tw.utils.getFileExtensionInfo(type)) {\n\t\tParser = $tw.Wiki.parsers[$tw.utils.getFileExtensionInfo(type).type];\n\t}\n\tif(!Parser) {\n\t\tParser = $tw.Wiki.parsers[options.defaultType || \"text/vnd.tiddlywiki\"];\n\t}\n\tif(!Parser) {\n\t\treturn null;\n\t}\n\t// Return the parser instance\n\treturn new Parser(type,text,{\n\t\tparseAsInline: options.parseAsInline,\n\t\twiki: this,\n\t\t_canonical_uri: options._canonical_uri,\n\t\tconfigTrimWhiteSpace: options.configTrimWhiteSpace\n\t});\n};\n\n/*\nParse a tiddler according to its MIME type\n*/\nexports.parseTiddler = function(title,options) {\n\toptions = $tw.utils.extend({},options);\n\tvar cacheType = options.parseAsInline ? \"inlineParseTree\" : \"blockParseTree\",\n\t\ttiddler = this.getTiddler(title),\n\t\tself = this;\n\treturn tiddler ? this.getCacheForTiddler(title,cacheType,function() {\n\t\t\tif(tiddler.hasField(\"_canonical_uri\")) {\n\t\t\t\toptions._canonical_uri = tiddler.fields._canonical_uri;\n\t\t\t}\n\t\t\treturn self.parseText(tiddler.fields.type,tiddler.fields.text,options);\n\t\t}) : null;\n};\n\nexports.parseTextReference = function(title,field,index,options) {\n\tvar tiddler,\n\t\ttext,\n\t\tparserInfo;\n\tif(!options.subTiddler) {\n\t\ttiddler = this.getTiddler(title);\n\t\tif(field === \"text\" || (!field && !index)) {\n\t\t\tthis.getTiddlerText(title); // Force the tiddler to be lazily loaded\n\t\t\treturn this.parseTiddler(title,options);\n\t\t}\n\t} \n\tparserInfo = this.getTextReferenceParserInfo(title,field,index,options);\n\tif(parserInfo.sourceText !== null) {\n\t\treturn this.parseText(parserInfo.parserType,parserInfo.sourceText,options);\n\t} else {\n\t\treturn null;\n\t}\n};\n\nexports.getTextReferenceParserInfo = function(title,field,index,options) {\n\tvar defaultType = options.defaultType || \"text/vnd.tiddlywiki\",\n\t\ttiddler,\n\t\tparserInfo = {\n\t\t\tsourceText : null,\n\t\t\tparserType : defaultType\n\t\t};\n\tif(options.subTiddler) {\n\t\ttiddler = this.getSubTiddler(title,options.subTiddler);\n\t} else {\n\t\ttiddler = this.getTiddler(title);\n\t}\n\tif(field === \"text\" || (!field && !index)) {\n\t\tif(tiddler && tiddler.fields) {\n\t\t\tparserInfo.sourceText = tiddler.fields.text || \"\";\n\t\t\tif(tiddler.fields.type) {\n\t\t\t\tparserInfo.parserType = tiddler.fields.type;\n\t\t\t}\n\t\t}\n\t} else if(field) {\n\t\tif(field === \"title\") {\n\t\t\tparserInfo.sourceText = title;\n\t\t} else if(tiddler && tiddler.fields) {\n\t\t\tparserInfo.sourceText = tiddler.hasField(field) ? tiddler.fields[field].toString() : null;\n\t\t}\n\t} else if(index) {\n\t\tthis.getTiddlerText(title); // Force the tiddler to be lazily loaded\n\t\tparserInfo.sourceText = this.extractTiddlerDataItem(tiddler,index,null);\n\t}\n\tif(parserInfo.sourceText === null) {\n\t\tparserInfo.parserType = null;\n\t}\n\treturn parserInfo;\n}\n\n/*\nParse a block of text of a specified MIME type\n\ttext: text on which to perform substitutions\n\twidget\n\toptions: see below\nOptions include:\n\tsubstitutions: an optional array of substitutions\n*/\nexports.getSubstitutedText = function(text,widget,options) {\n\toptions = options || {};\n\ttext = text || \"\";\n\tvar self = this,\n\t\tsubstitutions = options.substitutions || [],\n\t\toutput;\n\t// Evaluate embedded filters and substitute with first result\n\toutput = text.replace(/\\$\\{([\\S\\s]+?)\\}\\$/g, function(match,filter) {\n\t\treturn self.filterTiddlers(filter,widget)[0] || \"\";\n\t});\n\t// Process any substitutions provided in options\n\t$tw.utils.each(substitutions,function(substitute) {\n\t\toutput = $tw.utils.replaceString(output,new RegExp(\"\\\\$\" + $tw.utils.escapeRegExp(substitute.name) + \"\\\\$\",\"mg\"),substitute.value);\n\t});\n\t// Substitute any variable references with their values\n\treturn output.replace(/\\$\\(([^\\)\\$]+)\\)\\$/g, function(match,varname) {\n\t\treturn widget.getVariable(varname,{defaultValue: \"\"})\n\t});\n};\n\n/*\nMake a widget tree for a parse tree\nparser: parser object\noptions: see below\nOptions include:\ndocument: optional document to use\nvariables: hashmap of variables to set\nparentWidget: optional parent widget for the root node\n*/\nexports.makeWidget = function(parser,options) {\n\toptions = options || {};\n\tvar widgetNode = {\n\t\t\ttype: \"widget\",\n\t\t\tchildren: []\n\t\t},\n\t\tcurrWidgetNode = widgetNode;\n\t// Create let variable widget for variables\n\tif($tw.utils.count(options.variables) > 0) {\n\t\tvar letVariableWidget = {\n\t\t\ttype: \"let\",\n\t\t\tattributes: {\n\t\t\t},\n\t\t\tchildren: []\n\t\t};\n\t\t$tw.utils.each(options.variables,function(value,name) {\n\t\t\t$tw.utils.addAttributeToParseTreeNode(letVariableWidget,name,\"\" + value);\n\t\t});\n\t\tcurrWidgetNode.children = [letVariableWidget];\n\t\tcurrWidgetNode = letVariableWidget;\n\t}\n\t// Add in the supplied parse tree nodes\n\tcurrWidgetNode.children = parser ? parser.tree : [];\n\t// Create the widget\n\treturn new widget.widget(widgetNode,{\n\t\twiki: this,\n\t\tdocument: options.document || $tw.fakeDocument,\n\t\tparentWidget: options.parentWidget\n\t});\n};\n\n/*\nMake a widget tree for transclusion\ntitle: target tiddler title\noptions: as for wiki.makeWidget() plus:\noptions.field: optional field to transclude (defaults to \"text\")\noptions.mode: transclusion mode \"inline\" or \"block\"\noptions.recursionMarker : optional flag to set a recursion marker, defaults to \"yes\"\noptions.children: optional array of children for the transclude widget\noptions.importVariables: optional importvariables filter string for macros to be included\noptions.importPageMacros: optional boolean; if true, equivalent to passing \"[[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\" to options.importVariables\n*/\nexports.makeTranscludeWidget = function(title,options) {\n\toptions = options || {};\n\tvar parseTreeDiv = {tree: [{\n\t\t\ttype: \"element\",\n\t\t\ttag: \"div\",\n\t\t\tchildren: []}]},\n\t\tparseTreeImportVariables = {\n\t\t\ttype: \"importvariables\",\n\t\t\tattributes: {\n\t\t\t\tfilter: {\n\t\t\t\t\tname: \"filter\",\n\t\t\t\t\ttype: \"string\"\n\t\t\t\t}\n\t\t\t},\n\t\t\tisBlock: false,\n\t\t\tchildren: []},\n\t\tparseTreeTransclude = {\n\t\t\ttype: \"transclude\",\n\t\t\tattributes: {\n\t\t\t\trecursionMarker: {\n\t\t\t\t\tname: \"recursionMarker\",\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tvalue: options.recursionMarker || \"yes\"\n\t\t\t\t\t},\n\t\t\t\ttiddler: {\n\t\t\t\t\tname: \"tiddler\",\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tvalue: title\n\t\t\t\t}\n\t\t\t},\n\t\t\tisBlock: !options.parseAsInline};\n\tif(options.importVariables || options.importPageMacros) {\n\t\tif(options.importVariables) {\n\t\t\tparseTreeImportVariables.attributes.filter.value = options.importVariables;\n\t\t} else if(options.importPageMacros) {\n\t\t\tparseTreeImportVariables.attributes.filter.value = this.getTiddlerText(\"$:/core/config/GlobalImportFilter\");\n\t\t}\n\t\tparseTreeDiv.tree[0].children.push(parseTreeImportVariables);\n\t\tparseTreeImportVariables.children.push(parseTreeTransclude);\n\t} else {\n\t\tparseTreeDiv.tree[0].children.push(parseTreeTransclude);\n\t}\n\tif(options.field) {\n\t\tparseTreeTransclude.attributes.field = {type: \"string\", value: options.field};\n\t}\n\tif(options.mode) {\n\t\tparseTreeTransclude.attributes.mode = {type: \"string\", value: options.mode};\n\t}\n\tif(options.children) {\n\t\tparseTreeTransclude.children = options.children;\n\t}\n\treturn this.makeWidget(parseTreeDiv,options);\n};\n\n/*\nParse text in a specified format and render it into another format\n\toutputType: content type for the output\n\ttextType: content type of the input text\n\ttext: input text\n\toptions: see below\nOptions include:\nvariables: hashmap of variables to set\nparentWidget: optional parent widget for the root node\n*/\nexports.renderText = function(outputType,textType,text,options) {\n\toptions = options || {};\n\tvar parser = this.parseText(textType,text,options),\n\t\twidgetNode = this.makeWidget(parser,options);\n\tvar container = $tw.fakeDocument.createElement(\"div\");\n\twidgetNode.render(container,null);\n\treturn outputType === \"text/html\" ? container.innerHTML : container.textContent;\n};\n\n/*\nParse text from a tiddler and render it into another format\n\toutputType: content type for the output\n\ttitle: title of the tiddler to be rendered\n\toptions: see below\nOptions include:\nvariables: hashmap of variables to set\nparentWidget: optional parent widget for the root node\n*/\nexports.renderTiddler = function(outputType,title,options) {\n\toptions = options || {};\n\tvar parser = this.parseTiddler(title,options),\n\t\twidgetNode = this.makeWidget(parser,options);\n\tvar container = $tw.fakeDocument.createElement(\"div\");\n\twidgetNode.render(container,null);\n\treturn outputType === \"text/html\" ? container.innerHTML : (outputType === \"text/plain-formatted\" ? container.formattedTextContent : container.textContent);\n};\n\n/*\nReturn an array of tiddler titles that match a search string\n\ttext: The text string to search for\n\toptions: see below\nOptions available:\n\tsource: an iterator function for the source tiddlers, called source(iterator),\n\t\twhere iterator is called as iterator(tiddler,title)\n\texclude: An array of tiddler titles to exclude from the search\n\tinvert: If true returns tiddlers that do not contain the specified string\n\tcaseSensitive: If true forces a case sensitive search\n\tfield: If specified, restricts the search to the specified field, or an array of field names\n\tanchored: If true, forces all but regexp searches to be anchored to the start of text\n\texcludeField: If true, the field options are inverted to specify the fields that are not to be searched\n\n\tThe search mode is determined by the first of these boolean flags to be true\n\t\tliteral: searches for literal string\n\t\twhitespace: same as literal except runs of whitespace are treated as a single space\n\t\tregexp: treats the search term as a regular expression\n\t\twords: (default) treats search string as a list of tokens, and matches if all tokens are found, \n\t\t\tregardless of adjacency or ordering\n\t\tsome: treats search string as a list of tokens, and matches if at least ONE token is found\n*/\nexports.search = function(text,options) {\n\toptions = options || {};\n\tvar self = this,\n\t\tt,\n\t\tregExpStr=\"\",\n\t\tinvert = !!options.invert;\n\t// Convert the search string into a regexp for each term\n\tvar terms, searchTermsRegExps,\n\t\tflags = options.caseSensitive ? \"\" : \"i\",\n\t\tanchor = options.anchored ? \"^\" : \"\";\n\tif(options.literal) {\n\t\tif(text.length === 0) {\n\t\t\tsearchTermsRegExps = null;\n\t\t} else {\n\t\t\tsearchTermsRegExps = [new RegExp(\"(\" + anchor + $tw.utils.escapeRegExp(text) + \")\",flags)];\n\t\t}\n\t} else if(options.whitespace) {\n\t\tterms = [];\n\t\t$tw.utils.each(text.split(/\\s+/g),function(term) {\n\t\t\tif(term) {\n\t\t\t\tterms.push($tw.utils.escapeRegExp(term));\n\t\t\t}\n\t\t});\n\t\tsearchTermsRegExps = [new RegExp(\"(\" + anchor + terms.join(\"\\\\s+\") + \")\",flags)];\n\t} else if(options.regexp) {\n\t\ttry {\n\t\t\tsearchTermsRegExps = [new RegExp(\"(\" + text + \")\",flags)];\n\t\t} catch(e) {\n\t\t\tsearchTermsRegExps = null;\n\t\t\tconsole.log(\"Regexp error parsing /(\" + text + \")/\" + flags + \": \",e);\n\t\t}\n\t} else if(options.some) {\n\t\tterms = text.trim().split(/[^\\S\\xA0]+/);\n\t\tif(terms.length === 1 && terms[0] === \"\") {\n\t\t\tsearchTermsRegExps = null;\n\t\t} else {\n\t\t\tsearchTermsRegExps = [];\n\t\t\tfor(t=0; t<terms.length; t++) {\n\t\t\t\tregExpStr += (t===0) ? anchor + $tw.utils.escapeRegExp(terms[t]) : \"|\" + anchor + $tw.utils.escapeRegExp(terms[t]);\n\t\t\t}\n\t\t\tsearchTermsRegExps.push(new RegExp(\"(\" + regExpStr + \")\",flags));\n\t\t}\n\t} else { // default: words\n\t\tterms = text.split(/[^\\S\\xA0]+/);\n\t\tif(terms.length === 1 && terms[0] === \"\") {\n\t\t\tsearchTermsRegExps = null;\n\t\t} else {\n\t\t\tsearchTermsRegExps = [];\n\t\t\tfor(t=0; t<terms.length; t++) {\n\t\t\t\tsearchTermsRegExps.push(new RegExp(\"(\" + anchor + $tw.utils.escapeRegExp(terms[t]) + \")\",flags));\n\t\t\t}\n\t\t}\n\t}\n// Accumulate the array of fields to be searched or excluded from the search\n\tvar fields = [];\n\tif(options.field) {\n\t\tif($tw.utils.isArray(options.field)) {\n\t\t\t$tw.utils.each(options.field,function(fieldName) {\n\t\t\t\tif(fieldName) {\n\t\t\t\t\tfields.push(fieldName);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tfields.push(options.field);\n\t\t}\n\t}\n\t// Use default fields if none specified and we're not excluding fields (excluding fields with an empty field array is the same as searching all fields)\n\tif(fields.length === 0 && !options.excludeField) {\n\t\tfields.push(\"title\");\n\t\tfields.push(\"tags\");\n\t\tfields.push(\"text\");\n\t}\n\t// Function to check a given tiddler for the search term\n\tvar searchTiddler = function(title) {\n\t\tif(!searchTermsRegExps) {\n\t\t\treturn true;\n\t\t}\n\t\tvar notYetFound = searchTermsRegExps.slice();\n\n\t\tvar tiddler = self.getTiddler(title);\n\t\tif(!tiddler) {\n\t\t\ttiddler = new $tw.Tiddler({title: title, text: \"\", type: \"text/vnd.tiddlywiki\"});\n\t\t}\n\t\tvar contentTypeInfo = $tw.config.contentTypeInfo[tiddler.fields.type] || $tw.config.contentTypeInfo[\"text/vnd.tiddlywiki\"],\n\t\t\tsearchFields;\n\t\t// Get the list of fields we're searching\n\t\tif(options.excludeField) {\n\t\t\tsearchFields = Object.keys(tiddler.fields);\n\t\t\t$tw.utils.each(fields,function(fieldName) {\n\t\t\t\tvar p = searchFields.indexOf(fieldName);\n\t\t\t\tif(p !== -1) {\n\t\t\t\t\tsearchFields.splice(p,1);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsearchFields = fields;\n\t\t}\n\t\tfor(var fieldIndex=0; notYetFound.length>0 && fieldIndex<searchFields.length; fieldIndex++) {\n\t\t\t// Don't search the text field if the content type is binary\n\t\t\tvar fieldName = searchFields[fieldIndex];\n\t\t\tif(fieldName === \"text\" && contentTypeInfo.encoding !== \"utf8\") {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tvar str = tiddler.fields[fieldName],\n\t\t\t\tt;\n\t\t\tif(str) {\n\t\t\t\tif($tw.utils.isArray(str)) {\n\t\t\t\t\t// If the field value is an array, test each regexp against each field array entry and fail if each regexp doesn't match at least one field array entry\n\t\t\t\t\tfor(var s=0; s<str.length; s++) {\n\t\t\t\t\t\tfor(t=0; t<notYetFound.length;) {\n\t\t\t\t\t\t\tif(notYetFound[t].test(str[s])) {\n\t\t\t\t\t\t\t\tnotYetFound.splice(t, 1);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tt++;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// If the field isn't an array, force it to a string and test each regexp against it and fail if any do not match\n\t\t\t\t\tstr = tiddler.getFieldString(fieldName);\n\t\t\t\t\tfor(t=0; t<notYetFound.length;) {\n\t\t\t\t\t\tif(notYetFound[t].test(str)) {\n\t\t\t\t\t\t\tnotYetFound.splice(t, 1);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tt++;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\treturn notYetFound.length == 0;\n\t};\n\t// Loop through all the tiddlers doing the search\n\tvar results = [],\n\t\tsource = options.source || this.each;\n\tsource(function(tiddler,title) {\n\t\tif(searchTiddler(title) !== invert) {\n\t\t\tresults.push(title);\n\t\t}\n\t});\n\t// Remove any of the results we have to exclude\n\tif(options.exclude) {\n\t\tfor(t=0; t<options.exclude.length; t++) {\n\t\t\tvar p = results.indexOf(options.exclude[t]);\n\t\t\tif(p !== -1) {\n\t\t\t\tresults.splice(p,1);\n\t\t\t}\n\t\t}\n\t}\n\treturn results;\n};\n\n/*\nTrigger a load for a tiddler if it is skinny. Returns the text, or undefined if the tiddler is missing, null if the tiddler is being lazily loaded.\n*/\nexports.getTiddlerText = function(title,defaultText) {\n\tvar tiddler = this.getTiddler(title);\n\t// Return undefined if the tiddler isn't found\n\tif(!tiddler) {\n\t\treturn defaultText;\n\t}\n\tif(!tiddler.hasField(\"_is_skinny\")) {\n\t\t// Just return the text if we've got it\n\t\treturn tiddler.fields.text || \"\";\n\t} else {\n\t\t// Tell any listeners about the need to lazily load this tiddler\n\t\tthis.dispatchEvent(\"lazyLoad\",title);\n\t\t// Indicate that the text is being loaded\n\t\treturn null;\n\t}\n};\n\n/*\nCheck whether the text of a tiddler matches a given value. By default, the comparison is case insensitive, and any spaces at either end of the tiddler text is trimmed\n*/\nexports.checkTiddlerText = function(title,targetText,options) {\n\toptions = options || {};\n\tvar text = this.getTiddlerText(title,\"\");\n\tif(!options.noTrim) {\n\t\ttext = text.trim();\n\t}\n\tif(!options.caseSensitive) {\n\t\ttext = text.toLowerCase();\n\t\ttargetText = targetText.toLowerCase();\n\t}\n\treturn text === targetText;\n}\n\n/*\nExecute an action string without an associated context widget\n*/\nexports.invokeActionString = function(actions,event,variables,options) {\n\tvar widget = this.makeWidget(null,{parentWidget: options.parentWidget});\n\twidget.invokeActionString(actions,null,event,variables);\n};\n\n/*\nRead an array of browser File objects, invoking callback(tiddlerFieldsArray) once they're all read\n*/\nexports.readFiles = function(files,options) {\n\tvar callback;\n\tif(typeof options === \"function\") {\n\t\tcallback = options;\n\t\toptions = {};\n\t} else {\n\t\tcallback = options.callback;\n\t}\n\tvar result = [],\n\t\toutstanding = files.length,\n\t\treadFileCallback = function(tiddlerFieldsArray) {\n\t\t\tresult.push.apply(result,tiddlerFieldsArray);\n\t\t\tif(--outstanding === 0) {\n\t\t\t\tcallback(result);\n\t\t\t}\n\t\t};\n\tfor(var f=0; f<files.length; f++) {\n\t\tthis.readFile(files[f],$tw.utils.extend({},options,{callback: readFileCallback}));\n\t}\n\treturn files.length;\n};\n\n/*\nRead a browser File object, invoking callback(tiddlerFieldsArray) with an array of tiddler fields objects\n*/\nexports.readFile = function(file,options) {\n\tvar callback;\n\tif(typeof options === \"function\") {\n\t\tcallback = options;\n\t\toptions = {};\n\t} else {\n\t\tcallback = options.callback;\n\t}\n\t// Get the type, falling back to the filename extension\n\tvar self = this,\n\t\ttype = file.type;\n\tif(type === \"\" || !type) {\n\t\tvar dotPos = file.name.lastIndexOf(\".\");\n\t\tif(dotPos !== -1) {\n\t\t\tvar fileExtensionInfo = $tw.utils.getFileExtensionInfo(file.name.substr(dotPos));\n\t\t\tif(fileExtensionInfo) {\n\t\t\t\ttype = fileExtensionInfo.type;\n\t\t\t}\n\t\t}\n\t}\n\t// Figure out if we're reading a binary file\n\tvar contentTypeInfo = $tw.config.contentTypeInfo[type],\n\t\tisBinary = contentTypeInfo ? contentTypeInfo.encoding === \"base64\" : false;\n\t// Log some debugging information\n\tif($tw.log.IMPORT) {\n\t\tconsole.log(\"Importing file '\" + file.name + \"', type: '\" + type + \"', isBinary: \" + isBinary);\n\t}\n\t// Give the hook a chance to process the drag\n\tif($tw.hooks.invokeHook(\"th-importing-file\",{\n\t\tfile: file,\n\t\ttype: type,\n\t\tisBinary: isBinary,\n\t\tcallback: callback\n\t}) !== true) {\n\t\tthis.readFileContent(file,type,isBinary,options.deserializer,callback);\n\t}\n};\n\n/*\nLower level utility to read the content of a browser File object, invoking callback(tiddlerFieldsArray) with an array of tiddler fields objects\n*/\nexports.readFileContent = function(file,type,isBinary,deserializer,callback) {\n\tvar self = this;\n\t// Create the FileReader\n\tvar reader = new FileReader();\n\t// Onload\n\treader.onload = function(event) {\n\t\tvar text = event.target.result,\n\t\t\ttiddlerFields = {title: file.name || \"Untitled\"};\n\t\tif(isBinary) {\n\t\t\tvar commaPos = text.indexOf(\",\");\n\t\t\tif(commaPos !== -1) {\n\t\t\t\ttext = text.substr(commaPos + 1);\n\t\t\t}\n\t\t}\n\t\t// Check whether this is an encrypted TiddlyWiki file\n\t\tvar encryptedJson = $tw.utils.extractEncryptedStoreArea(text);\n\t\tif(encryptedJson) {\n\t\t\t// If so, attempt to decrypt it with the current password\n\t\t\t$tw.utils.decryptStoreAreaInteractive(encryptedJson,function(tiddlers) {\n\t\t\t\tcallback(tiddlers);\n\t\t\t});\n\t\t} else {\n\t\t\t// Otherwise, just try to deserialise any tiddlers in the file\n\t\t\tcallback(self.deserializeTiddlers(type,text,tiddlerFields,{deserializer: deserializer}));\n\t\t}\n\t};\n\t// Kick off the read\n\tif(isBinary) {\n\t\treader.readAsDataURL(file);\n\t} else {\n\t\treader.readAsText(file);\n\t}\n};\n\n/*\nFind any existing draft of a specified tiddler\n*/\nexports.findDraft = function(targetTitle) {\n\tvar draftTitle = undefined;\n\tthis.forEachTiddler({includeSystem: true},function(title,tiddler) {\n\t\tif(tiddler.fields[\"draft.title\"] && tiddler.fields[\"draft.of\"] === targetTitle) {\n\t\t\tdraftTitle = title;\n\t\t}\n\t});\n\treturn draftTitle;\n}\n\n/*\nCheck whether the specified draft tiddler has been modified.\nIf the original tiddler doesn't exist, create  a vanilla tiddler variable,\nto check if additional fields have been added.\n*/\nexports.isDraftModified = function(title) {\n\tvar tiddler = this.getTiddler(title);\n\tif(!tiddler.isDraft()) {\n\t\treturn false;\n\t}\n\tvar ignoredFields = [\"created\", \"modified\", \"title\", \"draft.title\", \"draft.of\"],\n\t\torigTiddler = this.getTiddler(tiddler.fields[\"draft.of\"]) || new $tw.Tiddler({text:\"\", tags:[]}),\n\t\ttitleModified = tiddler.fields[\"draft.title\"] !== tiddler.fields[\"draft.of\"];\n\treturn titleModified || !tiddler.isEqual(origTiddler,ignoredFields);\n};\n\n/*\nAdd a new record to the top of the history stack\ntitle: a title string or an array of title strings\nfromPageRect: page coordinates of the origin of the navigation\nhistoryTitle: title of history tiddler (defaults to $:/HistoryList)\n*/\nexports.addToHistory = function(title,fromPageRect,historyTitle) {\n\tvar story = new $tw.Story({wiki: this, historyTitle: historyTitle});\n\tstory.addToHistory(title,fromPageRect);\n\tconsole.log(\"$tw.wiki.addToHistory() is deprecated since V5.1.23! Use the this.story.addToHistory() from the story-object!\")\n};\n\n/*\nAdd a new tiddler to the story river\ntitle: a title string or an array of title strings\nfromTitle: the title of the tiddler from which the navigation originated\nstoryTitle: title of story tiddler (defaults to $:/StoryList)\noptions: see story.js\n*/\nexports.addToStory = function(title,fromTitle,storyTitle,options) {\n\tvar story = new $tw.Story({wiki: this, storyTitle: storyTitle});\n\tstory.addToStory(title,fromTitle,options);\n\tconsole.log(\"$tw.wiki.addToStory() is deprecated since V5.1.23! Use the this.story.addToStory() from the story-object!\")\n};\n\n/*\nGenerate a title for the draft of a given tiddler\n*/\nexports.generateDraftTitle = function(title) {\n\tvar c = 0,\n\t\tdraftTitle,\n\t\tusername = this.getTiddlerText(\"$:/status/UserName\"),\n\t\tattribution = username ? \" by \" + username : \"\";\n\tdo {\n\t\tdraftTitle = \"Draft \" + (c ? (c + 1) + \" \" : \"\") + \"of '\" + title + \"'\" + attribution;\n\t\tc++;\n\t} while(this.tiddlerExists(draftTitle));\n\treturn draftTitle;\n};\n\n/*\nInvoke the available upgrader modules\ntitles: array of tiddler titles to be processed\ntiddlers: hashmap by title of tiddler fields of pending import tiddlers. These can be modified by the upgraders. An entry with no fields indicates a tiddler that was pending import has been suppressed. When entries are added to the pending import the tiddlers hashmap may have entries that are not present in the titles array\nReturns a hashmap of messages keyed by tiddler title.\n*/\nexports.invokeUpgraders = function(titles,tiddlers) {\n\t// Collect up the available upgrader modules\n\tvar self = this;\n\tif(!this.upgraderModules) {\n\t\tthis.upgraderModules = [];\n\t\t$tw.modules.forEachModuleOfType(\"upgrader\",function(title,module) {\n\t\t\tif(module.upgrade) {\n\t\t\t\tself.upgraderModules.push(module);\n\t\t\t}\n\t\t});\n\t}\n\t// Invoke each upgrader in turn\n\tvar messages = {};\n\tfor(var t=0; t<this.upgraderModules.length; t++) {\n\t\tvar upgrader = this.upgraderModules[t],\n\t\t\tupgraderMessages = upgrader.upgrade(this,titles,tiddlers);\n\t\t$tw.utils.extend(messages,upgraderMessages);\n\t}\n\treturn messages;\n};\n\n// Determine whether a plugin by title is dynamically loadable\nexports.doesPluginRequireReload = function(title) {\n\tvar tiddler = this.getTiddler(title);\n\tif(tiddler && tiddler.fields.type === \"application/json\" && tiddler.fields[\"plugin-type\"]) {\n\t\tif(tiddler.fields[\"plugin-type\"] === \"import\") {\n\t\t\t// The import plugin never requires reloading\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn this.doesPluginInfoRequireReload(this.getPluginInfo(title) || this.getTiddlerDataCached(title));\n};\n\n// Determine whether a plugin info structure is dynamically loadable\nexports.doesPluginInfoRequireReload = function(pluginInfo) {\n\tif(pluginInfo) {\n\t\tvar foundModule = false;\n\t\t$tw.utils.each(pluginInfo.tiddlers,function(tiddler) {\n\t\t\tif(tiddler.type === \"application/javascript\" && $tw.utils.hop(tiddler,\"module-type\")) {\n\t\t\t\tfoundModule = true;\n\t\t\t}\n\t\t});\n\t\treturn foundModule;\n\t} else {\n\t\treturn null;\n\t}\n};\n\nexports.slugify = function(title,options) {\n\tvar tiddler = this.getTiddler(title),\n\t\tslug;\n\tif(tiddler && tiddler.fields.slug) {\n\t\tslug = tiddler.fields.slug;\n\t} else {\n\t\tslug = $tw.utils.transliterate(title.toString().toLowerCase()) // Replace diacritics with basic lowercase ASCII\n\t\t\t.replace(/\\s+/g,\"-\")                                       // Replace spaces with -\n\t\t\t.replace(/[^\\w\\-\\.]+/g,\"\")                                 // Remove all non-word chars except dash and dot\n\t\t\t.replace(/\\-\\-+/g,\"-\")                                     // Replace multiple - with single -\n\t\t\t.replace(/^-+/,\"\")                                         // Trim - from start of text\n\t\t\t.replace(/-+$/,\"\");                                        // Trim - from end of text\n\t}\n\t// If the resulting slug is blank (eg because the title is just punctuation characters)\n\tif(!slug) {\n\t\t// ...then just use the character codes of the title\n\t\tvar result = [];\n\t\t$tw.utils.each(title.split(\"\"),function(char) {\n\t\t\tresult.push(char.charCodeAt(0).toString());\n\t\t});\n\t\tslug = result.join(\"-\");\n\t}\n\treturn slug;\n};\n\n})();\n","type":"application/javascript","module-type":"wikimethod"},"$:/palettes/Blanca":{"title":"$:/palettes/Blanca","name":"Blanca","color-scheme":"light","description":"A clean white palette to let you focus","tags":"$:/tags/Palette","type":"application/x-tiddler-dictionary","text":"alert-background: #ffe476\nalert-border: #b99e2f\nalert-highlight: #881122\nalert-muted-foreground: #b99e2f\nbackground: #ffffff\nblockquote-bar: <<colour muted-foreground>>\nbutton-background:\nbutton-foreground:\nbutton-border:\ncode-background: #f7f7f9\ncode-border: #e1e1e8\ncode-foreground: #dd1144\ndirty-indicator: #ff0000\ndownload-background: #66cccc\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: #fff\ndropdown-tab-background: #ececec\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #0000aa\nexternal-link-foreground: #0000ee\nfootnote-target-background: #ecf2ff\nforeground: #333333\nhighlight-background: #ffff00\nhighlight-foreground: #000000\nmessage-background: #ecf2ff\nmessage-border: #cfd6e6\nmessage-foreground: #547599\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: #999999\nmodal-footer-background: #f5f5f5\nmodal-footer-border: #dddddd\nmodal-header-border: #eeeeee\nmuted-foreground: #999999\nnotification-background: #ffffdd\nnotification-border: #999999\npage-background: #ffffff\npre-background: #f5f5f5\npre-border: #cccccc\nprimary: #7897f3\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #000000\nsidebar-controls-foreground: #ccc\nsidebar-foreground-shadow: rgba(255,255,255, 0.8)\nsidebar-foreground: #acacac\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: #c0c0c0\nsidebar-tab-background-selected: #ffffff\nsidebar-tab-background: <<colour tab-background>>\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: <<colour tab-border>>\nsidebar-tab-divider: <<colour tab-divider>>\nsidebar-tab-foreground-selected: \nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: #444444\nsidebar-tiddler-link-foreground: #7897f3\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: #ffffff\ntab-background: #eeeeee\ntab-border-selected: #cccccc\ntab-border: #cccccc\ntab-divider: #d8d8d8\ntab-foreground-selected: <<colour tab-foreground>>\ntab-foreground: #666666\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #ffeedd\ntag-foreground: #000\ntiddler-background: <<colour background>>\ntiddler-border: #eee\ntiddler-controls-foreground-hover: #888888\ntiddler-controls-foreground-selected: #444444\ntiddler-controls-foreground: #cccccc\ntiddler-editor-background: #f8f8f8\ntiddler-editor-border-image: #ffffff\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: #e0e8e0\ntiddler-editor-fields-odd: #f0f4f0\ntiddler-info-background: #f8f8f8\ntiddler-info-border: #dddddd\ntiddler-info-tab-background: #f8f8f8\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: #c0c0c0\ntiddler-title-foreground: #ff9900\ntoolbar-new-button:\ntoolbar-options-button:\ntoolbar-save-button:\ntoolbar-info-button:\ntoolbar-edit-button:\ntoolbar-close-button:\ntoolbar-delete-button:\ntoolbar-cancel-button:\ntoolbar-done-button:\nuntagged-background: #999999\nvery-muted-foreground: #888888\n"},"$:/palettes/Blue":{"title":"$:/palettes/Blue","name":"Blue","color-scheme":"light","description":"A blue theme","tags":"$:/tags/Palette","type":"application/x-tiddler-dictionary","text":"alert-background: #ffe476\nalert-border: #b99e2f\nalert-highlight: #881122\nalert-muted-foreground: #b99e2f\nbackground: #fff\nblockquote-bar: <<colour muted-foreground>>\nbutton-background:\nbutton-foreground:\nbutton-border:\ncode-background: #f7f7f9\ncode-border: #e1e1e8\ncode-foreground: #dd1144\ndirty-indicator: #ff0000\ndownload-background: #34c734\ndownload-foreground: <<colour foreground>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: #fff\ndropdown-tab-background: #ececec\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #0000aa\nexternal-link-foreground: #0000ee\nfootnote-target-background: #ecf2ff\nforeground: #333353\nhighlight-background: #ffff00\nhighlight-foreground: #000000\nmessage-background: #ecf2ff\nmessage-border: #cfd6e6\nmessage-foreground: #547599\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: #999999\nmodal-footer-background: #f5f5f5\nmodal-footer-border: #dddddd\nmodal-header-border: #eeeeee\nmuted-foreground: #999999\nnotification-background: #ffffdd\nnotification-border: #999999\npage-background: #ddddff\npre-background: #f5f5f5\npre-border: #cccccc\nprimary: #5778d8\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #000000\nsidebar-controls-foreground: #ffffff\nsidebar-foreground-shadow: rgba(255,255,255, 0.8)\nsidebar-foreground: #acacac\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: #c0c0c0\nsidebar-tab-background-selected: <<colour page-background>>\nsidebar-tab-background: <<colour tab-background>>\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: <<colour tab-border>>\nsidebar-tab-divider: <<colour tab-divider>>\nsidebar-tab-foreground-selected: \nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: #444444\nsidebar-tiddler-link-foreground: #5959c0\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: <<colour background>>\ntab-background: #ccccdd\ntab-border-selected: #ccccdd\ntab-border: #cccccc\ntab-divider: #d8d8d8\ntab-foreground-selected: <<colour tab-foreground>>\ntab-foreground: #666666\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #eeeeff\ntag-foreground: #000\ntiddler-background: <<colour background>>\ntiddler-border: <<colour background>>\ntiddler-controls-foreground-hover: #666666\ntiddler-controls-foreground-selected: #444444\ntiddler-controls-foreground: #cccccc\ntiddler-editor-background: #f8f8f8\ntiddler-editor-border-image: #ffffff\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: #e0e8e0\ntiddler-editor-fields-odd: #f0f4f0\ntiddler-info-background: #ffffff\ntiddler-info-border: #dddddd\ntiddler-info-tab-background: #ffffff\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: #c0c0c0\ntiddler-title-foreground: #5959c0\ntoolbar-new-button: #5eb95e\ntoolbar-options-button: rgb(128, 88, 165)\ntoolbar-save-button: #0e90d2\ntoolbar-info-button: #0e90d2\ntoolbar-edit-button: rgb(243, 123, 29)\ntoolbar-close-button: #dd514c\ntoolbar-delete-button: #dd514c\ntoolbar-cancel-button: rgb(243, 123, 29)\ntoolbar-done-button: #5eb95e\nuntagged-background: #999999\nvery-muted-foreground: #888888\n"},"$:/palettes/Muted":{"title":"$:/palettes/Muted","name":"Muted","color-scheme":"light","description":"Bright tiddlers on a muted background","tags":"$:/tags/Palette","type":"application/x-tiddler-dictionary","text":"alert-background: #ffe476\nalert-border: #b99e2f\nalert-highlight: #881122\nalert-muted-foreground: #b99e2f\nbackground: #ffffff\nblockquote-bar: <<colour muted-foreground>>\nbutton-background:\nbutton-foreground:\nbutton-border:\ncode-background: #f7f7f9\ncode-border: #e1e1e8\ncode-foreground: #dd1144\ndirty-indicator: #ff0000\ndownload-background: #34c734\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: #fff\ndropdown-tab-background: #ececec\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #0000aa\nexternal-link-foreground: #0000ee\nfootnote-target-background: #ecf2ff\nforeground: #333333\nhighlight-background: #ffff00\nhighlight-foreground: #000000\nmessage-background: #ecf2ff\nmessage-border: #cfd6e6\nmessage-foreground: #547599\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: #999999\nmodal-footer-background: #f5f5f5\nmodal-footer-border: #dddddd\nmodal-header-border: #eeeeee\nmuted-foreground: #bbb\nnotification-background: #ffffdd\nnotification-border: #999999\npage-background: #6f6f70\npre-background: #f5f5f5\npre-border: #cccccc\nprimary: #29a6ee\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #000000\nsidebar-controls-foreground: #c2c1c2\nsidebar-foreground-shadow: rgba(255,255,255,0)\nsidebar-foreground: #d3d2d4\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: #c0c0c0\nsidebar-tab-background-selected: #6f6f70\nsidebar-tab-background: #666667\nsidebar-tab-border-selected: #999\nsidebar-tab-border: #515151\nsidebar-tab-divider: #999\nsidebar-tab-foreground-selected: \nsidebar-tab-foreground: #999\nsidebar-tiddler-link-foreground-hover: #444444\nsidebar-tiddler-link-foreground: #d1d0d2\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: #ffffff\ntab-background: #d8d8d8\ntab-border-selected: #d8d8d8\ntab-border: #cccccc\ntab-divider: #d8d8d8\ntab-foreground-selected: <<colour tab-foreground>>\ntab-foreground: #666666\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #d5ad34\ntag-foreground: #ffffff\ntiddler-background: <<colour background>>\ntiddler-border: <<colour background>>\ntiddler-controls-foreground-hover: #888888\ntiddler-controls-foreground-selected: #444444\ntiddler-controls-foreground: #cccccc\ntiddler-editor-background: #f8f8f8\ntiddler-editor-border-image: #ffffff\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: #e0e8e0\ntiddler-editor-fields-odd: #f0f4f0\ntiddler-info-background: #f8f8f8\ntiddler-info-border: #dddddd\ntiddler-info-tab-background: #f8f8f8\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: #c0c0c0\ntiddler-title-foreground: #182955\ntoolbar-new-button: \ntoolbar-options-button: \ntoolbar-save-button: \ntoolbar-info-button: \ntoolbar-edit-button: \ntoolbar-close-button: \ntoolbar-delete-button: \ntoolbar-cancel-button: \ntoolbar-done-button: \nuntagged-background: #999999\nvery-muted-foreground: #888888\n"},"$:/palettes/ContrastDark":{"title":"$:/palettes/ContrastDark","name":"Contrast (Dark)","color-scheme":"dark","description":"High contrast and unambiguous (dark version)","tags":"$:/tags/Palette","type":"application/x-tiddler-dictionary","text":"alert-background: #f00\nalert-border: <<colour background>>\nalert-highlight: <<colour foreground>>\nalert-muted-foreground: #800\nbackground: #000\nblockquote-bar: <<colour muted-foreground>>\nbutton-background: <<colour background>>\nbutton-foreground: <<colour foreground>>\nbutton-border: <<colour foreground>>\ncode-background: <<colour background>>\ncode-border: <<colour foreground>>\ncode-foreground: <<colour foreground>>\ndirty-indicator: #f00\ndownload-background: #080\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: <<colour foreground>>\ndropdown-tab-background: <<colour foreground>>\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #00a\nexternal-link-foreground: #00e\nfootnote-target-background: #4c4c4c\nforeground: #fff\nhighlight-background: #ffff00\nhighlight-foreground: #000000\nmessage-background: <<colour foreground>>\nmessage-border: <<colour background>>\nmessage-foreground: <<colour background>>\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: <<colour foreground>>\nmodal-footer-background: <<colour background>>\nmodal-footer-border: <<colour foreground>>\nmodal-header-border: <<colour foreground>>\nmuted-foreground: <<colour foreground>>\nnotification-background: <<colour background>>\nnotification-border: <<colour foreground>>\npage-background: <<colour background>>\npre-background: <<colour background>>\npre-border: <<colour foreground>>\nprimary: #00f\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: <<colour background>>\nsidebar-controls-foreground: <<colour foreground>>\nsidebar-foreground-shadow: rgba(0,0,0, 0)\nsidebar-foreground: <<colour foreground>>\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: <<colour foreground>>\nsidebar-tab-background-selected: <<colour background>>\nsidebar-tab-background: <<colour tab-background>>\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: <<colour tab-border>>\nsidebar-tab-divider: <<colour tab-divider>>\nsidebar-tab-foreground-selected: <<colour foreground>>\nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: <<colour foreground>>\nsidebar-tiddler-link-foreground: <<colour primary>>\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: <<colour background>>\ntab-background: <<colour foreground>>\ntab-border-selected: <<colour foreground>>\ntab-border: <<colour foreground>>\ntab-divider: <<colour foreground>>\ntab-foreground-selected: <<colour foreground>>\ntab-foreground: <<colour background>>\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #fff\ntag-foreground: #000\ntiddler-background: <<colour background>>\ntiddler-border: <<colour foreground>>\ntiddler-controls-foreground-hover: #ddd\ntiddler-controls-foreground-selected: #fdd\ntiddler-controls-foreground: <<colour foreground>>\ntiddler-editor-background: <<colour background>>\ntiddler-editor-border-image: <<colour foreground>>\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: <<colour background>>\ntiddler-editor-fields-odd: <<colour background>>\ntiddler-info-background: <<colour background>>\ntiddler-info-border: <<colour foreground>>\ntiddler-info-tab-background: <<colour background>>\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: <<colour foreground>>\ntiddler-title-foreground: <<colour foreground>>\ntoolbar-new-button: \ntoolbar-options-button: \ntoolbar-save-button: \ntoolbar-info-button: \ntoolbar-edit-button: \ntoolbar-close-button: \ntoolbar-delete-button: \ntoolbar-cancel-button: \ntoolbar-done-button: \nuntagged-background: <<colour foreground>>\nvery-muted-foreground: #888888\n"},"$:/palettes/ContrastLight":{"title":"$:/palettes/ContrastLight","name":"Contrast (Light)","color-scheme":"light","description":"High contrast and unambiguous (light version)","tags":"$:/tags/Palette","type":"application/x-tiddler-dictionary","text":"alert-background: #f00\nalert-border: <<colour background>>\nalert-highlight: <<colour foreground>>\nalert-muted-foreground: #800\nbackground: #fff\nblockquote-bar: <<colour muted-foreground>>\nbutton-background: <<colour background>>\nbutton-foreground: <<colour foreground>>\nbutton-border: <<colour foreground>>\ncode-background: <<colour background>>\ncode-border: <<colour foreground>>\ncode-foreground: <<colour foreground>>\ndirty-indicator: #f00\ndownload-background: #080\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: <<colour foreground>>\ndropdown-tab-background: <<colour foreground>>\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #00a\nexternal-link-foreground: #00e\nfootnote-target-background: #e5e5e5\nforeground: #000\nhighlight-background: #ffff00\nhighlight-foreground: #000000\nmessage-background: <<colour foreground>>\nmessage-border: <<colour background>>\nmessage-foreground: <<colour background>>\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: <<colour foreground>>\nmodal-footer-background: <<colour background>>\nmodal-footer-border: <<colour foreground>>\nmodal-header-border: <<colour foreground>>\nmuted-foreground: <<colour foreground>>\nnotification-background: <<colour background>>\nnotification-border: <<colour foreground>>\npage-background: <<colour background>>\npre-background: <<colour background>>\npre-border: <<colour foreground>>\nprimary: #00f\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: <<colour background>>\nsidebar-controls-foreground: <<colour foreground>>\nsidebar-foreground-shadow: rgba(0,0,0, 0)\nsidebar-foreground: <<colour foreground>>\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: <<colour foreground>>\nsidebar-tab-background-selected: <<colour background>>\nsidebar-tab-background: <<colour tab-background>>\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: <<colour tab-border>>\nsidebar-tab-divider: <<colour tab-divider>>\nsidebar-tab-foreground-selected: <<colour foreground>>\nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: <<colour foreground>>\nsidebar-tiddler-link-foreground: <<colour primary>>\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: <<colour background>>\ntab-background: <<colour foreground>>\ntab-border-selected: <<colour foreground>>\ntab-border: <<colour foreground>>\ntab-divider: <<colour foreground>>\ntab-foreground-selected: <<colour foreground>>\ntab-foreground: <<colour background>>\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #000\ntag-foreground: #fff\ntiddler-background: <<colour background>>\ntiddler-border: <<colour foreground>>\ntiddler-controls-foreground-hover: #ddd\ntiddler-controls-foreground-selected: #fdd\ntiddler-controls-foreground: <<colour foreground>>\ntiddler-editor-background: <<colour background>>\ntiddler-editor-border-image: <<colour foreground>>\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: <<colour background>>\ntiddler-editor-fields-odd: <<colour background>>\ntiddler-info-background: <<colour background>>\ntiddler-info-border: <<colour foreground>>\ntiddler-info-tab-background: <<colour background>>\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: <<colour foreground>>\ntiddler-title-foreground: <<colour foreground>>\ntoolbar-new-button: \ntoolbar-options-button: \ntoolbar-save-button: \ntoolbar-info-button: \ntoolbar-edit-button: \ntoolbar-close-button: \ntoolbar-delete-button: \ntoolbar-cancel-button: \ntoolbar-done-button: \nuntagged-background: <<colour foreground>>\nvery-muted-foreground: #888888\n"},"$:/palettes/CupertinoDark":{"title":"$:/palettes/CupertinoDark","tags":"$:/tags/Palette","color-scheme":"dark","name":"Cupertino Dark","description":"A macOS inspired dark palette","type":"application/x-tiddler-dictionary","text":"alert-background: #FF453A\nalert-border: #FF453A\nalert-highlight: #FFD60A\nalert-muted-foreground: <<colour muted-foreground>>\nbackground: #282828\nblockquote-bar: <<colour page-background>>\nbutton-foreground: <<colour foreground>>\ncode-background: <<colour pre-background>>\ncode-border: <<colour pre-border>>\ncode-foreground: rgba(255, 255, 255, 0.54)\ndirty-indicator: #FF453A\ndownload-background: <<colour primary>>\ndownload-foreground: <<colour foreground>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour tiddler-info-background>>\ndropdown-border: <<colour dropdown-background>>\ndropdown-tab-background-selected: #3F638B\ndropdown-tab-background: #323232\ndropzone-background: #30D158\nexternal-link-background-hover: transparent\nexternal-link-background-visited: transparent\nexternal-link-background: transparent\nexternal-link-foreground-hover: \nexternal-link-foreground-visited: #BF5AF2\nexternal-link-foreground: #32D74B\nfootnote-target-background: #747474\nforeground: #FFFFFF\nhighlight-background: #ffff78\nhighlight-foreground: #000000\nmenubar-background: #464646\nmenubar-foreground: #ffffff\nmessage-background: <<colour background>>\nmessage-border: <<colour very-muted-foreground>>\nmessage-foreground: rgba(255, 255, 255, 0.54)\nmodal-backdrop: <<colour page-background>>\nmodal-background: <<colour background>>\nmodal-border: <<colour very-muted-foreground>>\nmodal-footer-background: <<colour background>>\nmodal-footer-border: <<colour background>>\nmodal-header-border: <<colour very-muted-foreground>>\nmuted-foreground: #98989D\nnotification-background: <<colour dropdown-background>>\nnotification-border: <<colour dropdown-background>>\npage-background: #323232\npre-background: #464646\npre-border: transparent\nprimary: #0A84FF\nselect-tag-background: <<colour background>>\nselect-tag-foreground: <<colour foreground>>\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #FF9F0A\nsidebar-controls-foreground: #8E8E93\nsidebar-foreground-shadow: transparent\nsidebar-foreground: rgba(255, 255, 255, 0.54)\nsidebar-muted-foreground-hover: rgba(255, 255, 255, 0.54)\nsidebar-muted-foreground: rgba(255, 255, 255, 0.38)\nsidebar-tab-background-selected: #3F638B\nsidebar-tab-background: <<colour background>>\nsidebar-tab-border-selected: <<colour background>>\nsidebar-tab-border: <<colour background>>\nsidebar-tab-divider: <<colour background>>\nsidebar-tab-foreground-selected: rgba(255, 255, 255, 0.87)\nsidebar-tab-foreground: rgba(255, 255, 255, 0.54)\nsidebar-tiddler-link-foreground-hover: rgba(255, 255, 255, 0.7)\nsidebar-tiddler-link-foreground: rgba(255, 255, 255, 0.54)\nsite-title-foreground: #ffffff\nstatic-alert-foreground: #B4B4B4\ntab-background-selected: #3F638B\ntab-background: <<colour page-background>>\ntab-border-selected: <<colour page-background>>\ntab-border: <<colour page-background>>\ntab-divider: <<colour page-background>>\ntab-foreground-selected: rgba(255, 255, 255, 0.87)\ntab-foreground: rgba(255, 255, 255, 0.54)\ntable-border: #464646\ntable-footer-background: <<colour tiddler-editor-fields-odd>>\ntable-header-background: <<colour tiddler-editor-fields-even>>\ntag-background: #48484A\ntag-foreground: #323232\ntiddler-background: <<colour background>>\ntiddler-border: transparent\ntiddler-controls-foreground-hover: <<colour sidebar-controls-foreground-hover>>\ntiddler-controls-foreground-selected: <<colour sidebar-controls-foreground-hover>>\ntiddler-controls-foreground: #48484A\ntiddler-editor-background: <<colour background>>\ntiddler-editor-border-image: \ntiddler-editor-border: rgba(255, 255, 255, 0.08)\ntiddler-editor-fields-even: rgba(255, 255, 255, 0.1)\ntiddler-editor-fields-odd: rgba(255, 255, 255, 0.04)\ntiddler-info-background: #1E1E1E\ntiddler-info-border: #1E1E1E\ntiddler-info-tab-background: #3F638B\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: <<colour muted-foreground>>\ntiddler-title-foreground: #FFFFFF\ntoolbar-new-button: \ntoolbar-options-button: \ntoolbar-save-button: \ntoolbar-info-button: \ntoolbar-edit-button: \ntoolbar-close-button: \ntoolbar-delete-button: \ntoolbar-cancel-button: \ntoolbar-done-button: \nuntagged-background: <<colour very-muted-foreground>>\nvery-muted-foreground: #464646\nselection-background: #3F638B\nselection-foreground: #ffffff\nwikilist-background: <<colour page-background>>\nwikilist-button-background: #3F638B\nwikilist-button-foreground: <<colour foreground>>\nwikilist-button-open: #32D74B\nwikilist-button-open-hover: #32D74B\nwikilist-button-reveal: #0A84FF\nwikilist-button-reveal-hover: #0A84FF\nwikilist-button-remove: #FF453A\nwikilist-button-remove-hover: #FF453A\nwikilist-droplink-dragover: #32D74B\nwikilist-item: <<colour background>>\nwikilist-toolbar-background: <<colour background>>\nwikilist-title: <<colour foreground>>\nwikilist-title-svg: <<colour foreground>>\nwikilist-toolbar-foreground: <<colour foreground>>\nwikilist-url: <<colour muted-foreground>>\n"},"$:/palettes/DarkPhotos":{"title":"$:/palettes/DarkPhotos","created":"20150402111612188","description":"Good with dark photo backgrounds","modified":"20150402112344080","name":"DarkPhotos","tags":"$:/tags/Palette","type":"application/x-tiddler-dictionary","color-scheme":"light","text":"alert-background: #ffe476\nalert-border: #b99e2f\nalert-highlight: #881122\nalert-muted-foreground: #b99e2f\nbackground: #ffffff\nblockquote-bar: <<colour muted-foreground>>\nbutton-background: \nbutton-foreground: \nbutton-border: \ncode-background: #f7f7f9\ncode-border: #e1e1e8\ncode-foreground: #dd1144\ndirty-indicator: #ff0000\ndownload-background: #34c734\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: #fff\ndropdown-tab-background: #ececec\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #0000aa\nexternal-link-foreground: #0000ee\nfootnote-target-background: #ecf2ff\nforeground: #333333\nhighlight-background: #ffff00\nhighlight-foreground: #000000\nmessage-background: #ecf2ff\nmessage-border: #cfd6e6\nmessage-foreground: #547599\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: #999999\nmodal-footer-background: #f5f5f5\nmodal-footer-border: #dddddd\nmodal-header-border: #eeeeee\nmuted-foreground: #ddd\nnotification-background: #ffffdd\nnotification-border: #999999\npage-background: #336438\npre-background: #f5f5f5\npre-border: #cccccc\nprimary: #5778d8\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #ccf\nsidebar-controls-foreground: #fff\nsidebar-foreground-shadow: rgba(0,0,0, 0.5)\nsidebar-foreground: #fff\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: #eee\nsidebar-tab-background-selected: rgba(255,255,255, 0.8)\nsidebar-tab-background: rgba(255,255,255, 0.4)\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: <<colour tab-border>>\nsidebar-tab-divider: rgba(255,255,255, 0.2)\nsidebar-tab-foreground-selected: \nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: #aaf\nsidebar-tiddler-link-foreground: #ddf\nsite-title-foreground: #fff\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: #ffffff\ntab-background: #d8d8d8\ntab-border-selected: #d8d8d8\ntab-border: #cccccc\ntab-divider: #d8d8d8\ntab-foreground-selected: <<colour tab-foreground>>\ntab-foreground: #666666\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #ec6\ntag-foreground: #ffffff\ntiddler-background: <<colour background>>\ntiddler-border: <<colour background>>\ntiddler-controls-foreground-hover: #888888\ntiddler-controls-foreground-selected: #444444\ntiddler-controls-foreground: #cccccc\ntiddler-editor-background: #f8f8f8\ntiddler-editor-border-image: #ffffff\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: #e0e8e0\ntiddler-editor-fields-odd: #f0f4f0\ntiddler-info-background: #f8f8f8\ntiddler-info-border: #dddddd\ntiddler-info-tab-background: #f8f8f8\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: #c0c0c0\ntiddler-title-foreground: #182955\ntoolbar-new-button: \ntoolbar-options-button: \ntoolbar-save-button: \ntoolbar-info-button: \ntoolbar-edit-button: \ntoolbar-close-button: \ntoolbar-delete-button: \ntoolbar-cancel-button: \ntoolbar-done-button: \nuntagged-background: #999999\nvery-muted-foreground: #888888\n"},"$:/palettes/DesertSand":{"title":"$:/palettes/DesertSand","tags":"$:/tags/Palette","color-scheme":"light","name":"Desert Sand","description":"A desert sand palette","type":"application/x-tiddler-dictionary","text":"alert-background: #ffe476\nalert-border: #b99e2f\nalert-highlight: #881122\nalert-muted-foreground: #b99e2f\nbackground: #E9E0C7\nblockquote-bar: <<colour muted-foreground>>\nbutton-foreground: <<colour foreground>>\ncode-background: #F3EDDF\ncode-border: #C3BAA1\ncode-foreground: #ab3250\ndiff-delete-background: #bd8b8b\ndiff-delete-foreground: <<colour foreground>>\ndiff-equal-background: \ndiff-equal-foreground: <<colour foreground>>\ndiff-insert-background: #91c093\ndiff-insert-foreground: <<colour foreground>>\ndiff-invisible-background: \ndiff-invisible-foreground: <<colour muted-foreground>>\ndirty-indicator: #ad3434\ndownload-background: #6ca16c\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: #E9E0C7\ndropdown-tab-background: #BAB29C\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #313163\nexternal-link-foreground: #555592\nfootnote-target-background: #fff7d9\nforeground: #2D2A23\nhighlight-background: #ffff00\nhighlight-foreground: #000000\nmenubar-background: #CDC2A6\nmenubar-foreground: #5A5446\nmessage-background: #ECE5CF\nmessage-border: #D6CBAA\nmessage-foreground: #5f6e7d\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: #8A8885\nmodal-footer-background: #CDC2A6\nmodal-footer-border: #9D998E\nmodal-header-border: #9D998E\nmuted-foreground: #9D998E\nnotification-background: #F0E9D7\nnotification-border: #939189\npage-background: #e0d3af\npre-background: #D6CBAA\npre-border: #CDC2A6\nprimary: #5B6F55\nselection-background: #9D947B\nselection-foreground: <<colour foreground>>\nselect-tag-background: #F0E9D7\nselect-tag-foreground: #2D2A23\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #2D2A23\nsidebar-controls-foreground: #867F69\nsidebar-foreground-shadow: transparent\nsidebar-foreground: #867F69\nsidebar-muted-foreground-hover: #706A58\nsidebar-muted-foreground: #B3A98C\nsidebar-tab-background-selected: #e0d3af\nsidebar-tab-background: #A6A193\nsidebar-tab-border-selected: #C3BAA1\nsidebar-tab-border: #C3BAA1\nsidebar-tab-divider: #CDC2A6\nsidebar-tab-foreground-selected: \nsidebar-tab-foreground: #2D2A23\nsidebar-tiddler-link-foreground-hover: #433F35\nsidebar-tiddler-link-foreground: #706A58\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstatic-alert-foreground: #A6A193\ntab-background-selected: #E9E0C7\ntab-background: #A6A193\ntab-border-selected: #C3BAA1\ntab-border: #C3BAA1\ntab-divider: #CDC2A6\ntab-foreground-selected: <<colour tab-foreground>>\ntab-foreground: #2D2A23\ntable-border: #9D998E\ntable-footer-background: #8A8885\ntable-header-background: #B0AA98\ntag-background: #706A58\ntag-foreground: #E3D7B7\ntiddler-background: <<colour background>>\ntiddler-border: <<colour background>>\ntiddler-controls-foreground-hover: #9D947B\ntiddler-controls-foreground-selected: #706A58\ntiddler-controls-foreground: #C3BAA1\ntiddler-editor-background: #E9E0C7\ntiddler-editor-border-image: #A6A193\ntiddler-editor-border: #A6A193\ntiddler-editor-fields-even: #D6CBAA\ntiddler-editor-fields-odd: #C3BAA1\ntiddler-info-background: #E3D7B7\ntiddler-info-border: #BAB29C\ntiddler-info-tab-background: #E9E0C7\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: #867F69\ntiddler-title-foreground: #374464\ntoolbar-new-button: \ntoolbar-options-button: \ntoolbar-save-button: \ntoolbar-info-button: \ntoolbar-edit-button: \ntoolbar-close-button: \ntoolbar-delete-button: \ntoolbar-cancel-button: \ntoolbar-done-button: \nuntagged-background: #8A8885\nvery-muted-foreground: #CDC2A6\nwikilist-background: <<colour page-background>>\nwikilist-item: #CDC2A6\nwikilist-info: #161512\nwikilist-title: #433F35\nwikilist-title-svg: <<colour wikilist-title>>\nwikilist-url: #706A58\nwikilist-button-open: #7db66a\nwikilist-button-open-hover: #56a556\nwikilist-button-reveal: #5a6c9e\nwikilist-button-reveal-hover: #454591\nwikilist-button-remove: #bc5972\nwikilist-button-remove-hover: #814040\nwikilist-toolbar-background: #CDC2A6\nwikilist-toolbar-foreground: #2D2A23\nwikilist-droplink-dragover: rgba(255,192,192,0.5)\nwikilist-button-background: #A6A193\nwikilist-button-foreground: #161512\n"},"$:/palettes/GruvboxDark":{"title":"$:/palettes/GruvboxDark","name":"Gruvbox Dark","color-scheme":"dark","description":"Retro groove color scheme","tags":"$:/tags/Palette","type":"application/x-tiddler-dictionary","license":"https://github.com/morhetz/gruvbox","text":"alert-background: #cc241d\nalert-border: #cc241d\nalert-highlight: #d79921\nalert-muted-foreground: #504945\nbackground: #3c3836\nblockquote-bar: <<colour muted-foreground>>\nbutton-foreground: <<colour foreground>>\ncode-background: #504945\ncode-border: #504945\ncode-foreground: #fb4934\ndiff-delete-background: #fb4934\ndiff-delete-foreground: <<colour foreground>>\ndiff-equal-background: \ndiff-equal-foreground: <<colour foreground>>\ndiff-insert-background: #b8bb26\ndiff-insert-foreground: <<colour foreground>>\ndiff-invisible-background: \ndiff-invisible-foreground: <<colour muted-foreground>>\ndirty-indicator: #fb4934\ndownload-background: #b8bb26\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: #665c54\ndropdown-border: <<colour background>>\ndropdown-tab-background-selected: #ebdbb2\ndropdown-tab-background: #665c54\ndropzone-background: #98971a\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #d3869b\nexternal-link-foreground: #8ec07c\nfootnote-target-background: #665c54\nforeground: #fbf1c7\nhighlight-background: #ffff79\nhighlight-foreground: #000000\nmenubar-background: #504945\nmenubar-foreground: <<colour foreground>>\nmessage-background: #83a598\nmessage-border: #83a598\nmessage-foreground: #3c3836\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: #504945\nmodal-footer-background: #3c3836\nmodal-footer-border: #3c3836\nmodal-header-border: #3c3836\nmuted-foreground: #d5c4a1\nnotification-background: <<colour primary>>\nnotification-border: <<colour primary>>\npage-background: #282828\npre-background: #504945\npre-border: #504945\nprimary: #d79921\nselect-tag-background: #665c54\nselect-tag-foreground: <<colour foreground>>\nselection-background: #458588\nselection-foreground: <<colour foreground>>\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #7c6f64\nsidebar-controls-foreground: #504945\nsidebar-foreground-shadow: transparent\nsidebar-foreground: #fbf1c7\nsidebar-muted-foreground-hover: #7c6f64\nsidebar-muted-foreground: #504945\nsidebar-tab-background-selected: #bdae93\nsidebar-tab-background: #3c3836\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: #bdae93\nsidebar-tab-divider: <<colour page-background>>\nsidebar-tab-foreground-selected: #282828\nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: #458588\nsidebar-tiddler-link-foreground: #98971a\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstability-deprecated: #cc241d\nstability-experimental: #d79921\nstability-legacy: #458588\nstability-stable: #98971a\nstatic-alert-foreground: #B48EAD\ntab-background-selected: #ebdbb2\ntab-background: #665c54\ntab-border-selected: #665c54\ntab-border: #665c54\ntab-divider: #bdae93\ntab-foreground-selected: #282828\ntab-foreground: #ebdbb2\ntable-border: #7c6f64\ntable-footer-background: #665c54\ntable-header-background: #504945\ntag-background: #d3869b\ntag-foreground: #282828\ntiddler-background: <<colour background>>\ntiddler-border: <<colour background>>\ntiddler-controls-foreground-hover: #7c6f64\ntiddler-controls-foreground-selected: <<colour primary>>\ntiddler-controls-foreground: #665c54\ntiddler-editor-background: #32302f\ntiddler-editor-border-image: #282828\ntiddler-editor-border: #282828\ntiddler-editor-fields-even: #504945\ntiddler-editor-fields-odd: #7c6f64\ntiddler-info-background: #32302f\ntiddler-info-border: #ebdbb2\ntiddler-info-tab-background: #ebdbb2\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: #7c6f64\ntiddler-title-foreground: #a89984\ntoolbar-new-button: \ntoolbar-options-button: \ntoolbar-save-button: \ntoolbar-info-button: \ntoolbar-edit-button: \ntoolbar-close-button: \ntoolbar-delete-button: \ntoolbar-cancel-button: \ntoolbar-done-button: \nuntagged-background: #504945\nvery-muted-foreground: #bdae93\nwikilist-background: <<colour page-background>>\nwikilist-button-background: #acacac\nwikilist-button-foreground: <<colour button-foreground>>\nwikilist-item: <<colour background>>\nwikilist-toolbar-background: <<colour background>>\nwikilist-toolbar-foreground: <<colour foreground>>\nwikilist-title: <<colour foreground>>\nwikilist-title-svg: <<colour wikilist-title>>\nwikilist-url: <<colour muted-foreground>>\nwikilist-button-open-hover: <<colour primary>>\nwikilist-button-open: <<colour dropzone-background>>\nwikilist-button-remove: <<colour dirty-indicator>>\nwikilist-button-remove-hover: <<colour alert-background>>\nwikilist-droplink-dragover: <<colour dropzone-background>>\nwikilist-button-reveal: <<colour sidebar-tiddler-link-foreground-hover>>\nwikilist-button-reveal-hover: <<colour message-background>>\n"},"$:/palettes/Nord":{"title":"$:/palettes/Nord","name":"Nord","color-scheme":"dark","description":"An arctic, north-bluish color palette.","tags":"$:/tags/Palette","type":"application/x-tiddler-dictionary","license":"MIT, arcticicestudio, https://github.com/arcticicestudio/nord/blob/develop/LICENSE.md","text":"alert-background: #D08770\nalert-border: #D08770\nalert-highlight: #B48EAD\nalert-muted-foreground: #4C566A\nbackground: #3b4252\nblockquote-bar: <<colour muted-foreground>>\nbutton-foreground: <<colour foreground>>\ncode-background: #2E3440\ncode-border: #2E3440\ncode-foreground: #BF616A\ndiff-delete-background: #BF616A\ndiff-delete-foreground: <<colour foreground>>\ndiff-equal-background: \ndiff-equal-foreground: <<colour foreground>>\ndiff-insert-background: #A3BE8C\ndiff-insert-foreground: <<colour foreground>>\ndiff-invisible-background: \ndiff-invisible-foreground: <<colour muted-foreground>>\ndirty-indicator: #BF616A\ndownload-background: #A3BE8C\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour background>>\ndropdown-tab-background-selected: #ECEFF4\ndropdown-tab-background: #4C566A\ndropzone-background: #A3BE8C\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #5E81AC\nexternal-link-foreground: #8FBCBB\nfootnote-target-background: #2E3440\nforeground: #d8dee9\nhighlight-background: #ffff78\nhighlight-foreground: #000000\nmenubar-background: #2E3440\nmenubar-foreground: #d8dee9\nmessage-background: #2E3440\nmessage-border: #2E3440\nmessage-foreground: #547599\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: #3b4252\nmodal-footer-background: #3b4252\nmodal-footer-border: #3b4252\nmodal-header-border: #3b4252\nmuted-foreground: #4C566A\nnotification-background: <<colour primary>>\nnotification-border: #EBCB8B\npage-background: #2e3440\npre-background: #2E3440\npre-border: #2E3440\nprimary: #5E81AC\nselect-tag-background: #3b4252\nselect-tag-foreground: <<colour foreground>>\nselection-background: #5E81AC\nselection-foreground: <<colour foreground>>\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #D8DEE9\nsidebar-controls-foreground: #4C566A\nsidebar-foreground-shadow: transparent\nsidebar-foreground: #D8DEE9\nsidebar-muted-foreground-hover: #4C566A\nsidebar-muted-foreground: #4C566A\nsidebar-tab-background-selected: #ECEFF4\nsidebar-tab-background: #4C566A\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: #4C566A\nsidebar-tab-divider: <<colour page-background>>\nsidebar-tab-foreground-selected: #4C566A\nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: #A3BE8C\nsidebar-tiddler-link-foreground: #81A1C1\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstability-deprecated: #bf616a\nstability-experimental: #d08770\nstability-legacy: #88c0d0\nstability-stable: #a3be8c\nstatic-alert-foreground: #B48EAD\ntab-background-selected: #ECEFF4\ntab-background: #4C566A\ntab-border-selected: #4C566A\ntab-border: #4C566A\ntab-divider: #4C566A\ntab-foreground-selected: #4C566A\ntab-foreground: #D8DEE9\ntable-border: #4C566A\ntable-footer-background: #2e3440\ntable-header-background: #2e3440\ntag-background: #A3BE8C\ntag-foreground: #4C566A\ntiddler-background: <<colour background>>\ntiddler-border: <<colour background>>\ntiddler-controls-foreground-hover: \ntiddler-controls-foreground-selected: #EBCB8B\ntiddler-controls-foreground: #4C566A\ntiddler-editor-background: #2e3440\ntiddler-editor-border-image: #2e3440\ntiddler-editor-border: #3b4252\ntiddler-editor-fields-even: #2e3440\ntiddler-editor-fields-odd: #2e3440\ntiddler-info-background: #2e3440\ntiddler-info-border: #2e3440\ntiddler-info-tab-background: #2e3440\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: #4C566A\ntiddler-title-foreground: #81A1C1\ntoolbar-new-button: \ntoolbar-options-button: \ntoolbar-save-button: \ntoolbar-info-button: \ntoolbar-edit-button: \ntoolbar-close-button: \ntoolbar-delete-button: \ntoolbar-cancel-button: \ntoolbar-done-button: \nuntagged-background: #2d3038\nvery-muted-foreground: #2d3038\nwikilist-background: <<colour page-background>>\nwikilist-toolbar-background: <<colour background>>\nwikilist-item: <<colour background>>\nwikilist-title: <<colour foreground>>\nwikilist-info: <<colour muted-foreground>>\nwikilist-button-open: #A3BE8C\nwikilist-button-open-hover: #A3BE8C\nwikilist-button-reveal: #81A1C1\nwikilist-button-reveal-hover: #81A1C1\nwikilist-button-remove: #B48EAD\nwikilist-button-remove-hover: #B48EAD\n"},"$:/palettes/Rocker":{"title":"$:/palettes/Rocker","name":"Rocker","color-scheme":"dark","description":"A dark theme","tags":"$:/tags/Palette","type":"application/x-tiddler-dictionary","text":"alert-background: #ffe476\nalert-border: #b99e2f\nalert-highlight: #881122\nalert-muted-foreground: #b99e2f\nbackground: #ffffff\nblockquote-bar: <<colour muted-foreground>>\nbutton-background:\nbutton-foreground:\nbutton-border:\ncode-background: #f7f7f9\ncode-border: #e1e1e8\ncode-foreground: #dd1144\ndirty-indicator: #ff0000\ndownload-background: #34c734\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: #fff\ndropdown-tab-background: #ececec\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #0000aa\nexternal-link-foreground: #0000ee\nfootnote-target-background: #ecf2ff\nforeground: #333333\nhighlight-background: #ffff00\nhighlight-foreground: #000000\nmessage-background: #ecf2ff\nmessage-border: #cfd6e6\nmessage-foreground: #547599\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: #999999\nmodal-footer-background: #f5f5f5\nmodal-footer-border: #dddddd\nmodal-header-border: #eeeeee\nmuted-foreground: #999999\nnotification-background: #ffffdd\nnotification-border: #999999\npage-background: #000\npre-background: #f5f5f5\npre-border: #cccccc\nprimary: #cc0000\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #000000\nsidebar-controls-foreground: #ffffff\nsidebar-foreground-shadow: rgba(255,255,255, 0.0)\nsidebar-foreground: #acacac\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: #c0c0c0\nsidebar-tab-background-selected: #000\nsidebar-tab-background: <<colour tab-background>>\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: <<colour tab-border>>\nsidebar-tab-divider: <<colour tab-divider>>\nsidebar-tab-foreground-selected: \nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: #ffbb99\nsidebar-tiddler-link-foreground: #cc0000\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: #ffffff\ntab-background: #d8d8d8\ntab-border-selected: #d8d8d8\ntab-border: #cccccc\ntab-divider: #d8d8d8\ntab-foreground-selected: <<colour tab-foreground>>\ntab-foreground: #666666\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #ffbb99\ntag-foreground: #000\ntiddler-background: <<colour background>>\ntiddler-border: <<colour background>>\ntiddler-controls-foreground-hover: #888888\ntiddler-controls-foreground-selected: #444444\ntiddler-controls-foreground: #cccccc\ntiddler-editor-background: #f8f8f8\ntiddler-editor-border-image: #ffffff\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: #e0e8e0\ntiddler-editor-fields-odd: #f0f4f0\ntiddler-info-background: #f8f8f8\ntiddler-info-border: #dddddd\ntiddler-info-tab-background: #f8f8f8\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: #c0c0c0\ntiddler-title-foreground: #cc0000\ntoolbar-new-button:\ntoolbar-options-button:\ntoolbar-save-button:\ntoolbar-info-button:\ntoolbar-edit-button:\ntoolbar-close-button:\ntoolbar-delete-button:\ntoolbar-cancel-button:\ntoolbar-done-button:\nuntagged-background: #999999\nvery-muted-foreground: #888888\n"},"$:/palettes/SolarFlare":{"title":"$:/palettes/SolarFlare","name":"Solar Flare","color-scheme":"light","description":"Warm, relaxing earth colours","tags":"$:/tags/Palette","type":"application/x-tiddler-dictionary","text":": Background Tones\n\nbase03: #002b36\nbase02: #073642\n\n: Content Tones\n\nbase01: #586e75\nbase00: #657b83\nbase0: #839496\nbase1: #93a1a1\n\n: Background Tones\n\nbase2: #eee8d5\nbase3: #fdf6e3\n\n: Accent Colors\n\nyellow: #b58900\norange: #cb4b16\nred: #dc322f\nmagenta: #d33682\nviolet: #6c71c4\nblue: #268bd2\ncyan: #2aa198\ngreen: #859900\n\n: Additional Tones (RA)\n\nbase10: #c0c4bb\nviolet-muted: #7c81b0\nblue-muted: #4e7baa\n\nyellow-hot: #ffcc44\norange-hot: #eb6d20\nred-hot: #ff2222\nblue-hot: #2298ee\ngreen-hot: #98ee22\n\n: Palette\n\n: Do not use colour macro for background and foreground\nbackground: #fdf6e3\n    download-foreground: <<colour background>>\n    dragger-foreground: <<colour background>>\n    dropdown-background: <<colour background>>\n    modal-background: <<colour background>>\n    sidebar-foreground-shadow: <<colour background>>\n    tiddler-background: <<colour background>>\n    tiddler-border: <<colour background>>\n    tiddler-link-background: <<colour background>>\n    tab-background-selected: <<colour background>>\n        dropdown-tab-background-selected: <<colour tab-background-selected>>\nforeground: #657b83\n    dragger-background: <<colour foreground>>\n    tab-foreground: <<colour foreground>>\n        tab-foreground-selected: <<colour tab-foreground>>\n            sidebar-tab-foreground-selected: <<colour tab-foreground-selected>>\n        sidebar-tab-foreground: <<colour tab-foreground>>\n    sidebar-button-foreground: <<colour foreground>>\n    sidebar-controls-foreground: <<colour foreground>>\n    sidebar-foreground: <<colour foreground>>\n: base03\n: base02\n: base01\n    alert-muted-foreground: <<colour base01>>\n: base00\n    code-foreground: <<colour base00>>\n    message-foreground: <<colour base00>>\n    tag-foreground: <<colour base00>>\n: base0\n    sidebar-tiddler-link-foreground: <<colour base0>>\n: base1\n    muted-foreground: <<colour base1>>\n        blockquote-bar: <<colour muted-foreground>>\n        dropdown-border: <<colour muted-foreground>>\n        sidebar-muted-foreground: <<colour muted-foreground>>\n        tiddler-title-foreground: <<colour muted-foreground>>\n            site-title-foreground: <<colour tiddler-title-foreground>>\n: base2\n    modal-footer-background: <<colour base2>>\n    page-background: <<colour base2>>\n        modal-backdrop: <<colour page-background>>\n        notification-background: <<colour page-background>>\n        code-background: <<colour page-background>>\n            code-border: <<colour code-background>>\n        pre-background: <<colour page-background>>\n            pre-border: <<colour pre-background>>\n        sidebar-tab-background-selected: <<colour page-background>>\n    table-header-background: <<colour base2>>\n    tag-background: <<colour base2>>\n    tiddler-editor-background: <<colour base2>>\n    tiddler-info-background: <<colour base2>>\n    tiddler-info-tab-background: <<colour base2>>\n    tab-background: <<colour base2>>\n        dropdown-tab-background: <<colour tab-background>>\n: base3\n    alert-background: <<colour base3>>\n    message-background: <<colour base3>>\n: yellow\n: orange\n: red\n: magenta\n    alert-highlight: <<colour magenta>>\n: violet\n    external-link-foreground: <<colour violet>>\n: blue\n: cyan\n: green\n: base10\n    tiddler-controls-foreground: <<colour base10>>\n: violet-muted\n    external-link-foreground-visited: <<colour violet-muted>>\n: blue-muted\n    primary: <<colour blue-muted>>\n        download-background: <<colour primary>>\n        tiddler-link-foreground: <<colour primary>>\n\nalert-border: #b99e2f\ndirty-indicator: #ff0000\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nfootnote-target-background: #ded8c5\nhighlight-background: #ffff00\nhighlight-foreground: #000000\nmessage-border: #cfd6e6\nmodal-border: #999999\nselect-tag-background:\nselect-tag-foreground:\nsidebar-controls-foreground-hover:\nsidebar-muted-foreground-hover:\nsidebar-tab-background: #ded8c5\nsidebar-tiddler-link-foreground-hover:\nstability-deprecated: <<colour red>>\nstability-experimental: <<colour yellow>>\nstability-legacy: <<colour blue>>\nstability-stable: <<colour green>>\nstatic-alert-foreground: #aaaaaa\ntab-border: #cccccc\n    modal-footer-border: <<colour tab-border>>\n    modal-header-border: <<colour tab-border>>\n    notification-border: <<colour tab-border>>\n    sidebar-tab-border: <<colour tab-border>>\n    tab-border-selected: <<colour tab-border>>\n        sidebar-tab-border-selected: <<colour tab-border-selected>>\ntab-divider: #d8d8d8\n    sidebar-tab-divider: <<colour tab-divider>>\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntiddler-controls-foreground-hover: #888888\ntiddler-controls-foreground-selected: #444444\ntiddler-editor-border-image: #ffffff\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: #e0e8e0\ntiddler-editor-fields-odd: #f0f4f0\ntiddler-info-border: #dddddd\ntiddler-subtitle-foreground: #c0c0c0\ntoolbar-new-button:\ntoolbar-options-button:\ntoolbar-save-button:\ntoolbar-info-button:\ntoolbar-edit-button:\ntoolbar-close-button:\ntoolbar-delete-button:\ntoolbar-cancel-button:\ntoolbar-done-button:\nuntagged-background: #999999\nvery-muted-foreground: #888888\n"},"$:/palettes/SolarizedDark":{"title":"$:/palettes/SolarizedDark","tags":"$:/tags/Palette","type":"application/x-tiddler-dictionary","description":"Precision dark colors for machines and people","license":"MIT, Ethan Schoonover, https://github.com/altercation/solarized/blob/master/LICENSE","name":"SolarizedDark","color-scheme":"dark","text":"alert-background: #073642\nalert-border: #93a1a1\nalert-highlight: #d33682\nalert-muted-foreground: #d33682\nbackground: #073642\nblockquote-bar: #d33682\nbutton-background: #073642\nbutton-border: #586e75\nbutton-foreground: #93a1a1\ncode-background: #073642\ncode-border: #586e75\ncode-foreground: #93a1a1\ndirty-indicator: #dc322f\ndownload-background: #859900\ndownload-foreground: #073642\ndragger-background: #073642\ndragger-foreground: #839496\ndropdown-background: #073642\ndropdown-border: #93a1a1\ndropdown-tab-background: #002b36\ndropdown-tab-background-selected: #073642\ndropzone-background: #859900\nexternal-link-background: inherit\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-foreground: #268bd2\nexternal-link-foreground-hover:\nexternal-link-foreground-visited: #268bd2\nfootnote-target-background: #073642\nforeground: #839496\nhighlight-background: #ffff78\nhighlight-foreground: #000000\nmessage-background: #002b36\nmessage-border: #586e75\nmessage-foreground: #839496\nmodal-backdrop: #657b83\nmodal-background: #002b36\nmodal-border: #586e75\nmodal-footer-background: #073642\nmodal-footer-border: #586e75\nmodal-header-border: #586e75\nmuted-foreground: #93a1a1\nnotification-background: #002b36\nnotification-border: #586e75\npage-background: #073642\npre-background: inherit\npre-border: #657b83\nprimary: #859900\nselect-tag-background: #002b36\nselect-tag-foreground: #839496\nsidebar-button-foreground: #93a1a1\nsidebar-controls-foreground: #93a1a1\nsidebar-controls-foreground-hover: #eee8d5\nsidebar-foreground: #93a1a1\nsidebar-foreground-shadow: transparent\nsidebar-muted-foreground: #839496\nsidebar-muted-foreground-hover: #93a1a1\nsidebar-tab-background: #002b36\nsidebar-tab-background-selected: #073642\nsidebar-tab-border: #073642\nsidebar-tab-border-selected: #839496\nsidebar-tab-divider: #002b36\nsidebar-tab-foreground: #657b83\nsidebar-tab-foreground-selected: #93a1a1\nsidebar-tiddler-link-foreground: #2aa198\nsidebar-tiddler-link-foreground-hover: #eee8d5\nsite-title-foreground: #d33682\nstability-deprecated: #dc322f\nstability-experimental: #b58900\nstability-legacy: #268bd2\nstability-stable: #859900\nstatic-alert-foreground: #93a1a1\ntab-background: #073642\ntab-background-selected: #002b36\ntab-border: #586e75\ntab-border-selected: #93a1a1\ntab-divider: #93a1a1\ntab-foreground: #839496\ntab-foreground-selected: #93a1a1\ntable-border: #586e75\ntable-footer-background: #073642\ntable-header-background: #073642\ntag-background: #b58900\ntag-foreground: #002b36\ntiddler-background: #002b36\ntiddler-border: #586e75\ntiddler-controls-foreground: inherit\ntiddler-controls-foreground-hover: #d33682\ntiddler-controls-foreground-selected: #2aa198\ntiddler-editor-background: #002b36\ntiddler-editor-border: #073642\ntiddler-editor-border-image: #002b36\ntiddler-editor-fields-even: #002b36\ntiddler-editor-fields-odd: #073642\ntiddler-info-background: #073642\ntiddler-info-border: #657b83\ntiddler-info-tab-background: #002b36\ntiddler-link-background: #002b36\ntiddler-link-foreground: #2aa198\ntiddler-subtitle-foreground: #839496\ntiddler-title-foreground: #d33682\ntoolbar-cancel-button: #839496\ntoolbar-close-button: #839496\ntoolbar-delete-button: #dc322f\ntoolbar-done-button: #839496\ntoolbar-edit-button: #839496\ntoolbar-info-button: #839496\ntoolbar-new-button: #839496\ntoolbar-options-button: #839496\ntoolbar-save-button: inherit\nuntagged-background: #586e75\nvery-muted-foreground: #586e75\n"},"$:/palettes/SolarizedLight":{"title":"$:/palettes/SolarizedLight","tags":"$:/tags/Palette","type":"application/x-tiddler-dictionary","description":"Precision colors for machines and people","license":"MIT, Ethan Schoonover, https://github.com/altercation/solarized/blob/master/LICENSE","name":"SolarizedLight","color-scheme":"light","text":"alert-background: #eee8d5\nalert-border: #586e75\nalert-highlight: #d33682\nalert-muted-foreground: #d33682\nbackground: #eee8d5\nblockquote-bar: #d33682\nbutton-background: #eee8d5\nbutton-border: #93a1a1\nbutton-foreground: #586e75\ncode-background: #eee8d5\ncode-border: #93a1a1\ncode-foreground: #586e75\ndirty-indicator: #dc322f\ndownload-background: #859900\ndownload-foreground: #eee8d5\ndragger-background: #eee8d5\ndragger-foreground: #657b83\ndropdown-background: #eee8d5\ndropdown-border: #586e75\ndropdown-tab-background: #fdf6e3\ndropdown-tab-background-selected: #eee8d5\ndropzone-background: #859900\nexternal-link-background: inherit\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-foreground: #268bd2\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #268bd2\nfootnote-target-background: #eee8d5\nforeground: #657b83\nhighlight-background: #ffff00\nhighlight-foreground: #000000\nmessage-background: #fdf6e3\nmessage-border: #93a1a1\nmessage-foreground: #657b83\nmodal-backdrop: #839496\nmodal-background: #fdf6e3\nmodal-border: #93a1a1\nmodal-footer-background: #eee8d5\nmodal-footer-border: #93a1a1\nmodal-header-border: #93a1a1\nmuted-foreground: #586e75\nnotification-background: #fdf6e3\nnotification-border: #93a1a1\npage-background: #eee8d5\npre-background: #eee8d5\npre-border: #839496\nprimary: #859900\nselect-tag-background: #fdf6e3\nselect-tag-foreground: #657b83\nsidebar-button-foreground: #586e75\nsidebar-controls-foreground: #586e75\nsidebar-controls-foreground-hover: #d33682\nsidebar-foreground: #586e75\nsidebar-foreground-shadow: transparent\nsidebar-muted-foreground: #657b83\nsidebar-muted-foreground-hover: #586e75\nsidebar-tab-background: #fdf6e3\nsidebar-tab-background-selected: #eee8d5\nsidebar-tab-border: #eee8d5\nsidebar-tab-border-selected: #657b83\nsidebar-tab-divider: #fdf6e3\nsidebar-tab-foreground: #839496\nsidebar-tab-foreground-selected: #586e75\nsidebar-tiddler-link-foreground: #2aa198\nsidebar-tiddler-link-foreground-hover: #002b36\nsite-title-foreground: #d33682\nstability-deprecated: #dc322f\nstability-experimental: #b58900\nstability-legacy: #268bd2\nstability-stable: #859900\nstatic-alert-foreground: #586e75\ntab-background: #eee8d5\ntab-background-selected: #fdf6e3\ntab-border: #93a1a1\ntab-border-selected: #586e75\ntab-divider: #586e75\ntab-foreground: #657b83\ntab-foreground-selected: #586e75\ntable-border: #93a1a1\ntable-footer-background: #eee8d5\ntable-header-background: #eee8d5\ntag-background: #b58900\ntag-foreground: #fdf6e3\ntiddler-background: #fdf6e3\ntiddler-border: #93a1a1\ntiddler-controls-foreground: inherit\ntiddler-controls-foreground-hover: #d33682\ntiddler-controls-foreground-selected: #2aa198\ntiddler-editor-background: #fdf6e3\ntiddler-editor-border: #eee8d5\ntiddler-editor-border-image: #fdf6e3\ntiddler-editor-fields-even: #fdf6e3\ntiddler-editor-fields-odd: #eee8d5\ntiddler-info-background: #eee8d5\ntiddler-info-border: #839496\ntiddler-info-tab-background: #fdf6e3\ntiddler-link-background: #fdf6e3\ntiddler-link-foreground: #2aa198\ntiddler-subtitle-foreground: #657b83\ntiddler-title-foreground: #d33682\ntoolbar-cancel-button: #657b83\ntoolbar-close-button: #657b83\ntoolbar-delete-button: #dc322f\ntoolbar-done-button: #657b83\ntoolbar-edit-button: #657b83\ntoolbar-info-button: #657b83\ntoolbar-new-button: #657b83\ntoolbar-options-button: #657b83\ntoolbar-save-button: inherit\nuntagged-background: #586e75\nvery-muted-foreground: #93a1a1\n"},"$:/palettes/SpartanDay":{"title":"$:/palettes/SpartanDay","tags":"$:/tags/Palette","type":"application/x-tiddler-dictionary","description":"Cold, spartan day colors","name":"Spartan Day","color-scheme":"light","text":"alert-background: <<colour background>>\nalert-border: <<colour very-muted-foreground>>\nalert-highlight: <<colour very-muted-foreground>>\nalert-muted-foreground: <<colour muted-foreground>>\nbackground: #FAFAFA\nblockquote-bar: <<colour page-background>>\nbutton-background: transparent\nbutton-foreground: inherit\nbutton-border: <<colour tag-background>>\ncode-background: #ececec\ncode-border: #ececec\ncode-foreground: \ndirty-indicator: #c80000\ndownload-background: <<colour primary>>\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: #FFFFFF\ndropdown-border: <<colour dropdown-background>>\ndropdown-tab-background-selected: <<colour dropdown-background>>\ndropdown-tab-background: #F5F5F5\ndropzone-background: <<colour tag-background>>\nexternal-link-background-hover: transparent\nexternal-link-background-visited: transparent\nexternal-link-background: transparent\nexternal-link-foreground-hover: \nexternal-link-foreground-visited: \nexternal-link-foreground: \nfootnote-target-background: #ececec\nforeground: rgba(0, 0, 0, 0.87)\nhighlight-background: #ffff00\nhighlight-foreground: #000000\nmessage-background: <<colour background>>\nmessage-border: <<colour very-muted-foreground>>\nmessage-foreground: rgba(0, 0, 0, 0.54)\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: <<colour very-muted-foreground>>\nmodal-footer-background: <<colour background>>\nmodal-footer-border: <<colour very-muted-foreground>>\nmodal-header-border: <<colour very-muted-foreground>>\nmuted-foreground: rgba(0, 0, 0, 0.54)\nnotification-background: <<colour dropdown-background>>\nnotification-border: <<colour dropdown-background>>\npage-background: #f4f4f4\npre-background: #ececec\npre-border: #ececec\nprimary: #3949ab\nselect-tag-background: <<colour background>>\nselect-tag-foreground: <<colour foreground>>\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #aeaeae\nsidebar-controls-foreground: #c6c6c6\nsidebar-foreground-shadow: transparent\nsidebar-foreground: rgba(0, 0, 0, 0.54)\nsidebar-muted-foreground-hover: rgba(0, 0, 0, 0.54)\nsidebar-muted-foreground: rgba(0, 0, 0, 0.38)\nsidebar-tab-background-selected: <<colour page-background>>\nsidebar-tab-background: transparent\nsidebar-tab-border-selected: <<colour table-border>>\nsidebar-tab-border: transparent\nsidebar-tab-divider: <<colour table-border>>\nsidebar-tab-foreground-selected: rgba(0, 0, 0, 0.87)\nsidebar-tab-foreground: rgba(0, 0, 0, 0.54)\nsidebar-tiddler-link-foreground-hover: rgba(0, 0, 0, 0.87)\nsidebar-tiddler-link-foreground: rgba(0, 0, 0, 0.54)\nsite-title-foreground: rgba(0, 0, 0, 0.87)\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: <<colour background>>\ntab-background: transparent\ntab-border-selected: <<colour table-border>>\ntab-border: transparent\ntab-divider: <<colour table-border>>\ntab-foreground-selected: rgba(0, 0, 0, 0.87)\ntab-foreground: rgba(0, 0, 0, 0.54)\ntable-border: #d8d8d8\ntable-footer-background: <<colour tiddler-editor-fields-odd>>\ntable-header-background: <<colour tiddler-editor-fields-even>>\ntag-background: #ec6\ntag-foreground: <<colour button-foreground>>\ntiddler-background: <<colour background>>\ntiddler-border: #f9f9f9\ntiddler-controls-foreground-hover: <<colour sidebar-controls-foreground-hover>>\ntiddler-controls-foreground-selected: <<colour sidebar-controls-foreground-hover>>\ntiddler-controls-foreground: <<colour sidebar-controls-foreground>>\ntiddler-editor-background: transparent\ntiddler-editor-border-image: \ntiddler-editor-border: #e8e7e7\ntiddler-editor-fields-even: rgba(0, 0, 0, 0.1)\ntiddler-editor-fields-odd: rgba(0, 0, 0, 0.04)\ntiddler-info-background: #F5F5F5\ntiddler-info-border: #F5F5F5\ntiddler-info-tab-background: <<colour tiddler-editor-fields-odd>>\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: <<colour muted-foreground>>\ntiddler-title-foreground: #000000\ntoolbar-new-button: \ntoolbar-options-button: \ntoolbar-save-button: \ntoolbar-info-button: \ntoolbar-edit-button: \ntoolbar-close-button: \ntoolbar-delete-button: \ntoolbar-cancel-button: \ntoolbar-done-button: \nuntagged-background: <<colour very-muted-foreground>>\nvery-muted-foreground: rgba(0, 0, 0, 0.12)\n"},"$:/palettes/SpartanNight":{"title":"$:/palettes/SpartanNight","tags":"$:/tags/Palette","type":"application/x-tiddler-dictionary","description":"Dark spartan colors","name":"Spartan Night","color-scheme":"dark","text":"alert-background: <<colour background>>\nalert-border: <<colour very-muted-foreground>>\nalert-highlight: <<colour very-muted-foreground>>\nalert-muted-foreground: <<colour muted-foreground>>\nbackground: #303030\nblockquote-bar: <<colour page-background>>\nbutton-background: transparent\nbutton-foreground: inherit\nbutton-border: <<colour tag-background>>\ncode-background: <<colour pre-background>>\ncode-border: <<colour pre-border>>\ncode-foreground: rgba(255, 255, 255, 0.54)\ndirty-indicator: #c80000\ndownload-background: <<colour primary>>\ndownload-foreground: <<colour foreground>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: #424242\ndropdown-border: <<colour dropdown-background>>\ndropdown-tab-background-selected: <<colour dropdown-background>>\ndropdown-tab-background: #050505\ndropzone-background: <<colour tag-background>>\nexternal-link-background-hover: transparent\nexternal-link-background-visited: transparent\nexternal-link-background: transparent\nexternal-link-foreground-hover: \nexternal-link-foreground-visited: #7c318c\nexternal-link-foreground: #9e3eb3\nfootnote-target-background: #494949\nforeground: rgba(255, 255, 255, 0.7)\nhighlight-background: #ffff78\nhighlight-foreground: #000000\nmessage-background: <<colour background>>\nmessage-border: <<colour very-muted-foreground>>\nmessage-foreground: rgba(255, 255, 255, 0.54)\nmodal-backdrop: <<colour page-background>>\nmodal-background: <<colour background>>\nmodal-border: <<colour very-muted-foreground>>\nmodal-footer-background: <<colour background>>\nmodal-footer-border: <<colour background>>\nmodal-header-border: <<colour very-muted-foreground>>\nmuted-foreground: rgba(255, 255, 255, 0.54)\nnotification-background: <<colour dropdown-background>>\nnotification-border: <<colour dropdown-background>>\npage-background: #212121\npre-background: #2a2a2a\npre-border: transparent\nprimary: #5656f3\nselect-tag-background: <<colour background>>\nselect-tag-foreground: <<colour foreground>>\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #494949\nsidebar-controls-foreground: #5d5d5d\nsidebar-foreground-shadow: transparent\nsidebar-foreground: rgba(255, 255, 255, 0.54)\nsidebar-muted-foreground-hover: rgba(255, 255, 255, 0.54)\nsidebar-muted-foreground: rgba(255, 255, 255, 0.38)\nsidebar-tab-background-selected: <<colour page-background>>\nsidebar-tab-background: transparent\nsidebar-tab-border-selected: <<colour table-border>>\nsidebar-tab-border: transparent\nsidebar-tab-divider: <<colour table-border>>\nsidebar-tab-foreground-selected: rgba(255, 255, 255, 0.87)\nsidebar-tab-foreground: rgba(255, 255, 255, 0.54)\nsidebar-tiddler-link-foreground-hover: rgba(255, 255, 255, 0.7)\nsidebar-tiddler-link-foreground: rgba(255, 255, 255, 0.54)\nsite-title-foreground: rgba(255, 255, 255, 0.7)\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: <<colour background>>\ntab-background: transparent\ntab-border-selected: <<colour table-border>>\ntab-border: transparent\ntab-divider: <<colour table-border>>\ntab-foreground-selected: rgba(255, 255, 255, 0.87)\ntab-foreground: rgba(255, 255, 255, 0.54)\ntable-border: #3a3a3a\ntable-footer-background: <<colour tiddler-editor-fields-odd>>\ntable-header-background: <<colour tiddler-editor-fields-even>>\ntag-background: #ec6\ntag-foreground: <<colour button-foreground>>\ntiddler-background: <<colour background>>\ntiddler-border: rgb(55,55,55)\ntiddler-controls-foreground-hover: <<colour sidebar-controls-foreground-hover>>\ntiddler-controls-foreground-selected: <<colour sidebar-controls-foreground-hover>>\ntiddler-controls-foreground: <<colour sidebar-controls-foreground>>\ntiddler-editor-background: transparent\ntiddler-editor-border-image: \ntiddler-editor-border: rgba(255, 255, 255, 0.08)\ntiddler-editor-fields-even: rgba(255, 255, 255, 0.1)\ntiddler-editor-fields-odd: rgba(255, 255, 255, 0.04)\ntiddler-info-background: #454545\ntiddler-info-border: #454545\ntiddler-info-tab-background: <<colour tiddler-editor-fields-odd>>\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: <<colour muted-foreground>>\ntiddler-title-foreground: #FFFFFF\ntoolbar-new-button: \ntoolbar-options-button: \ntoolbar-save-button: \ntoolbar-info-button: \ntoolbar-edit-button: \ntoolbar-close-button: \ntoolbar-delete-button: \ntoolbar-cancel-button: \ntoolbar-done-button: \nuntagged-background: <<colour very-muted-foreground>>\nvery-muted-foreground: rgba(255, 255, 255, 0.12)\n"},"$:/palettes/Twilight":{"title":"$:/palettes/Twilight","tags":"$:/tags/Palette","author":"Thomas Elmiger","type":"application/x-tiddler-dictionary","name":"Twilight","description":"Delightful, soft darkness.","color-scheme":"dark","text":"alert-background: rgb(255, 255, 102)\nalert-border: rgb(232, 232, 125)\nalert-highlight: rgb(255, 51, 51)\nalert-muted-foreground: rgb(224, 82, 82)\nbackground: rgb(38, 38, 38)\nblockquote-bar: rgba(240, 196, 117, 0.7)\nbutton-background: rgb(63, 63, 63)\nbutton-border: rgb(127, 127, 127)\nbutton-foreground: rgb(179, 179, 179)\ncode-background: rgba(0,0,0,0.03)\ncode-border: rgba(0,0,0,0.08)\ncode-foreground: rgb(255, 94, 94)\ndiff-delete-background: #ffc9c9\ndiff-delete-foreground: <<colour foreground>>\ndiff-equal-background: \ndiff-equal-foreground: <<colour foreground>>\ndiff-insert-background: #aaefad\ndiff-insert-foreground: <<colour foreground>>\ndiff-invisible-background: \ndiff-invisible-foreground: <<colour muted-foreground>>\ndirty-indicator: rgb(255, 94, 94)\ndownload-background: #19a974\ndownload-foreground: rgb(38, 38, 38)\ndragger-background: rgb(179, 179, 179)\ndragger-foreground: rgb(38, 38, 38)\ndropdown-background: rgb(38, 38, 38)\ndropdown-border: rgb(255, 255, 255)\ndropdown-tab-background: rgba(0,0,0,.1)\ndropdown-tab-background-selected: rgba(255,255,255,1)\ndropzone-background: #9eebcf\nexternal-link-background: inherit\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-foreground: rgb(179, 179, 255)\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: rgb(153, 153, 255)\nfootnote-target-background: <<colour tag-foreground>>\nforeground: rgb(179, 179, 179)\nhighlight-background: #ffff78\nhighlight-foreground: #000000\nmessage-background: <<colour tag-foreground>>\nmessage-border: #96ccff\nmessage-foreground: <<colour tag-background>>\nmodal-backdrop: rgb(179, 179, 179)\nmodal-background: rgb(38, 38, 38)\nmodal-border: rgba(0,0,0,.5)\nmodal-footer-background: #f4f4f4\nmodal-footer-border: rgba(0,0,0,.1)\nmodal-header-border: rgba(0,0,0,.2)\nmuted-foreground: rgb(255, 255, 255)\nnotification-background: <<colour tag-foreground>>\nnotification-border: <<colour tag-background>>\npage-background: rgb(26, 26, 26)\npre-background: rgb(25, 25, 25)\npre-border: rgba(0,0,0,.2)\nprimary: rgb(255, 201, 102)\nselect-tag-background: \nselect-tag-foreground: \nsidebar-button-foreground: rgb(179, 179, 179)\nsidebar-controls-foreground: rgb(153, 153, 153)\nsidebar-controls-foreground-hover: <<colour tiddler-controls-foreground-hover>>\nsidebar-foreground: rgb(141, 141, 141)\nsidebar-foreground-shadow: transparent\nsidebar-muted-foreground: rgba(0, 0, 0, 0.5)\nsidebar-muted-foreground-hover: rgb(141, 141, 141)\nsidebar-tab-background: rgba(141, 141, 141, 0.2)\nsidebar-tab-background-selected: rgb(26, 26, 26)\nsidebar-tab-border: rgb(127, 127, 127)\nsidebar-tab-border-selected: rgb(127, 127, 127)\nsidebar-tab-divider: rgb(127, 127, 127)\nsidebar-tab-foreground: rgb(179, 179, 179)\nsidebar-tab-foreground-selected: rgb(179, 179, 179)\nsidebar-tiddler-link-foreground: rgb(179, 179, 179)\nsidebar-tiddler-link-foreground-hover: rgb(115, 115, 115)\nsite-title-foreground: rgb(255, 201, 102)\nstatic-alert-foreground: rgba(0,0,0,.3)\ntab-background: rgba(0,0,0,0.125)\ntab-background-selected: rgb(38, 38, 38)\ntab-border: rgb(255, 201, 102)\ntab-border-selected: rgb(255, 201, 102)\ntab-divider: rgb(255, 201, 102)\ntab-foreground: rgb(179, 179, 179)\ntab-foreground-selected: rgb(179, 179, 179)\ntable-border: rgba(255,255,255,.3)\ntable-footer-background: rgba(0,0,0,.4)\ntable-header-background: rgba(0,0,0,.1)\ntag-background: rgb(255, 201, 102)\ntag-foreground: rgb(25, 25, 25)\ntiddler-background: rgb(38, 38, 38)\ntiddler-border: rgba(240, 196, 117, 0.7)\ntiddler-controls-foreground: rgb(128, 128, 128)\ntiddler-controls-foreground-hover: rgba(255, 255, 255, 0.8)\ntiddler-controls-foreground-selected: rgba(255, 255, 255, 0.9)\ntiddler-editor-background: rgb(33, 33, 33)\ntiddler-editor-border: rgb(63, 63, 63)\ntiddler-editor-border-image: rgb(25, 25, 25)\ntiddler-editor-fields-even: rgb(33, 33, 33)\ntiddler-editor-fields-odd: rgb(28, 28, 28)\ntiddler-info-background: rgb(43, 43, 43)\ntiddler-info-border: rgb(25, 25, 25)\ntiddler-info-tab-background: rgb(43, 43, 43)\ntiddler-link-background: rgb(38, 38, 38)\ntiddler-link-foreground: rgb(204, 204, 255)\ntiddler-subtitle-foreground: rgb(255, 255, 255)\ntiddler-title-foreground: rgb(255, 192, 76)\ntoolbar-cancel-button: \ntoolbar-close-button: \ntoolbar-delete-button: \ntoolbar-done-button: \ntoolbar-edit-button: \ntoolbar-info-button: \ntoolbar-new-button: \ntoolbar-options-button: \ntoolbar-save-button: \nuntagged-background: rgb(255, 255, 255)\nvery-muted-foreground: rgba(240, 196, 117, 0.7)\n"},"$:/palettes/Vanilla":{"title":"$:/palettes/Vanilla","name":"Vanilla","description":"Pale and unobtrusive","tags":"$:/tags/Palette","type":"application/x-tiddler-dictionary","color-scheme":"light","text":"alert-background: #ffe476\nalert-border: #b99e2f\nalert-highlight: #881122\nalert-muted-foreground: #b99e2f\nbackground: #ffffff\nblockquote-bar: <<colour muted-foreground>>\nbutton-background:\nbutton-foreground:\nbutton-border:\ncode-background: #f7f7f9\ncode-border: #e1e1e8\ncode-foreground: #dd1144\ndiff-delete-background: #ffc9c9\ndiff-delete-foreground: <<colour foreground>>\ndiff-equal-background: \ndiff-equal-foreground: <<colour foreground>>\ndiff-insert-background: #aaefad\ndiff-insert-foreground: <<colour foreground>>\ndiff-invisible-background: \ndiff-invisible-foreground: <<colour muted-foreground>>\ndirty-indicator: #ff0000\ndownload-background: #34c734\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: #ffffff\ndropdown-tab-background: #ececec\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #0000aa\nexternal-link-foreground: #0000ee\nfootnote-target-background: #ecf2ff\nforeground: #333333\nhighlight-background: #ffff00\nhighlight-foreground: #000000\nmessage-background: #ecf2ff\nmessage-border: #cfd6e6\nmessage-foreground: #547599\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: #999999\nmodal-footer-background: #f5f5f5\nmodal-footer-border: #dddddd\nmodal-header-border: #eeeeee\nmuted-foreground: #bbbbbb\nnetwork-activity-foreground: #448844\nnotification-background: #ffffdd\nnotification-border: #999999\npage-background: #f4f4f4\npre-background: #f5f5f5\npre-border: #cccccc\nprimary: #5778d8\nselection-background:\nselection-foreground:\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #000000\nsidebar-controls-foreground: #aaaaaa\nsidebar-foreground-shadow: rgba(255,255,255, 0.8)\nsidebar-foreground: #acacac\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: #c0c0c0\nsidebar-tab-background-selected: #f4f4f4\nsidebar-tab-background: #e0e0e0\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: <<colour tab-border>>\nsidebar-tab-divider: #e4e4e4\nsidebar-tab-foreground-selected:\nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: #444444\nsidebar-tiddler-link-foreground: #999999\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstability-stable: #008000\nstability-experimental: #c07c00\nstability-deprecated: #ff0000\nstability-legacy: #0000ff\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: #ffffff\ntab-background: #d8d8d8\ntab-border-selected: #d8d8d8\ntab-border: #cccccc\ntab-divider: #d8d8d8\ntab-foreground-selected: <<colour tab-foreground>>\ntab-foreground: #666666\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #eecc66\ntag-foreground: #ffffff\ntestcase-accent-level-1: #c1eaff\ntestcase-accent-level-2: #E3B740\ntestcase-accent-level-3: #5FD564\ntiddler-background: <<colour background>>\ntiddler-border: <<colour background>>\ntiddler-controls-foreground-hover: #888888\ntiddler-controls-foreground-selected: #444444\ntiddler-controls-foreground: #cccccc\ntiddler-editor-background: #f8f8f8\ntiddler-editor-border-image: #ffffff\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: #e0e8e0\ntiddler-editor-fields-odd: #f0f4f0\ntiddler-info-background: #f8f8f8\ntiddler-info-border: #dddddd\ntiddler-info-tab-background: #f8f8f8\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: #c0c0c0\ntiddler-title-foreground: #182955\ntoolbar-new-button:\ntoolbar-options-button:\ntoolbar-save-button:\ntoolbar-info-button:\ntoolbar-edit-button:\ntoolbar-close-button:\ntoolbar-delete-button:\ntoolbar-cancel-button:\ntoolbar-done-button:\nuntagged-background: #999999\nvery-muted-foreground: #888888\nwikilist-background: #e5e5e5\nwikilist-item: #ffffff\nwikilist-info: #000000\nwikilist-title: #666666\nwikilist-title-svg: <<colour wikilist-title>>\nwikilist-url: #aaaaaa\nwikilist-button-open: #4fb82b\nwikilist-button-open-hover: green\nwikilist-button-reveal: #5778d8\nwikilist-button-reveal-hover: blue\nwikilist-button-remove: #d85778\nwikilist-button-remove-hover: red\nwikilist-toolbar-background: #d3d3d3\nwikilist-toolbar-foreground: #888888\nwikilist-droplink-dragover: rgba(255,192,192,0.5)\nwikilist-button-background: #acacac\nwikilist-button-foreground: #000000\n"},"$:/core/readme":{"title":"$:/core/readme","text":"This plugin contains TiddlyWiki's core components, comprising:\n\n* JavaScript code modules\n* Icons\n* Templates needed to create TiddlyWiki's user interface\n* British English (''en-GB'') translations of the localisable strings used by the core\n"},"$:/library/sjcl.js/license":{"title":"$:/library/sjcl.js/license","type":"text/plain","text":"SJCL is open. You can use, modify and redistribute it under a BSD\nlicense or under the GNU GPL, version 2.0.\n\n---------------------------------------------------------------------\n\nhttp://opensource.org/licenses/BSD-2-Clause\n\nCopyright (c) 2009-2015, Emily Stark, Mike Hamburg and Dan Boneh at\nStanford University. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n1. Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS\nIS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\nTO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\nPARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nHOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\nTO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\nPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n---------------------------------------------------------------------\n\nhttp://opensource.org/licenses/GPL-2.0\n\nThe Stanford Javascript Crypto Library (hosted here on GitHub) is a\nproject by the Stanford Computer Security Lab to build a secure,\npowerful, fast, small, easy-to-use, cross-browser library for\ncryptography in Javascript.\n\nCopyright (c) 2009-2015, Emily Stark, Mike Hamburg and Dan Boneh at\nStanford University.\n\nThis program is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License as published by the\nFree Software Foundation; either version 2 of the License, or (at your\noption) any later version.\n\nThis program is distributed in the hope that it will be useful, but\nWITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General\nPublic License for more details.\n\nYou should have received a copy of the GNU General Public License along\nwith this program; if not, write to the Free Software Foundation, Inc.,\n59 Temple Place, Suite 330, Boston, MA 02111-1307 USA"},"$:/core/templates/MOTW.html":{"title":"$:/core/templates/MOTW.html","text":"\\rules only filteredtranscludeinline transcludeinline entity\n<!-- The following comment is called a MOTW comment and is necessary for the TiddlyIE Internet Explorer extension -->\n<!-- saved from url=(0021)https://tiddlywiki.com -->&#13;&#10;"},"$:/core/templates/alltiddlers.template.html":{"title":"$:/core/templates/alltiddlers.template.html","type":"text/vnd.tiddlywiki-html","text":"<!-- This template is provided for backwards compatibility with older versions of TiddlyWiki -->\n\n<$set name=\"exportFilter\" value=\"[!is[system]sort[title]]\">\n\n{{$:/core/templates/exporters/StaticRiver}}\n\n</$set>\n"},"$:/core/templates/canonical-uri-external-image":{"title":"$:/core/templates/canonical-uri-external-image","text":"<!--\n\nThis template is used to assign the ''_canonical_uri'' field to external images.\n\nChange the `./images/` part to a different base URI. The URI can be relative or absolute.\n\n-->\n./images/<$view field=\"title\" format=\"doubleurlencoded\"/>"},"$:/core/templates/canonical-uri-external-raw":{"title":"$:/core/templates/canonical-uri-external-raw","text":"<!--\n\nThis template is used to assign the ''_canonical_uri'' field to external raw files that are stored in the same directory\n\n-->\n<$view field=\"title\" format=\"doubleurlencoded\"/>"},"$:/core/templates/canonical-uri-external-text":{"title":"$:/core/templates/canonical-uri-external-text","text":"<!--\n\nThis template is used to assign the ''_canonical_uri'' field to external text files.\n\nChange the `./text/` part to a different base URI. The URI can be relative or absolute.\n\n-->\n./text/<$view field=\"title\" format=\"doubleurlencoded\"/>.tid"},"$:/core/templates/css-tiddler":{"title":"$:/core/templates/css-tiddler","text":"<!--\n\nThis template is used for saving CSS tiddlers as a style tag with data attributes representing the tiddler fields.\n\n-->`<style`<$fields template=' data-tiddler-$name$=\"$encoded_value$\"'></$fields>` type=\"text/css\">`<$view field=\"text\" format=\"text\" />`</style>`"},"$:/core/templates/exporters/CsvFile":{"title":"$:/core/templates/exporters/CsvFile","tags":"$:/tags/Exporter","description":"{{$:/language/Exporters/CsvFile}}","extension":".csv","text":"<$macrocall $name=\"csvtiddlers\" filter=<<exportFilter>> format=\"quoted-comma-sep\" $output=\"text/raw\"/>\n"},"$:/core/templates/exporters/JsonFile":{"title":"$:/core/templates/exporters/JsonFile","tags":"$:/tags/Exporter","description":"{{$:/language/Exporters/JsonFile}}","extension":".json","text":"<$macrocall $name=\"jsontiddlers\" filter=<<exportFilter>> $output=\"text/raw\"/>\n"},"$:/core/templates/exporters/StaticRiver":{"title":"$:/core/templates/exporters/StaticRiver","tags":"$:/tags/Exporter","description":"{{$:/language/Exporters/StaticRiver}}","extension":".html","text":"\\define tv-config-static() yes\n\\define tv-wikilink-template() #$uri_encoded$\n\\define tv-config-toolbar-icons() no\n\\define tv-config-toolbar-text() no\n\\define tv-config-toolbar-class() tc-btn-invisible\n\\rules only filteredtranscludeinline transcludeinline\n<!doctype html>\n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n<meta name=\"generator\" content=\"TiddlyWiki\" />\n<meta name=\"tiddlywiki-version\" content=\"{{$:/core/templates/version}}\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n<meta name=\"format-detection\" content=\"telephone=no\">\n<link id=\"faviconLink\" rel=\"shortcut icon\" href=\"favicon.ico\">\n<title>{{$:/core/wiki/title}}</title>\n<div id=\"styleArea\">\n{{$:/boot/boot.css||$:/core/templates/css-tiddler}}\n</div>\n<style type=\"text/css\">\n{{$:/core/ui/PageStylesheet||$:/core/templates/wikified-tiddler}}\n</style>\n</head>\n<body class=\"tc-body\">\n{{$:/StaticBanner||$:/core/templates/html-tiddler}}\n<section class=\"tc-story-river tc-static-story-river\">\n{{$:/core/templates/exporters/StaticRiver/Content||$:/core/templates/html-tiddler}}\n</section>\n</body>\n</html>\n"},"$:/core/templates/exporters/StaticRiver/Content":{"title":"$:/core/templates/exporters/StaticRiver/Content","text":"\\define renderContent()\n{{{ $(exportFilter)$ ||$:/core/templates/static-tiddler}}}\n\\end\n\\import [subfilter{$:/core/config/GlobalImportFilter}]\n<<renderContent>>\n"},"$:/core/templates/exporters/TidFile":{"title":"$:/core/templates/exporters/TidFile","tags":"$:/tags/Exporter","description":"{{$:/language/Exporters/TidFile}}","extension":".tid","condition":"[<count>compare:lte[1]]","text":"\\define renderContent()\n{{{ $(exportFilter)$ +[limit[1]] ||$:/core/templates/tid-tiddler}}}\n\\end\n\\import [subfilter{$:/core/config/GlobalImportFilter}]\n<<renderContent>>"},"$:/core/save/all-external-js":{"title":"$:/core/save/all-external-js","text":"\\whitespace trim\n\\import [subfilter{$:/core/config/GlobalImportFilter}]\n\\define saveTiddlerFilter()\n[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/core]] -[[$:/boot/boot.css]] -[is[system]type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$\n\\end\n\n<!-- Important: core library is provided by serving URI encoded $:/core/templates/tiddlywiki5.js -->\n\\define defaultCoreURL() %24%3A%2Fcore%2Ftemplates%2Ftiddlywiki5.js\n\n<$let coreURL={{{ [[coreURL]is[variable]then<coreURL>else<defaultCoreURL>] }}}>\n\t{{$:/core/templates/tiddlywiki5-external-js.html}}\n</$let>\n"},"$:/core/save/offline-external-js":{"title":"$:/core/save/offline-external-js","text":"\\whitespace trim\n\\import [subfilter{$:/core/config/GlobalImportFilter}]\n\\define saveTiddlerFilter()\n[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/core]] -[[$:/plugins/tiddlywiki/filesystem]] -[[$:/plugins/tiddlywiki/tiddlyweb]] -[[$:/boot/boot.css]] -[is[system]type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$\n\\end\n\\define defaultCoreURL() tiddlywikicore-$(version)$.js\n<$let coreURL={{{ [[coreURL]is[variable]then<coreURL>else<defaultCoreURL>] }}}>\n\t{{$:/core/templates/tiddlywiki5-external-js.html}}\n</$let>\n"},"$:/core/templates/tiddlywiki.js/load-tiddler":{"title":"$:/core/templates/tiddlywiki.js/load-tiddler","text":"_load(window,<$macrocall $name=\"jsontiddler\" $output=\"text/raw\"/>);"},"$:/core/templates/tiddlywiki5.js":{"title":"$:/core/templates/tiddlywiki5.js","text":"\\rules only filteredtranscludeinline transcludeinline codeinline\n\n`/*\n`{{ $:/core/copyright.txt ||$:/core/templates/plain-text-tiddler}}`\n*/\n\n$tw = (typeof $tw === 'undefined') ? Object.create(null) : $tw;\n\n$tw.preloadTiddlers = $tw.preloadTiddlers || [];\n\n_load = function(window,tiddler) {\n\t\"use strict\";\n\tvar f;\n\t$tw.preloadTiddlers.push(tiddler);\n\tif(tiddler.library === \"yes\") {\n\t\tvar module = { exports:{} };\n\t\tvar moduleName = function moduleName(path) {\n\t\t\tvar word = path.split(\"/\").pop();\n\t\t\tword = word.substring(0,word.indexOf(\".\")) || word;\n\t\t\treturn word;\n\t\t}\n\t\tf = new Function(\"module\",tiddler.text);\n\t\tf(module);\n\t\twindow[moduleName(tiddler.title)] = module.exports;\n\t} else {\n\t\tf = new Function(\"window\",tiddler.text);\n\t\tf(window);\n\t}\n}\n\n/* ~~ Library modules ~~ */\n\n`{{{ [is[system]type[application/javascript]library[yes]] ||$:/core/templates/tiddlywiki.js/load-tiddler}}}`\n\n/* ~~ Boot kernel prologue ~~ */\n\n`{{ $:/boot/bootprefix.js ||$:/core/templates/tiddlywiki.js/load-tiddler}}`\n\n/* ~~ Core tiddlers ~~ */\n\n`{{$:/core/templates/tiddlywiki5.js/tiddlers}}`\n\n/* ~~ Boot kernel ~~ */\n\n`{{ $:/boot/boot.js ||$:/core/templates/tiddlywiki.js/load-tiddler}}`\n"},"$:/core/templates/tiddlywiki5.js/tiddlers":{"title":"$:/core/templates/tiddlywiki5.js/tiddlers","text":"`\n$tw.preloadTiddlerArray(`<$text text=<<jsontiddlers \"[[$:/core]]\">>/>`);\n$tw.preloadTiddlerArray([{\n\ttitle: \"$:/config/SaveWikiButton/Template\",\n\ttext: \"$:/core/save/offline-external-js\"\n}]);\n`\n"},"$:/core/templates/tiddlywiki5-external-js.html":{"title":"$:/core/templates/tiddlywiki5-external-js.html","text":"<$set name=\"saveTiddlerAndShadowsFilter\" filter=\"[subfilter<saveTiddlerFilter>] [subfilter<saveTiddlerFilter>plugintiddlers[]]\">\n`<!doctype html>\n`{{$:/core/templates/MOTW.html}}`<html lang=\"`<$text text={{{ [{$:/language}get[name]] }}}/>`\">\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n<!--~~ Raw markup for the top of the head section ~~-->\n`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified/TopHead]] ||$:/core/templates/raw-static-tiddler}}}`\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=Edge\"/>\n<meta name=\"application-name\" content=\"TiddlyWiki\" />\n<meta name=\"generator\" content=\"TiddlyWiki\" />\n<meta name=\"tiddlywiki-version\" content=\"`{{$:/core/templates/version}}`\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\" />\n<meta name=\"mobile-web-app-capable\" content=\"yes\"/>\n<meta name=\"format-detection\" content=\"telephone=no\" />\n<meta name=\"copyright\" content=\"`{{$:/core/copyright.txt}}`\" />\n<link id=\"faviconLink\" rel=\"shortcut icon\" href=\"favicon.ico\">\n<title>`{{$:/core/wiki/title}}`</title>\n<!--~~ This is a Tiddlywiki file. The points of interest in the file are marked with this pattern ~~-->\n\n<!--~~ Raw markup ~~-->\n`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/core/wiki/rawmarkup]] ||$:/core/templates/plain-text-tiddler}}}`\n`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkup]] ||$:/core/templates/plain-text-tiddler}}}`\n`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified]] ||$:/core/templates/raw-static-tiddler}}}`\n</head>\n<body class=\"tc-body\">\n<!--~~ Raw markup for the top of the body section ~~-->\n`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified/TopBody]] ||$:/core/templates/raw-static-tiddler}}}`\n<!--~~ Static styles ~~-->\n<div id=\"styleArea\">\n`{{$:/boot/boot.css||$:/core/templates/css-tiddler}}`\n</div>\n<!--~~ Static content for Google and browsers without JavaScript ~~-->\n<noscript>\n<div id=\"splashArea\">\n`{{$:/core/templates/static.area}}`\n</div>\n</noscript>\n<!--~~ Ordinary tiddlers ~~-->\n`{{$:/core/templates/store.area.template.html}}`\n<!--~~ Raw markup for the bottom of the body section ~~-->\n`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified/BottomBody]] ||$:/core/templates/raw-static-tiddler}}}`\n<!--~~ Load external JavaScripts ~~-->\n<script src=\"`{{{ [<coreURL>] }}}`\" onerror=\"alert('Error: Cannot load `{{{ [<coreURL>] }}}`');\"></script>\n</body>\n</html>`\n</$set>"},"$:/core/templates/html-div-skinny-tiddler":{"title":"$:/core/templates/html-div-skinny-tiddler","text":"<!--\n\nThis template is a variant of $:/core/templates/html-div-tiddler used for saving skinny tiddlers (with no text field)\n\n-->`<div`<$fields template=' $name$=\"$encoded_value$\"'></$fields>`>\n<pre></pre>\n</div>`\n"},"$:/core/templates/html-div-tiddler":{"title":"$:/core/templates/html-div-tiddler","text":"<!--\n\nThis template is used for saving tiddlers as an HTML DIV tag with attributes representing the tiddler fields.\n\n-->`<div`<$fields template=' $name$=\"$encoded_value$\"'></$fields>`>\n<pre>`<$view field=\"text\" format=\"htmltextencoded\" />`</pre>\n</div>`\n"},"$:/core/templates/html-json-skinny-tiddler":{"title":"$:/core/templates/html-json-skinny-tiddler","text":"<$text text=<<join>>/><$jsontiddler tiddler=<<currentTiddler>> exclude=\"text\" escapeUnsafeScriptChars=\"yes\"/>\n"},"$:/core/templates/html-json-tiddler":{"title":"$:/core/templates/html-json-tiddler","text":"<$jsontiddler tiddler=<<currentTiddler>> escapeUnsafeScriptChars=\"yes\"/>"},"$:/core/templates/html-tiddler":{"title":"$:/core/templates/html-tiddler","text":"<!--\n\nThis template is used for saving tiddlers as raw HTML\n\n--><$view field=\"text\" format=\"htmlwikified\" />"},"$:/core/templates/javascript-tiddler":{"title":"$:/core/templates/javascript-tiddler","text":"<!--\n\nThis template is used for saving JavaScript tiddlers as a script tag with data attributes representing the tiddler fields.\n\n-->`<script`<$fields template=' data-tiddler-$name$=\"$encoded_value$\"'></$fields>` type=\"text/javascript\">`<$view field=\"text\" format=\"text\" />`</script>`"},"$:/core/templates/json-tiddler":{"title":"$:/core/templates/json-tiddler","text":"<!--\n\nThis template is used for saving tiddlers as raw JSON\n\n--><$text text=<<jsontiddler>>/>"},"$:/core/templates/module-tiddler":{"title":"$:/core/templates/module-tiddler","text":"<!--\n\nThis template is used for saving JavaScript tiddlers as a script tag with data attributes representing the tiddler fields. The body of the tiddler is wrapped in a call to the `$tw.modules.define` function in order to define the body of the tiddler as a module\n\n-->`<script`<$fields template=' data-tiddler-$name$=\"$encoded_value$\"'></$fields>` type=\"text/javascript\" data-module=\"yes\">$tw.modules.define(\"`<$view field=\"title\" format=\"jsencoded\" />`\",\"`<$view field=\"module-type\" format=\"jsencoded\" />`\",function(module,exports,require) {`<$view field=\"text\" format=\"text\" />`});\n</script>`"},"$:/core/templates/plain-text-tiddler":{"title":"$:/core/templates/plain-text-tiddler","text":"<$view field=\"text\" format=\"text\" />"},"$:/core/templates/raw-static-tiddler":{"title":"$:/core/templates/raw-static-tiddler","text":"<!--\n\nThis template is used for saving tiddlers as static HTML\n\n--><$view field=\"text\" format=\"plainwikified\" />"},"$:/core/save/all":{"title":"$:/core/save/all","text":"\\import [subfilter{$:/core/config/GlobalImportFilter}]\n\\define saveTiddlerFilter()\n[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/boot/boot.css]] -[is[system]type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$\n\\end\n{{$:/core/templates/tiddlywiki5.html}}\n"},"$:/core/save/empty":{"title":"$:/core/save/empty","text":"\\define saveTiddlerFilter()\n[is[system]] -[prefix[$:/state/popup/]] -[[$:/boot/boot.css]] -[is[system]type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]]\n\\end\n{{$:/core/templates/tiddlywiki5.html}}\n"},"$:/core/save/lazy-all":{"title":"$:/core/save/lazy-all","text":"\\define saveTiddlerFilter()\n[is[system]] -[prefix[$:/state/popup/]] -[[$:/HistoryList]] -[[$:/boot/boot.css]] -[is[system]type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] [is[tiddler]type[application/javascript]] +[sort[title]]\n\\end\n\\define skinnySaveTiddlerFilter()\n[!is[system]] -[type[application/javascript]]\n\\end\n{{$:/core/templates/tiddlywiki5.html}}\n"},"$:/core/save/lazy-images":{"title":"$:/core/save/lazy-images","text":"\\define saveTiddlerFilter()\n[is[tiddler]] -[prefix[$:/state/popup/]] -[[$:/HistoryList]] -[[$:/boot/boot.css]] -[is[system]type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] -[!is[system]is[image]] +[sort[title]] \n\\end\n\\define skinnySaveTiddlerFilter()\n[!is[system]is[image]]\n\\end\n{{$:/core/templates/tiddlywiki5.html}}\n"},"$:/core/templates/server/static.sidebar.wikitext":{"title":"$:/core/templates/server/static.sidebar.wikitext","text":"\\whitespace trim\n<div class=\"tc-sidebar-scrollable\" style=\"overflow: auto;\" role=\"region\" aria-label={{$:/language/SideBar/Caption}}>\n<div class=\"tc-sidebar-header\">\n<h1 class=\"tc-site-title\">\n<$transclude tiddler=\"$:/SiteTitle\"/>\n</h1>\n<div class=\"tc-site-subtitle\">\n<$transclude tiddler=\"$:/SiteSubtitle\"/>\n</div>\n<h2>\n</h2>\n<div class=\"tc-sidebar-lists\">\n<$list filter={{$:/DefaultTiddlers}}>\n<div class=\"tc-menu-list-subitem\">\n<$link><$text text=<<currentTiddler>>/></$link>\n</div>\n</$list>\n</div>\n<!-- Currently disabled the recent list as it is unweildy when the responsive narrow view kicks in\n<h2>\n{{$:/language/SideBar/Recent/Caption}}\n</h2>\n<div class=\"tc-sidebar-lists\">\n<$macrocall $name=\"timeline\" format={{$:/language/RecentChanges/DateFormat}}/>\n</div>\n</div>\n</div>\n-->\n"},"$:/core/templates/server/static.tiddler.html":{"title":"$:/core/templates/server/static.tiddler.html","text":"\\whitespace trim\n\\define tv-config-static() yes\n\\define tv-wikilink-template() $uri_encoded$\n\\import [subfilter{$:/core/config/GlobalImportFilter}]\n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n<meta name=\"generator\" content=\"TiddlyWiki\" />\n<meta name=\"tiddlywiki-version\" content={{$:/core/templates/version}} />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\" />\n<meta name=\"mobile-web-app-capable\" content=\"yes\"/>\n<meta name=\"format-detection\" content=\"telephone=no\">\n<link id=\"faviconLink\" rel=\"shortcut icon\" href=\"favicon.ico\">\n<link rel=\"stylesheet\" href=\"%24%3A%2Fcore%2Ftemplates%2Fstatic.template.css\">\n<title><$view field=\"caption\" format=\"plainwikified\"><$view field=\"title\"/></$view>: <$view tiddler=\"$:/core/wiki/title\" format=\"plainwikified\"/></title>\n</head>\n<body class=\"tc-body\">\n<$transclude tiddler=\"$:/core/templates/server/static.sidebar.wikitext\" mode=\"inline\"/>\n<section class=\"tc-story-river\" role=\"main\">\n<div class=\"tc-tiddler-frame\" role=\"article\">\n<$transclude tiddler=\"$:/core/templates/server/static.tiddler.wikitext\" mode=\"inline\"/>\n</div>\n</section>\n</body>\n</html>"},"$:/core/templates/server/static.tiddler.wikitext":{"title":"$:/core/templates/server/static.tiddler.wikitext","text":"\\whitespace trim\n<div class=\"tc-tiddler-title tc-clearfix\">\n<div class=\"tc-titlebar\">\n<h2><$text text=<<currentTiddler>>/></h2>\n</div>\n</div>\n<div class=\"tc-subtitle tc-clearfix\">\n<$link to={{!!modifier}}>\n<$view field=\"modifier\"/>\n</$link> <$view field=\"modified\" format=\"date\" template={{$:/language/Tiddler/DateFormat}}/>\n</div>\n<div class=\"tc-tags-wrapper\" tc-clearfix>\n<$list filter=\"[all[current]tags[]sort[title]]\">\n<a href={{{ [<currentTiddler>encodeuricomponent[]] }}}>\n<$macrocall $name=\"tag-pill\" tag=<<currentTiddler>>/>\n</a>\n</$list>\n</div>\n<div class=\"tc-tiddler-body tc-clearfix\">\n<$transclude mode=\"block\"/>\n</div>\n"},"$:/core/templates/single.tiddler.window":{"title":"$:/core/templates/single.tiddler.window","text":"\\whitespace trim\n\\define containerClasses()\ntc-page-container tc-page-view-$(storyviewTitle)$ tc-language-$(languageTitle)$\n\\end\n\\import [subfilter{$:/core/config/GlobalImportFilter}]\n\n<$vars\n\ttv-config-toolbar-icons={{$:/config/Toolbar/Icons}}\n\ttv-config-toolbar-text={{$:/config/Toolbar/Text}}\n\ttv-config-toolbar-class={{$:/config/Toolbar/ButtonClass}}\n\ttv-show-missing-links={{$:/config/MissingLinks}}\n\tstoryviewTitle={{$:/view}}\n\tlanguageTitle={{{ [{$:/language}get[name]] }}}>\n\n<div class=<<containerClasses>>>\n\n<$navigator story=\"$:/StoryList\" history=\"$:/HistoryList\">\n\n<$transclude tiddler=\"$:/core/ui/ViewTemplate/body\" mode=\"block\"/>\n\n</$navigator>\n\n</div>\n\n</$vars>\n"},"$:/core/templates/social-metadata":{"title":"$:/core/templates/social-metadata","tags":"$:/tags/RawMarkupWikified","text":"\\procedure meta-plain(name,source,name-attribute:\"name\")\n\\whitespace trim\n<%if [<source>has[text]] %>\n\t&lt;meta&#32;<$text text=<<name-attribute>>/>=\"<$text text=<<name>>/>\" content=\"<$text text={{{ [<source>get[text]encodehtml[]] }}}/>\"&gt;\n\t<$text text={{{ [charcode[10]] }}}/>\n<%endif%>\n\\end meta-plain\n\n\\procedure meta-wikified(name,source,name-attribute:\"name\")\n\\whitespace trim\n<%if [<source>has[text]] %>\n\t<$wikify name=\"html\" text={{{ [<source>get[text]] }}} output=\"text\">\n\t\t&lt;meta&#32;<$text text=<<name-attribute>>/>=\"<$text text=<<name>>/>\" content=\"<$text text={{{ [<html>encodehtml[]] }}}/>\"&gt;\n\t\t<$text text={{{ [charcode[10]] }}}/>\n\t</$wikify>\n<%endif%>\n\\end meta-wikified\n\n\\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline macrocallblock conditional commentinline commentblock\n<<meta-wikified \"description\" \"$:/SiteSubtitle\">>\n\n<!-- Facebook Meta Tags -->\n<<meta-plain \"og:url\" \"$:/SiteUrl\" \"property\">>\n<<meta-plain \"og:type\" \"website\" \"property\">>\n<<meta-wikified \"og:title\" \"$:/SiteTitle\" \"property\">>\n<<meta-wikified \"og:description\" \"$:/SiteSubtitle\" \"property\">>\n<<meta-plain \"og:image\" \"$:/SitePreviewUrl\" \"property\">>\n\n<!-- Twitter Meta Tags -->\n<<meta-plain \"twitter:card\" \"summary_large_image\">>\n<<meta-plain \"twitter:domain\" \"$:/SiteDomain\" \"property\">>\n<<meta-plain \"twitter:url\" \"$:/SiteUrl\" \"property\">>\n<<meta-wikified \"twitter:title\" \"$:/SiteTitle\">>\n<<meta-wikified \"twitter:description\" \"$:/SiteSubtitle\">>\n<<meta-plain \"twitter:image\" \"$:/SitePreviewUrl\">>\n"},"$:/core/templates/split-recipe":{"title":"$:/core/templates/split-recipe","text":"<$list filter=\"[!is[system]]\">\ntiddler: <$view field=\"title\" format=\"urlencoded\"/>.tid\n</$list>\n"},"$:/core/templates/static-tiddler":{"title":"$:/core/templates/static-tiddler","text":"<a name=<<currentTiddler>>>\n<$transclude tiddler=\"$:/core/ui/ViewTemplate\"/>\n</a>"},"$:/core/templates/static.area":{"title":"$:/core/templates/static.area","text":"<$reveal type=\"nomatch\" state=\"$:/isEncrypted\" text=\"yes\">\n{{{ [all[shadows+tiddlers]tag[$:/tags/RawStaticContent]!has[draft.of]] ||$:/core/templates/raw-static-tiddler}}}\n{{$:/core/templates/static.content||$:/core/templates/html-tiddler}}\n</$reveal>\n<$reveal type=\"match\" state=\"$:/isEncrypted\" text=\"yes\">\nThis file contains an encrypted ~TiddlyWiki. Enable ~JavaScript and enter the decryption password when prompted.\n</$reveal>\n<!-- ensure splash screen isn't shown when JS is disabled -->\n`<style>\n.tc-remove-when-wiki-loaded {display: none;}\n</style>`\n"},"$:/core/templates/static.content":{"title":"$:/core/templates/static.content","text":"<!-- For Google, and people without JavaScript-->\nThis [[TiddlyWiki|https://tiddlywiki.com]] contains the following tiddlers:\n\n<ul>\n<$list filter=<<saveTiddlerFilter>>>\n<li><$view field=\"title\" format=\"text\"></$view></li>\n</$list>\n</ul>\n"},"$:/core/templates/static.template.css":{"title":"$:/core/templates/static.template.css","text":"{{$:/boot/boot.css||$:/core/templates/plain-text-tiddler}}\n\n{{$:/core/ui/PageStylesheet||$:/core/templates/wikified-tiddler}}\n"},"$:/core/templates/static.template.html":{"title":"$:/core/templates/static.template.html","type":"text/vnd.tiddlywiki-html","text":"\\define tv-config-static() yes\n\\define tv-wikilink-template() static/$uri_doubleencoded$.html\n\\define tv-config-toolbar-icons() no\n\\define tv-config-toolbar-text() no\n\\define tv-config-toolbar-class() tc-btn-invisible\n\\rules only filteredtranscludeinline transcludeinline\n<!doctype html>\n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n<meta name=\"generator\" content=\"TiddlyWiki\" />\n<meta name=\"tiddlywiki-version\" content=\"{{$:/core/templates/version}}\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\" />\n<meta name=\"mobile-web-app-capable\" content=\"yes\"/>\n<meta name=\"format-detection\" content=\"telephone=no\">\n<link id=\"faviconLink\" rel=\"shortcut icon\" href=\"favicon.ico\">\n<title>{{$:/core/wiki/title}}</title>\n<div id=\"styleArea\">\n{{$:/boot/boot.css||$:/core/templates/css-tiddler}}\n</div>\n<style type=\"text/css\">\n{{$:/core/ui/PageStylesheet||$:/core/templates/wikified-tiddler}}\n</style>\n</head>\n<body class=\"tc-body\">\n{{$:/StaticBanner||$:/core/templates/html-tiddler}}\n{{$:/core/ui/PageTemplate||$:/core/templates/html-tiddler}}\n</body>\n</html>\n"},"$:/core/templates/static.tiddler.html":{"title":"$:/core/templates/static.tiddler.html","text":"\\define tv-wikilink-template() $uri_doubleencoded$.html\n\\define tv-config-static() yes\n\\define tv-config-toolbar-icons() no\n\\define tv-config-toolbar-text() no\n\\define tv-config-toolbar-class() tc-btn-invisible\n\\import [subfilter{$:/core/config/GlobalImportFilter}]\n`<!doctype html>\n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n<meta name=\"generator\" content=\"TiddlyWiki\" />\n<meta name=\"tiddlywiki-version\" content=\"`{{$:/core/templates/version}}`\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\" />\n<meta name=\"mobile-web-app-capable\" content=\"yes\"/>\n<meta name=\"format-detection\" content=\"telephone=no\">\n<link id=\"faviconLink\" rel=\"shortcut icon\" href=\"favicon.ico\">\n<link rel=\"stylesheet\" href=\"static.css\">\n<title>`<$view field=\"caption\"><$view field=\"title\"/></$view>: {{$:/core/wiki/title}}`</title>\n</head>\n<body class=\"tc-body\">\n`{{$:/StaticBanner||$:/core/templates/html-tiddler}}`\n<section class=\"tc-story-river tc-static-story-river\">\n`<$view tiddler=\"$:/core/ui/ViewTemplate\" format=\"htmlwikified\"/>`\n</section>\n</body>\n</html>\n`\n"},"$:/core/templates/store.area.template.html":{"title":"$:/core/templates/store.area.template.html","text":"\\whitespace trim\n<!-- Unencrypted -->\n<$list filter=\"[[$:/isEncrypted]get[text]else[no]match[no]]\">\n    <$list filter=\"[[storeAreaFormat]is[variable]getvariable[]else[json]match[json]]\">\n        <!-- New-style JSON store area, with an old-style store area for compatibility with v5.1.x tooling -->\n        `<script class=\"tiddlywiki-tiddler-store\" type=\"application/json\">[`\n            <$let newline={{{ [charcode[10]] }}} join=`,$(newline)$`>\n                <$text text=<<newline>>/>\n                <$list filter=<<saveTiddlerFilter>> join=<<join>> template=\"$:/core/templates/html-json-tiddler\"/>\n                <$list filter=\"[subfilter<skinnySaveTiddlerFilter>]\"  template=\"$:/core/templates/html-json-skinny-tiddler\"/>\n                <$text text=<<newline>>/>\n            </$let>\n        `]</script>`\n        `<div id=\"storeArea\" style=\"display:none;\">`\n        `</div>`\n    </$list>\n    <$list filter=\"[[storeAreaFormat]is[variable]getvariable[]else[json]match[div]]\">\n        <!-- Old-style DIV/PRE-based store area -->\n        <$reveal type=\"nomatch\" state=\"$:/isEncrypted\" text=\"yes\">\n            `<div id=\"storeArea\" style=\"display:none;\">`\n                <$list filter={{{ [<saveTiddlerFilter>] }}} template=\"$:/core/templates/html-div-tiddler\"/>\n                <$list filter=\"[subfilter<skinnySaveTiddlerFilter>]\" template=\"$:/core/templates/html-div-skinny-tiddler\"/>\n            `</div>`\n        </$reveal>\n    </$list>\n</$list>\n<!-- Encrypted -->\n<$list filter=\"[[$:/isEncrypted]get[text]else[no]match[yes]]\">\n    `<!--~~ Encrypted tiddlers ~~-->`\n    `<pre id=\"encryptedStoreArea\" type=\"text/plain\" style=\"display:none;\">`\n        <$encrypt filter=<<saveTiddlerFilter>>/>\n    `</pre>`\n</$list>"},"$:/core/templates/tid-tiddler":{"title":"$:/core/templates/tid-tiddler","text":"<!--\n\nThis template is used for saving tiddlers in TiddlyWeb *.tid format\n\n--><$fields exclude='text bag' template='$name$: $value$\n'></$fields>`\n`<$view field=\"text\" format=\"text\" />"},"$:/core/templates/tiddler-metadata":{"title":"$:/core/templates/tiddler-metadata","text":"<!--\n\nThis template is used for saving tiddler metadata *.meta files\n\n--><$fields exclude='text bag' template='$name$: $value$\n'></$fields>"},"$:/core/templates/tiddlywiki5.html":{"title":"$:/core/templates/tiddlywiki5.html","text":"<$set name=\"saveTiddlerAndShadowsFilter\" filter=\"[subfilter<saveTiddlerFilter>] [subfilter<saveTiddlerFilter>plugintiddlers[]]\">\n`<!doctype html>\n`{{$:/core/templates/MOTW.html}}`<html lang=\"`<$text text={{{ [{$:/language}get[name]] }}}/>`\">\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n<!--~~ Raw markup for the top of the head section ~~-->\n`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified/TopHead]] ||$:/core/templates/raw-static-tiddler}}}`\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=Edge\"/>\n<meta name=\"application-name\" content=\"TiddlyWiki\" />\n<meta name=\"generator\" content=\"TiddlyWiki\" />\n<meta name=\"tiddlywiki-version\" content=\"`{{$:/core/templates/version}}`\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\" />\n<meta name=\"mobile-web-app-capable\" content=\"yes\"/>\n<meta name=\"format-detection\" content=\"telephone=no\" />\n<meta name=\"copyright\" content=\"`{{$:/core/copyright.txt}}`\" />\n<link id=\"faviconLink\" rel=\"shortcut icon\" href=\"favicon.ico\">\n<title>`{{$:/core/wiki/title}}`</title>\n<!--~~ This is a Tiddlywiki file. The points of interest in the file are marked with this pattern ~~-->\n\n<!--~~ Raw markup ~~-->\n`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/core/wiki/rawmarkup]] ||$:/core/templates/plain-text-tiddler}}}\n{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkup]] ||$:/core/templates/plain-text-tiddler}}}\n{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified]] ||$:/core/templates/raw-static-tiddler}}}`\n</head>\n<body class=\"tc-body\">\n<!--~~ Raw markup for the top of the body section ~~-->\n`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified/TopBody]] ||$:/core/templates/raw-static-tiddler}}}`\n<!--~~ Static styles ~~-->\n<div id=\"styleArea\">\n`{{$:/boot/boot.css||$:/core/templates/css-tiddler}}`\n</div>\n<!--~~ Static content for Google and browsers without JavaScript ~~-->\n<noscript>\n<div id=\"splashArea\">\n`{{$:/core/templates/static.area}}`\n</div>\n</noscript>\n<!--~~ Ordinary tiddlers ~~-->\n`{{$:/core/templates/store.area.template.html}}`\n<!--~~ Library modules ~~-->\n<div id=\"libraryModules\" style=\"display:none;\">\n`{{{ [is[system]type[application/javascript]library[yes]] ||$:/core/templates/javascript-tiddler}}}`\n</div>\n<!--~~ Boot kernel prologue ~~-->\n<div id=\"bootKernelPrefix\" style=\"display:none;\">\n`{{ $:/boot/bootprefix.js ||$:/core/templates/javascript-tiddler}}`\n</div>\n<!--~~ Boot kernel ~~-->\n<div id=\"bootKernel\" style=\"display:none;\">\n`{{ $:/boot/boot.js ||$:/core/templates/javascript-tiddler}}`\n</div>\n<!--~~ Raw markup for the bottom of the body section ~~-->\n`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified/BottomBody]] ||$:/core/templates/raw-static-tiddler}}}`\n</body>\n</html>`\n</$set>\n"},"$:/core/templates/version":{"title":"$:/core/templates/version","text":"<<version>>"},"$:/core/templates/wikified-tiddler":{"title":"$:/core/templates/wikified-tiddler","text":"<$transclude />"},"$:/core/ui/AboveStory/tw2-plugin-check":{"title":"$:/core/ui/AboveStory/tw2-plugin-check","tags":"$:/tags/AboveStory","text":"\\define lingo-base() $:/language/AboveStory/ClassicPlugin/\n<$list filter=\"[all[system+tiddlers]tag[systemConfig]limit[1]]\">\n\n<div class=\"tc-message-box\">\n\n<<lingo Warning>>\n\n<ul>\n\n<$list filter=\"[all[system+tiddlers]tag[systemConfig]]\">\n\n<li>\n\n<$link><$view field=\"title\"/></$link>\n\n</li>\n\n</$list>\n\n</ul>\n\n</div>\n\n</$list>\n"},"$:/core/ui/Actions/new-image":{"title":"$:/core/ui/Actions/new-image","tags":"$:/tags/Actions","description":"create a new image tiddler","text":"\\whitespace trim\n<$action-sendmessage $message=\"tm-new-tiddler\" type={{{ [{$:/config/NewImageType}addprefix[image/]] }}}/>\n"},"$:/core/ui/Actions/new-journal":{"title":"$:/core/ui/Actions/new-journal","tags":"$:/tags/Actions","description":"create a new journal tiddler","text":"\\whitespace trim\n\\function get-tags() [<textFieldTags>] [<tagsFieldTags>] +[join[ ]]\n<$let journalTitleTemplate={{$:/config/NewJournal/Title}} textFieldTags={{$:/config/NewJournal/Tags}} tagsFieldTags={{$:/config/NewJournal/Tags!!tags}} journalText={{$:/config/NewJournal/Text}}>\n<$wikify name=\"journalTitle\" text=\"<$transclude $variable='now' format=<<journalTitleTemplate>>/>\">\n<$reveal type=\"nomatch\" state=<<journalTitle>> text=\"\">\n<$action-sendmessage $message=\"tm-new-tiddler\" title=<<journalTitle>> tags=<<get-tags>> text={{{ [<journalTitle>get[]] }}}/>\n</$reveal>\n<$reveal type=\"match\" state=<<journalTitle>> text=\"\">\n<$action-sendmessage $message=\"tm-new-tiddler\" title=<<journalTitle>> tags=<<get-tags>> text=<<journalText>>/>\n</$reveal>\n</$wikify>\n</$let>\n"},"$:/core/ui/Actions/new-tiddler":{"title":"$:/core/ui/Actions/new-tiddler","tags":"$:/tags/Actions","description":"create a new empty tiddler","text":"\\whitespace trim\n\\function get-tags() [<textFieldTags>] [<tagsFieldTags>] +[join[ ]]\n<$let textFieldTags={{$:/config/NewTiddler/Tags}} tagsFieldTags={{$:/config/NewTiddler/Tags!!tags}}>\n<$action-sendmessage $message=\"tm-new-tiddler\" tags=<<get-tags>>/>\n</$let>\n"},"$:/core/ui/AdvancedSearch/Filter":{"title":"$:/core/ui/AdvancedSearch/Filter","tags":"$:/tags/AdvancedSearch","caption":"{{$:/language/Search/Filter/Caption}}","text":"\\procedure lingo-base() $:/language/Search/\n\\procedure set-next-input-tab()\n<$transclude $variable=\"change-input-tab\"\n\tstateTitle=\"$:/state/tab--1498284803\"\n\ttag=\"$:/tags/AdvancedSearch\"\n\tbeforeafter=\"after\"\n\tdefaultState=\"$:/core/ui/AdvancedSearch/System\"\n\tactions=\"<$action-setfield $tiddler='$:/state/advancedsearch/currentTab' text=<<nextTab>>/>\"\n/>\n\\end\n\n\\procedure set-previous-input-tab()\n<$transclude $variable=\"change-input-tab\"\n\tstateTitle=\"$:/state/tab--1498284803\"\n\ttag=\"$:/tags/AdvancedSearch\"\n\tbeforeafter=\"before\"\n\tdefaultState=\"$:/core/ui/AdvancedSearch/System\"\n\tactions=\"<$action-setfield $tiddler='$:/state/advancedsearch/currentTab' text=<<nextTab>>/>\"\n/>\n\\end\n\n\\procedure cancel-search-actions()\n\\whitespace trim\n<$list filter=\"[{$:/temp/advancedsearch/input}!match{$:/temp/advancedsearch}]\">\n\t<$list-empty>\n\t\t<$action-deletetiddler $filter=\"[[$:/temp/advancedsearch]] [[$:/temp/advancedsearch/input]] [[$:/temp/advancedsearch/selected-item]]\"/>\n\t</$list-empty>\n\t<$action-setfield $tiddler=\"$:/temp/advancedsearch/input\" text={{$:/temp/advancedsearch}}/>\n\t<$action-setfield $tiddler=\"$:/temp/advancedsearch/refresh\" text=\"yes\"/>\n</$list>\n\\end\n\n\\procedure input-accept-actions()\n\\whitespace trim\n<$list filter=\"[{$:/config/Search/NavigateOnEnter/enable}match[yes]]\">\n\t<$list-empty>\n\t\t<$list filter=\"[<tiddler>get[text]!is[missing]] :else[<tiddler>get[text]is[shadow]]\">\n\t\t\t<$action-navigate $to={{{ [<tiddler>get[text]] }}}/>\n\t\t</$list>\n\t<$/list-empty>\n\t<$action-navigate $to={{{ [<tiddler>get[text]] }}}/>\n</$list>\n\\end\n\n\\procedure input-accept-variant-actions()\n\\whitespace trim\n<$list filter=\"[{$:/config/Search/NavigateOnEnter/enable}match[yes]]\">\n\t<$list-empty>\n\t\t<$list filter=\"[<tiddler>get[text]!is[missing]] :else[<tiddler>get[text]is[shadow]]\">\n\t\t\t<$list filter=\"[<__tiddler__>get[text]minlength[1]]\">\n\t\t\t\t<$action-sendmessage $message=\"tm-edit-tiddler\" $param={{{  [<tiddler>get[text]] }}}/>\n\t\t\t</$list>\n\t\t</$list>\n\t</$list-empty>\n\t<$list filter=\"[<tiddler>get[text]minlength[1]]\">\n\t\t<$action-sendmessage $message=\"tm-edit-tiddler\" $param={{{  [<tiddler>get[text]] }}}/>\n\t</$list>\n</$list>\n\\end\n\n\\whitespace trim\n\n<<lingo Filter/Hint>>\n\n<div class=\"tc-search tc-advanced-search\">\n\t<$keyboard key=\"((input-tab-right))\" actions=<<set-next-input-tab>> class=\"tc-small-gap-right\">\n\t\t<$keyboard key=\"((input-tab-left))\" actions=<<set-previous-input-tab>>>\n\t\t\t<$transclude $variable=\"keyboard-driven-input\"\n\t\t\t\ttiddler=\"$:/temp/advancedsearch/input\"\n\t\t\t\tstoreTitle=\"$:/temp/advancedsearch\"\n\t\t\t\trefreshTitle=\"$:/temp/advancedsearch/refresh\"\n\t\t\t\tselectionStateTitle=\"$:/temp/advancedsearch/selected-item\"\n\t\t\t\ttype=\"search\"\n\t\t\t\ttag=\"input\"\n\t\t\t\tfocus={{$:/config/Search/AutoFocus}}\n\t\t\t\tconfigTiddlerFilter=\"[[$:/temp/advancedsearch]]\"\n\t\t\t\tfirstSearchFilterField=\"text\"\n\t\t\t\tinputAcceptActions=<<input-accept-actions>>\n\t\t\t\tinputAcceptVariantActions=<<input-accept-variant-actions>>\n\t\t\t\tinputCancelActions=<<cancel-search-actions>>\n\t\t\t/>\n\t\t</$keyboard>\n\t</$keyboard>\n\t<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/AdvancedSearch/FilterButton]!has[draft.of]]\">\n\t\t<$transclude/>\n\t</$list>\n</div>\n\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\" tag=\"div\" class=\"tc-search-results\">\n\t<$set name=\"resultCount\" value=\"<$count filter={{$:/temp/advancedsearch}}/>\">\n\t\t<p><<lingo Filter/Matches>></p>\n\t\t<$list filter={{$:/temp/advancedsearch}}>\n\t\t\t<span class={{{[<currentTiddler>addsuffix[-primaryList]] -[[$:/temp/advancedsearch/selected-item]get[text]] :and[then[]else[tc-list-item-selected]] }}}>\n\t\t\t\t<$transclude tiddler=\"$:/core/ui/ListItemTemplate\"/>\n\t\t\t</span>\n\t\t</$list>\n\t</$set>\n</$reveal>\n"},"$:/core/ui/AdvancedSearch/Filter/FilterButtons/clear":{"title":"$:/core/ui/AdvancedSearch/Filter/FilterButtons/clear","tags":"$:/tags/AdvancedSearch/FilterButton","text":"\\whitespace trim\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<$button class=\"tc-btn-invisible\">\n<<cancel-search-actions>>\n<$action-sendmessage $message=\"tm-focus-selector\" $param=\"\"\".tc-advanced-search input\"\"\" />\n{{$:/core/images/close-button}}\n</$button>\n</$reveal>\n"},"$:/core/ui/AdvancedSearch/Filter/FilterButtons/delete":{"title":"$:/core/ui/AdvancedSearch/Filter/FilterButtons/delete","tags":"$:/tags/AdvancedSearch/FilterButton","text":"\\whitespace trim\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<$button tooltip={{$:/language/Buttons/DeleteTiddlers/Hint}} popup=<<qualify \"$:/state/filterDeleteDropdown\">> class=\"tc-btn-invisible\">\n{{$:/core/images/delete-button}}\n</$button>\n</$reveal>\n\n<$reveal state=<<qualify \"$:/state/filterDeleteDropdown\">> type=\"popup\" position=\"belowleft\" animate=\"yes\">\n<div class=\"tc-block-dropdown-wrapper\">\n<div class=\"tc-block-dropdown tc-edit-type-dropdown\">\n<div class=\"tc-dropdown-item-plain\">\n<$set name=\"resultCount\" value=\"\"\"<$count filter={{$:/temp/advancedsearch}}/>\"\"\">\n{{$:/language/ConfirmDeleteTiddlers}}\n</$set>\n</div>\n<div class=\"tc-dropdown-item-plain\">\n<$button class=\"tc-btn\">\n<$action-deletetiddler $filter={{$:/temp/advancedsearch}}/>\n{{$:/language/Buttons/DeleteTiddlers/Hint}}\n</$button>\n</div>\n</div>\n</div>\n</$reveal>\n"},"$:/core/ui/AdvancedSearch/Filter/FilterButtons/dropdown":{"title":"$:/core/ui/AdvancedSearch/Filter/FilterButtons/dropdown","tags":"$:/tags/AdvancedSearch/FilterButton","text":"\\whitespace trim\n\n<span class=\"tc-popup-keep\">\n<$button popup=<<qualify \"$:/state/filterDropdown\">> class=\"tc-btn-invisible\">\n{{$:/core/images/down-arrow}}\n</$button>\n</span>\n\n<$reveal state=<<qualify \"$:/state/filterDropdown\">> type=\"popup\" position=\"belowleft\" animate=\"yes\">\n<$set name=\"tv-show-missing-links\" value=\"yes\">\n<$linkcatcher actions=\"<$action-setfield $tiddler='$:/temp/advancedsearch' text=<<navigateTo>>/><$action-setfield $tiddler='$:/temp/advancedsearch/input' text=<<navigateTo>>/><$action-setfield $tiddler='$:/temp/advancedsearch/refresh' text='yes'/><$action-sendmessage $message='tm-focus-selector' $param='.tc-advanced-search input' />\">\n<div class=\"tc-block-dropdown-wrapper\">\n<div class=\"tc-block-dropdown tc-edit-type-dropdown\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Filter]!is[draft]]\">\n<$link to={{!!filter}}><$let tv-wikilinks=\"no\"><$transclude field=\"description\"/></$let></$link>\n</$list>\n</div>\n</div>\n</$linkcatcher>\n</$set>\n</$reveal>\n"},"$:/core/ui/AdvancedSearch/Filter/FilterButtons/export":{"title":"$:/core/ui/AdvancedSearch/Filter/FilterButtons/export","tags":"$:/tags/AdvancedSearch/FilterButton","text":"\\whitespace trim\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<$macrocall $name=\"exportButton\" exportFilter={{$:/temp/advancedsearch}} lingoBase=\"$:/language/Buttons/ExportTiddlers/\"/>\n</$reveal>\n"},"$:/core/ui/AdvancedSearch/Shadows":{"title":"$:/core/ui/AdvancedSearch/Shadows","tags":"$:/tags/AdvancedSearch","caption":"{{$:/language/Search/Shadows/Caption}}","first-search-filter":"[all[shadows]search<userInput>sort[title]limit[250]] -[[$:/temp/advancedsearch]] -[[$:/temp/advancedsearch/input]]","text":"\\procedure lingo-base() $:/language/Search/\n\n\\procedure set-next-input-tab()\n<$transclude $variable=\"change-input-tab\"\n\tstateTitle=\"$:/state/tab--1498284803\"\n\ttag=\"$:/tags/AdvancedSearch\"\n\tbeforeafter=\"after\"\n\tdefaultState=\"$:/core/ui/AdvancedSearch/System\"\n\tactions=\"<$action-setfield $tiddler='$:/state/advancedsearch/currentTab' text=<<nextTab>>/>\"/>\n\\end\n\n\\procedure set-previous-input-tab()\n<$transclude $variable=\"change-input-tab\"\n\tstateTitle=\"$:/state/tab--1498284803\"\n\ttag=\"$:/tags/AdvancedSearch\"\n\tbeforeafter=\"before\"\n\tdefaultState=\"$:/core/ui/AdvancedSearch/System\"\n\tactions=\"<$action-setfield $tiddler='$:/state/advancedsearch/currentTab' text=<<nextTab>>/>\"/>\n\\end\n\n\\procedure cancel-search-actions()\n\\whitespace trim\n<$list\n\tfilter=\"[{$:/temp/advancedsearch}!match{$:/temp/advancedsearch/input}]\"\n\temptyMessage=\"<$action-deletetiddler $filter='[[$:/temp/advancedsearch]] [[$:/temp/advancedsearch/input]] [[$:/temp/advancedsearch/selected-item]]' />\">\n\t<$action-setfield $tiddler=\"$:/temp/advancedsearch/input\" text={{$:/temp/advancedsearch}}/>\n\t<$action-setfield $tiddler=\"$:/temp/advancedsearch/refresh\" text=\"yes\"/>\n</$list>\n<$action-sendmessage $message=\"tm-focus-selector\" $param=\".tc-advanced-search input\"/>\n\\end\n\n\\procedure input-accept-actions()\n\\whitespace trim\n<$list\n\tfilter=\"[{$:/config/Search/NavigateOnEnter/enable}match[yes]]\"\n\temptyMessage=\"<$list filter='[<tiddler>get[text]!is[missing]] :else[<tiddler>get[text]is[shadow]]'><$action-navigate $to={{{ [<tiddler>get[text]] }}}/></$list>\">\n\t<$action-navigate $to={{{ [<tiddler>get[text]] }}}/>\n</$list>\n\\end\n\n\\procedure input-accept-variant-actions()\n\\whitespace trim\n<$list\n\tfilter=\"[{$:/config/Search/NavigateOnEnter/enable}match[yes]]\"\n\temptyMessage=\"<$list filter='[<tiddler>get[text]!is[missing]] :else[<tiddler>get[text]is[shadow]]'><$list filter='[<tiddler>get[text]minlength[1]]'><$action-sendmessage $message='tm-edit-tiddler' $param={{{  [<tiddler>get[text]] }}}/></$list></$list>\">\n\t<$list filter=\"[<tiddler>get[text]minlength[1]]\">\n\t\t<$action-sendmessage $message=\"tm-edit-tiddler\" $param={{{  [<tiddler>get[text]] }}}/>\n</$list></$list>\n\\end\n\n\\whitespace trim\n\n<<lingo Shadows/Hint>>\n\n<div class=\"tc-search\">\n<$keyboard key=\"((input-tab-right))\" actions=<<set-next-input-tab>>>\n<$keyboard key=\"((input-tab-left))\" actions=<<set-previous-input-tab>>>\n<$transclude $variable=\"keyboard-driven-input\"\n\ttiddler=\"$:/temp/advancedsearch/input\"\n\tstoreTitle=\"$:/temp/advancedsearch\"\n\trefreshTitle=\"$:/temp/advancedsearch/refresh\"\n\tselectionStateTitle=\"$:/temp/advancedsearch/selected-item\"\n\ttype=\"search\"\n\ttag=\"input\"\n\tfocus={{$:/config/Search/AutoFocus}}\n\tconfigTiddlerFilter=\"[[$:/core/ui/AdvancedSearch/Shadows]]\"\n\tinputCancelActions=<<cancel-search-actions>>\n\tinputAcceptActions=<<input-accept-actions>>\n\tinputAcceptVariantActions=<<input-accept-variant-actions>>\n\tfilterMinLength={{$:/config/Search/MinLength}}/>\n</$keyboard>\n</$keyboard>\n&#32;\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<$button class=\"tc-btn-invisible\">\n<<cancel-search-actions>>\n{{$:/core/images/close-button}}\n</$button>\n</$reveal>\n</div>\n\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n\n<$list filter=\"[{$:/temp/advancedsearch}minlength{$:/config/Search/MinLength}limit[1]]\" emptyMessage=\"<div class='tc-search-results'>{{$:/language/Search/Search/TooShort}}</div>\" variable=\"listItem\">\n\n<$set name=\"resultCount\" value={{{ [all[shadows]search{$:/temp/advancedsearch}] :except[[$:/temp/advancedsearch]] :except[[$:/temp/advancedsearch/input]] :and[count[]]}}}>\n\n<div class=\"tc-search-results\">\n\n<%if [<resultCount>match[0]] %>\n\t{{$:/language/Search/Matches/NoMatch}}\n<%else%>\n\t<<lingo Shadows/Matches>>\n<%endif%>\n\n<$list filter=\"[all[shadows]search{$:/temp/advancedsearch}sort[title]limit[250]] :else[[$:/temp/advancedsearch]] :else[[$:/temp/advancedsearch/input]]\">\n<span class={{{[<currentTiddler>addsuffix[-primaryList]] :else[[$:/temp/advancedsearch/selected-item]get[text]] :and[then[]else[tc-list-item-selected]] }}}>\n<$transclude tiddler=\"$:/core/ui/ListItemTemplate\"/>\n</span>\n</$list>\n\n</div>\n\n</$set>\n\n</$list>\n\n</$reveal>\n\n<$reveal state=\"$:/temp/advancedsearch\" type=\"match\" text=\"\">\n\n</$reveal>\n"},"$:/core/ui/AdvancedSearch/Standard":{"title":"$:/core/ui/AdvancedSearch/Standard","tags":"$:/tags/AdvancedSearch","caption":"{{$:/language/Search/Standard/Caption}}","text":"\\procedure lingo-base() $:/language/Search/\n\\procedure set-next-input-tab() <$transclude $variable=\"change-input-tab\" stateTitle=\"$:/state/tab--1498284803\" tag=\"$:/tags/AdvancedSearch\" beforeafter=\"after\" defaultState=\"$:/core/ui/AdvancedSearch/System\" actions=\"<$action-setfield $tiddler='$:/state/advancedsearch/currentTab' text=<<nextTab>>/>\"/>\n\n\\procedure set-previous-input-tab() <$transclude $variable=\"change-input-tab\" stateTitle=\"$:/state/tab--1498284803\" tag=\"$:/tags/AdvancedSearch\" beforeafter=\"before\" defaultState=\"$:/core/ui/AdvancedSearch/System\" actions=\"<$action-setfield $tiddler='$:/state/advancedsearch/currentTab' text=<<nextTab>>/>\"/>\n\n\\procedure next-search-tab() <$transclude $variable=\"change-input-tab\" stateTitle=\"$:/state/tab/search-results/advancedsearch\" tag=\"$:/tags/SearchResults\" beforeafter=\"after\" defaultState={{$:/config/SearchResults/Default}} actions=\"<$action-setfield $tiddler='$:/state/advancedsearch/standard/currentTab' text=<<nextTab>>/>\"/>\n\n\\procedure previous-search-tab() <$transclude $variable=\"change-input-tab\" stateTitle=\"$:/state/tab/search-results/advancedsearch\" tag=\"$:/tags/SearchResults\" beforeafter=\"before\" defaultState={{$:/config/SearchResults/Default}} actions=\"<$action-setfield $tiddler='$:/state/advancedsearch/standard/currentTab' text=<<nextTab>>/>\"/>\n\n\\procedure cancel-search-actions() <$list filter=\"[{$:/temp/advancedsearch}!match{$:/temp/advancedsearch/input}]\" emptyMessage=\"<$action-deletetiddler $filter='[[$:/temp/advancedsearch]] [[$:/temp/advancedsearch/input]] [[$:/temp/advancedsearch/selected-item]]' />\"><$action-setfield $tiddler=\"$:/temp/advancedsearch/input\" text={{$:/temp/advancedsearch}}/><$action-setfield $tiddler=\"$:/temp/advancedsearch/refresh\" text=\"yes\"/></$list><$action-sendmessage $message=\"tm-focus-selector\" $param=\".tc-advanced-search input\"/>\n\n\\procedure input-accept-actions() <$list filter=\"[{$:/config/Search/NavigateOnEnter/enable}match[yes]]\" emptyMessage=\"<$list filter='[<tiddler>get[text]!is[missing]] :else[<tiddler>get[text]is[shadow]]'><$action-navigate $to={{{ [<tiddler>get[text]] }}}/></$list>\"><$action-navigate $to={{{ [<tiddler>get[text]] }}}/></$list>\n\n\\procedure input-accept-variant-actions() <$list filter=\"[{$:/config/Search/NavigateOnEnter/enable}match[yes]]\" emptyMessage=\"<$list filter='[<tiddler>get[text]!is[missing]] :else[<tiddler>get[text]is[shadow]]'><$list filter='[<tiddler>get[text]minlength[1]]'><$action-sendmessage $message='tm-edit-tiddler' $param={{{  [<tiddler>get[text]] }}}/></$list></$list>\"><$list filter=\"[<tiddler>get[text]minlength[1]]\"><$action-sendmessage $message=\"tm-edit-tiddler\" $param={{{  [<tiddler>get[text]] }}}/></$list></$list>\n\n\\whitespace trim\n\n<<lingo Standard/Hint>>\n\n<div class=\"tc-search\">\n<$keyboard key=\"((input-tab-right))\" actions=<<set-next-input-tab>>>\n<$keyboard key=\"((input-tab-left))\" actions=<<set-previous-input-tab>>>\n<$keyboard key=\"shift-alt-Right\" actions=<<next-search-tab>>>\n<$keyboard key=\"shift-alt-Left\" actions=<<previous-search-tab>>>\n<$transclude $variable=\"keyboard-driven-input\"\n\ttiddler=\"$:/temp/advancedsearch/input\"\n\tstoreTitle=\"$:/temp/advancedsearch\"\n\trefreshTitle=\"$:/temp/advancedsearch/refresh\"\n\tselectionStateTitle=\"$:/temp/advancedsearch/selected-item\"\n\ttype=\"search\"\n\ttag=\"input\"\n\tfocus={{$:/config/Search/AutoFocus}}\n\tinputCancelActions=<<cancel-search-actions>>\n\tinputAcceptActions=<<input-accept-actions>>\n\tinputAcceptVariantActions=<<input-accept-variant-actions>>\n\tconfigTiddlerFilter=\"[[$:/state/search/currentTab]!is[missing]get[text]] :else[{$:/config/SearchResults/Default}]\"\n\tfilterMinLength={{$:/config/Search/MinLength}}/>\n</$keyboard>\n</$keyboard>\n</$keyboard>\n</$keyboard>\n&#32;\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<$button class=\"tc-btn-invisible\">\n<<cancel-search-actions>>\n{{$:/core/images/close-button}}\n</$button>\n</$reveal>\n</div>\n\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<$list\n\tfilter=\"[{$:/temp/advancedsearch}minlength{$:/config/Search/MinLength}limit[1]]\"\n\temptyMessage=\"<div class='tc-search-results'>{{$:/language/Search/Search/TooShort}}</div>\"\n\tvariable=\"listItem\">\n<$vars\n\tuserInput={{{ [[$:/temp/advancedsearch]get[text]] }}}\n\tconfigTiddler={{{ [[$:/state/advancedsearch/standard/currentTab]!is[missing]get[text]] :else[{$:/config/SearchResults/Default}] }}}\n\tsearchListState=\"$:/temp/advancedsearch/selected-item\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/SearchResults]!has[draft.of]butfirst[]limit[1]]\">\n<$list-empty>\n<$list filter='[all[shadows+tiddlers]tag[$:/tags/SearchResults]!has[draft.of]]'><$transclude mode=\"block\"/></$list>\n</$list-empty>\n<$transclude $variable=\"tabs\"\n\ttabsList=\"[all[shadows+tiddlers]tag[$:/tags/SearchResults]!has[draft.of]]\"\n\tdefault={{$:/config/SearchResults/Default}}\n\tactions=\"<$action-setfield $tiddler='$:/state/advancedsearch/standard/currentTab' text=<<currentTab>>/>\"\n\texplicitState=\"$:/state/tab/search-results/advancedsearch\" />\n</$list>\n</$vars>\n</$list>\n</$reveal>\n"},"$:/core/ui/AdvancedSearch/System":{"title":"$:/core/ui/AdvancedSearch/System","tags":"$:/tags/AdvancedSearch","caption":"{{$:/language/Search/System/Caption}}","first-search-filter":"[is[system]search<userInput>sort[title]limit[250]] :except[[$:/temp/advancedsearch]] :except[[$:/temp/advancedsearch/input]] :except[[$:/temp/advancedsearch/selected-item]]","text":"\\procedure lingo-base() $:/language/Search/\n\\procedure set-next-input-tab()\n<$transclude $variable=\"change-input-tab\"\n\tstateTitle=\"$:/state/tab--1498284803\"\n\ttag=\"$:/tags/AdvancedSearch\"\n\tbeforeafter=\"after\"\n\tdefaultState=\"$:/core/ui/AdvancedSearch/System\"\n\tactions=\"<$action-setfield $tiddler='$:/state/advancedsearch/currentTab' text=<<nextTab>>/>\"/>\n\\end\n\n\\procedure set-previous-input-tab()\n<$transclude $variable=\"change-input-tab\"\n\tstateTitle=\"$:/state/tab--1498284803\"\n\ttag=\"$:/tags/AdvancedSearch\"\n\tbeforeafter=\"before\"\n\tdefaultState=\"$:/core/ui/AdvancedSearch/System\"\n\tactions=\"<$action-setfield $tiddler='$:/state/advancedsearch/currentTab' text=<<nextTab>>/>\"/>\n\\end\n\n\\procedure cancel-search-actions()\n\\whitespace trim\n<$list\n\tfilter=\"[{$:/temp/advancedsearch}!match{$:/temp/advancedsearch/input}]\"\n\temptyMessage=\"<$action-deletetiddler $filter='[[$:/temp/advancedsearch]] [[$:/temp/advancedsearch/input]] [[$:/temp/advancedsearch/selected-item]]' />\">\n\t<$action-setfield $tiddler=\"$:/temp/advancedsearch/input\" text={{$:/temp/advancedsearch}}/>\n\t<$action-setfield $tiddler=\"$:/temp/advancedsearch/refresh\" text=\"yes\"/>\n</$list>\n<$action-sendmessage $message=\"tm-focus-selector\" $param=\".tc-advanced-search input\"/>\n\\end\n\n\\procedure input-accept-actions()\n\\whitespace trim\n<$list\n\tfilter=\"[{$:/config/Search/NavigateOnEnter/enable}match[yes]]\"\n\temptyMessage=\"<$list filter='[<tiddler>get[text]!is[missing]] :else[<tiddler>get[text]is[shadow]]'><$action-navigate $to={{{ [<tiddler>get[text]] }}}/></$list>\">\n\t<$action-navigate $to={{{ [<tiddler>get[text]] }}}/>\n</$list>\n\\end\n\n\\procedure input-accept-variant-actions()\n\\whitespace trim\n<$list\n\tfilter=\"[{$:/config/Search/NavigateOnEnter/enable}match[yes]]\"\n\temptyMessage=\"<$list filter='[<tiddler>get[text]!is[missing]] :else[<tiddler>get[text]is[shadow]]'><$list filter='[<tiddler>get[text]minlength[1]]'><$action-sendmessage $message='tm-edit-tiddler' $param={{{  [<tiddler>get[text]] }}}/></$list></$list>\">\n\t<$list filter=\"[<tiddler>get[text]minlength[1]]\">\n\t\t<$action-sendmessage $message=\"tm-edit-tiddler\" $param={{{  [<tiddler>get[text]] }}}/>\n</$list></$list>\n\\end\n\n\\whitespace trim\n\n<<lingo System/Hint>>\n\n<div class=\"tc-search\">\n<$keyboard key=\"((input-tab-right))\" actions=<<set-next-input-tab>>>\n<$keyboard key=\"((input-tab-left))\" actions=<<set-previous-input-tab>>>\n<$transclude $variable=\"keyboard-driven-input\"\n\ttiddler=\"$:/temp/advancedsearch/input\"\n\tstoreTitle=\"$:/temp/advancedsearch\"\n\trefreshTitle=\"$:/temp/advancedsearch/refresh\"\n\tselectionStateTitle=\"$:/temp/advancedsearch/selected-item\"\n\ttype=\"search\"\n\ttag=\"input\"\n\tfocus={{$:/config/Search/AutoFocus}}\n\tconfigTiddlerFilter=\"[[$:/core/ui/AdvancedSearch/System]]\"\n\tinputCancelActions=<<cancel-search-actions>>\n\tinputAcceptActions=<<input-accept-actions>>\n\tinputAcceptVariantActions=<<input-accept-variant-actions>>\n\tfilterMinLength={{$:/config/Search/MinLength}}/>\n</$keyboard>\n</$keyboard>\n&#32;\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<$button class=\"tc-btn-invisible\">\n<<cancel-search-actions>>\n{{$:/core/images/close-button}}\n</$button>\n</$reveal>\n</div>\n\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n\n<$list filter=\"[{$:/temp/advancedsearch}minlength{$:/config/Search/MinLength}limit[1]]\" emptyMessage=\"<div class='tc-search-results'>{{$:/language/Search/Search/TooShort}}</div>\" variable=\"listItem\">\n\n<$set name=\"resultCount\" value={{{ [is[system]search{$:/temp/advancedsearch}] :except[[$:/temp/advancedsearch]] :except[[$:/temp/advancedsearch/input]] :except[[$:/temp/advancedsearch/selected-item]] +[count[]] }}}>\n\n<div class=\"tc-search-results\">\n\n<%if [<resultCount>match[0]] %>\n\t{{$:/language/Search/Matches/NoMatch}}\n<%else%>\n\t<<lingo System/Matches>>\n<%endif%>\n\n<$list filter=\"[is[system]search{$:/temp/advancedsearch}sort[title]limit[250]] :except[[$:/temp/advancedsearch]] :except[[$:/temp/advancedsearch/input]] :except[[$:/temp/advancedsearch/selected-item]]\">\n<span class={{{[<currentTiddler>addsuffix[-primaryList]] :except[[$:/temp/advancedsearch/selected-item]get[text]] :and[then[]else[tc-list-item-selected]] }}}>\n<$transclude tiddler=\"$:/core/ui/ListItemTemplate\"/>\n</span>\n</$list>\n\n</div>\n\n</$set>\n\n</$list>\n\n</$reveal>\n\n<$reveal state=\"$:/temp/advancedsearch\" type=\"match\" text=\"\">\n\n</$reveal>\n"},"$:/AdvancedSearch":{"title":"$:/AdvancedSearch","icon":"$:/core/images/advanced-search-button","color":"#bbb","text":"\\whitespace trim\n<div class=\"tc-advanced-search\">\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/AdvancedSearch]!has[draft.of]]\" default=\"$:/core/ui/AdvancedSearch/System\" actions=\"\"\"<$action-setfield $tiddler=\"$:/state/advancedsearch/currentTab\" text=<<currentTab>>/>\"\"\" explicitState=\"$:/state/tab--1498284803\"/>\n</div>\n"},"$:/core/ui/AlertTemplate":{"title":"$:/core/ui/AlertTemplate","code-body":"yes","text":"\\whitespace trim\n<div class=\"tc-alert\">\n<div class=\"tc-alert-toolbar\">\n<$button class=\"tc-btn-invisible\"><$action-deletetiddler $tiddler=<<currentTiddler>>/>{{$:/core/images/cancel-button}}</$button>\n</div>\n<div class=\"tc-alert-subtitle\">\n<$wikify name=\"format\" text=<<lingo Tiddler/DateFormat>>>\n<$view field=\"component\"/>\n&#32;-&#32;\n<$view field=\"modified\" format=\"date\" template=<<format>>/>\n&#32;\n<$reveal type=\"nomatch\" state=\"!!count\" text=\"\">\n<span class=\"tc-alert-highlight\">\n({{$:/language/Count}}:&#32;<$view field=\"count\"/>)\n</span>\n</$reveal>\n</$wikify>\n</div>\n<div class=\"tc-alert-body\">\n\n<$transclude/>\n\n</div>\n</div>\n"},"$:/core/ui/BinaryWarning":{"title":"$:/core/ui/BinaryWarning","text":"\\define lingo-base() $:/language/BinaryWarning/\n<<lingo Prompt>>\n"},"$:/core/ui/VisibleTransclude":{"title":"$:/core/ui/VisibleTransclude","text":"<!--\nImport this component to make all the child transclusions visible.\n\nBlock transclusions are shown in red, and inline transclusions are shown in green.\n-->\n\\widget $transclude()\n<!-- Use a parameters widget so that we can access the `$params` data -->\n<$parameters tiddler=\"\" $$tiddler=\"\" mode=\"\" $$mode=\"\" $parseMode=\"@parseMode\" $params=\"@params\">\n\t<!-- Replicate the logic of the transclude widget to determine the output mode, and hence the tag and colour to use for output -->\n\t<$let\n\t\tmode={{{ [[$mode]is[variable]then<$mode>!is[blank]] :else[[mode]is[variable]then<mode>!is[blank]] :else[<@parseMode>] }}}\n\t\toutputTag={{{ [<mode>match[inline]then[span]else[div]] }}}\n\t\toutputColour={{{ [<mode>match[inline]then[green]else[red]] }}}\n\t>\n\t\t<!-- Use divs or spans according to the mode -->\n\t\t<$genesis $type=<<outputTag>> style=\"color:white;padding:4px;\" style.background=<<outputColour>>>\n\t\t\t<$genesis $type=<<outputTag>> style=\"display: inline-block;\">\n\t\t\t\t<div style=\"background:white;color:black;font-size: 12px;line-height:1.2;text-align:left;font-weight:normal;padding:4px;margin:4px;\">\n\t\t\t\t\t<!-- Render the parameters to the transclusion -->\n\t\t\t\t\t<$list filter=\"[<@params>jsonindexes[]]\" emptyMessage=\"(none)\">\n\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t<$text text=<<currentTiddler>>/><$text text=\": \"/><$text text={{{ [<@params>jsonget<currentTiddler>] }}}/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</$list>\n\t\t\t\t</div>\n\t\t\t</$genesis>\n\t\t\t<$genesis $type=<<outputTag>> style=\"background:white;color:black;padding:4px;\">\n\t\t\t\t<!-- Look for a parameter starting with $ to determine if we are in legacy mode -->\n\t\t\t\t<$list filter=\"[<@params>jsonindexes[]] :filter[<currentTiddler>prefix[$]] +[limit[1]]\" variable=\"ignore\" emptyMessage=\"\"\"\n\t\t\t\t\t<!-- Legacy mode: we render the transclusion without a dollar sign for recursionMarker and mode -->\n\t\t\t\t\t<$genesis $type=\"$transclude\" $remappable=\"no\" $names=\"[<@params>jsonindexes[]]\" $values=\"[<@params>jsonindexes[]] :map[<@params>jsonget<currentTiddler>]\" recursionMarker=\"no\" mode=<<mode>> $$fillignore=\"yes\">\n\t\t\t\t\t\t<!-- Reach back up to the grandparent transclusion to get the correct slot value -->\n\t\t\t\t\t\t<$slot $name=\"ts-raw\"/>\n\t\t\t\t\t</$genesis>\n\t\t\t\t\"\"\">\n\t\t\t\t\t<!-- Non-legacy mode: we use dollar signs for the recursionMarker and mode -->\n\t\t\t\t\t<$genesis $type=\"$transclude\" $remappable=\"no\" $names=\"[<@params>jsonindexes[]]\" $values=\"[<@params>jsonindexes[]] :map[<@params>jsonget<currentTiddler>]\" $$recursionMarker=\"no\" $$mode=<<mode>> $$fillignore=\"yes\">\n\t\t\t\t\t\t<!-- Reach back up to the grandparent transclusion to get the correct slot fill value -->\n\t\t\t\t\t\t<$slot $name=\"ts-raw\"/>\n\t\t\t\t\t</$genesis>\n\t\t\t\t</$list>\n\t\t\t</$genesis>\n\t\t</$genesis>\n\t</$let>\n</$parameters>\n\\end\n"},"$:/core/ui/Components/plugin-info":{"title":"$:/core/ui/Components/plugin-info","text":"\\define lingo-base() $:/language/ControlPanel/Plugins/\n\n\\define popup-state-macro()\n$(qualified-state)$-$(currentTiddler)$\n\\end\n\n\\define tabs-state-macro()\n$(popup-state)$-$(pluginInfoType)$\n\\end\n\n\\define plugin-icon-title()\n$(currentTiddler)$/icon\n\\end\n\n\\define plugin-disable-title()\n$:/config/Plugins/Disabled/$(currentTiddler)$\n\\end\n\n\\define plugin-table-body(type,disabledMessage,default-popup-state)\n\\whitespace trim\n<div class=\"tc-plugin-info-chunk tc-plugin-info-toggle\">\n\t<$reveal type=\"nomatch\" state=<<popup-state>> text=\"yes\" default=\"\"\"$default-popup-state$\"\"\">\n\t\t<$button class=\"tc-btn-invisible tc-btn-dropdown\" set=<<popup-state>> setTo=\"yes\">\n\t\t\t{{$:/core/images/chevron-right}}\n\t\t</$button>\n\t</$reveal>\n\t<$reveal type=\"match\" state=<<popup-state>> text=\"yes\" default=\"\"\"$default-popup-state$\"\"\">\n\t\t<$button class=\"tc-btn-invisible tc-btn-dropdown\" set=<<popup-state>> setTo=\"no\">\n\t\t\t{{$:/core/images/chevron-down}}\n\t\t</$button>\n\t</$reveal>\n</div>\n<div class=\"tc-plugin-info-chunk tc-plugin-info-icon\">\n\t<$transclude tiddler=<<currentTiddler>> subtiddler=<<plugin-icon-title>>>\n\t\t<$transclude tiddler=\"$:/core/images/plugin-generic-$type$\"/>\n\t</$transclude>\n</div>\n<div class=\"tc-plugin-info-chunk tc-plugin-info-description\">\n\t<h1>\n\t\t''<$text text={{{ [<currentTiddler>get[name]] ~[<currentTiddler>split[/]last[1]] }}}/>'':&nbsp;<$view field=\"description\"><$view field=\"title\"/></$view>&nbsp;$disabledMessage$\n\t</h1>\n\t<h2>\n\t\t<$view field=\"title\"/>\n\t</h2>\n\t<h2>\n\t\t<div>\n\t\t\t<%if [<currentTiddler>get[stability]match[STABILITY_0_DEPRECATED]] %>\n\t\t\t\t<span class=\"tc-plugin-info-stability tc-plugin-info-stability-deprecated\"><<lingo \"Stability/Deprecated\">></span>\n\t\t\t<%elseif [<currentTiddler>get[stability]match[STABILITY_1_EXPERIMENTAL]] %>\n\t\t\t\t<span class=\"tc-plugin-info-stability tc-plugin-info-stability-experimental\"><<lingo \"Stability/Experimental\">></span>\n\t\t\t<%elseif [<currentTiddler>get[stability]match[STABILITY_2_STABLE]] %>\n\t\t\t\t<span class=\"tc-plugin-info-stability tc-plugin-info-stability-stable\"><<lingo \"Stability/Stable\">></span>\n\t\t\t<%elseif [<currentTiddler>get[stability]match[STABILITY_3_LEGACY]] %>\n\t\t\t\t<span class=\"tc-plugin-info-stability tc-plugin-info-stability-legacy\"><<lingo \"Stability/Legacy\">></span>\n\t\t\t<%endif%>\n\t\t\t<em><$view field=\"version\"/></em></div>\n\t</h2>\n</div>\n\\end\n\n\\define plugin-info(type,default-popup-state)\n\\whitespace trim\n<$set name=\"popup-state\" value=<<popup-state-macro>>>\n\t<$reveal type=\"nomatch\" state=<<plugin-disable-title>> text=\"yes\">\n\t\t<$link to={{!!title}} class=\"tc-plugin-info\">\n\t\t\t<<plugin-table-body type:\"$type$\" default-popup-state:\"\"\"$default-popup-state$\"\"\">>\n\t\t</$link>\n\t</$reveal>\n\t<$reveal type=\"match\" state=<<plugin-disable-title>> text=\"yes\">\n\t\t<$link to={{!!title}} class=\"tc-plugin-info tc-plugin-info-disabled\">\n\t\t\t<<plugin-table-body type:\"$type$\" default-popup-state:\"\"\"$default-popup-state$\"\"\" disabledMessage:\"<$macrocall $name='lingo' title='Disabled/Status'/>\">>\n\t\t</$link>\n\t</$reveal>\n\t<$reveal type=\"match\" text=\"yes\" state=<<popup-state>> default=\"\"\"$default-popup-state$\"\"\">\n\t\t<div class=\"tc-plugin-info-dropdown\">\n\t\t\t<div class=\"tc-plugin-info-dropdown-body\">\n\t\t\t\t<$list filter=\"[all[current]] -[[$:/core]]\">\n\t\t\t\t\t<div style=\"float:right;\">\n\t\t\t\t\t\t<$reveal type=\"nomatch\" state=<<plugin-disable-title>> text=\"yes\">\n\t\t\t\t\t\t\t<$button set=<<plugin-disable-title>> setTo=\"yes\" tooltip={{$:/language/ControlPanel/Plugins/Disable/Hint}} aria-label={{$:/language/ControlPanel/Plugins/Disable/Caption}}>\n\t\t\t\t\t\t\t\t<<lingo Disable/Caption>>\n\t\t\t\t\t\t\t</$button>\n\t\t\t\t\t\t</$reveal>\n\t\t\t\t\t\t<$reveal type=\"match\" state=<<plugin-disable-title>> text=\"yes\">\n\t\t\t\t\t\t\t<$button set=<<plugin-disable-title>> setTo=\"no\" tooltip={{$:/language/ControlPanel/Plugins/Enable Hint}} aria-label={{$:/language/ControlPanel/Plugins/Enable/Caption}}>\n\t\t\t\t\t\t\t\t<<lingo Enable/Caption>>\n\t\t\t\t\t\t\t</$button>\n\t\t\t\t\t\t</$reveal>\n\t\t\t\t\t</div>\n\t\t\t\t</$list>\n\t\t\t\t<$set name=\"tabsList\" filter=\"[<currentTiddler>list[]] contents\">\n\t\t\t\t\t<$macrocall $name=\"tabs\" state=<<tabs-state-macro>> tabsList=<<tabsList>> default={{{ [enlist<tabsList>] }}} template=\"$:/core/ui/PluginInfo\"/>\n\t\t\t\t</$set>\n\t\t\t</div>\n\t\t</div>\n\t</$reveal>\n</$set>\n\\end\n\n<$macrocall $name=\"plugin-info\" type=<<plugin-type>> default-popup-state=<<default-popup-state>>/>\n"},"$:/core/ui/Components/tag-link":{"title":"$:/core/ui/Components/tag-link","text":"\\whitespace trim\n<$link>\n<$set name=\"backgroundColor\" value={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}}>\n<span style=<<tag-styles>> class=\"tc-tag-label\">\n<$view field=\"title\" format=\"text\"/>\n</span>\n</$set>\n</$link>"},"$:/core/ui/ControlPanel/Advanced":{"title":"$:/core/ui/ControlPanel/Advanced","tags":"$:/tags/ControlPanel/Info","caption":"{{$:/language/ControlPanel/Advanced/Caption}}","text":"\\whitespace trim\n{{$:/language/ControlPanel/Advanced/Hint}}\n\n<div class=\"tc-control-panel\">\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Advanced]!has[draft.of]]\" default=\"$:/core/ui/ControlPanel/TiddlerFields\" explicitState=\"$:/state/tab--959111941\"/>\n</div>\n"},"$:/core/ui/ControlPanel/Appearance":{"title":"$:/core/ui/ControlPanel/Appearance","tags":"$:/tags/ControlPanel","caption":"{{$:/language/ControlPanel/Appearance/Caption}}","text":"\\whitespace trim\n{{$:/language/ControlPanel/Appearance/Hint}}\n\n<div class=\"tc-control-panel\">\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Appearance]!has[draft.of]]\" default=\"$:/core/ui/ControlPanel/Theme\" explicitState=\"$:/state/tab--1963855381\"/>\n</div>\n"},"$:/snippets/retain-story-ordering-button":{"title":"$:/snippets/retain-story-ordering-button","text":"<$button set=\"$:/DefaultTiddlers\" setTo={{$:/config/ControlPanel/Basics/DefaultTiddlers/RetainStory}} ><<currentTiddler>></$button>"},"$:/core/ui/ControlPanel/Basics":{"title":"$:/core/ui/ControlPanel/Basics","tags":"$:/tags/ControlPanel/Info","caption":"{{$:/language/ControlPanel/Basics/Caption}}","text":"\\procedure lingo-base() $:/language/ControlPanel/Basics/\n\\whitespace trim\n\n|tc-max-width tc-edit-max-width|k\n|<<lingo Version/Prompt>> |''<<version>>'' |\n|<$link to=\"$:/SiteTitle\"><<lingo Title/Prompt>></$link> |<$edit-text tiddler=\"$:/SiteTitle\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/SiteSubtitle\"><<lingo Subtitle/Prompt>></$link> |<$edit-text tiddler=\"$:/SiteSubtitle\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/status/UserName\"><<lingo Username/Prompt>></$link> |<$edit-text tiddler=\"$:/status/UserName\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/config/AnimationDuration\"><<lingo AnimDuration/Prompt>></$link> |<$edit-text tiddler=\"$:/config/AnimationDuration\" default=\"\" tag=\"input\" type=\"number\"/> |\n|<$link to=\"$:/DefaultTiddlers\"><<lingo DefaultTiddlers/Prompt>></$link> |<<lingo DefaultTiddlers/TopHint>><br> <$edit class=\"tc-edit-texteditor\" tiddler=\"$:/DefaultTiddlers\" autoHeight=\"yes\"/><br>//<<lingo DefaultTiddlers/BottomHint>>// |\n|<$link to=\"$:/language/DefaultNewTiddlerTitle\"><<lingo NewTiddler/Title/Prompt>></$link> |<$edit-text tiddler=\"$:/language/DefaultNewTiddlerTitle\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/config/NewJournal/Title\"><<lingo NewJournal/Title/Prompt>></$link> |<$edit-text tiddler=\"$:/config/NewJournal/Title\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/config/NewJournal/Text\"><<lingo NewJournal/Text/Prompt>></$link> |<$edit tiddler=\"$:/config/NewJournal/Text\" class=\"tc-edit-texteditor\" default=\"\" autoHeight=\"yes\"/> |\n|<$link to=\"$:/config/NewTiddler/Tags\"><<lingo NewTiddler/Tags/Prompt>></$link> |<$vars currentTiddler=\"$:/config/NewTiddler/Tags\" tagField=\"text\">{{||$:/core/ui/EditTemplate/tags}}<$list filter=\"[<currentTiddler>tags[]] +[limit[1]]\" variable=\"ignore\"><$button tooltip={{$:/language/ControlPanel/Basics/RemoveTags/Hint}}><<lingo RemoveTags>><$action-listops $tiddler=<<currentTiddler>> $field=\"text\" $subfilter={{{ [<currentTiddler>get[tags]] }}}/><$action-setfield $tiddler=<<currentTiddler>> tags=\"\"/></$button></$list></$vars> |\n|<$link to=\"$:/config/NewJournal/Tags\"><<lingo NewJournal/Tags/Prompt>></$link> |<$vars currentTiddler=\"$:/config/NewJournal/Tags\" tagField=\"text\">{{||$:/core/ui/EditTemplate/tags}}<$list filter=\"[<currentTiddler>tags[]] +[limit[1]]\" variable=\"ignore\"><$button tooltip={{$:/language/ControlPanel/Basics/RemoveTags/Hint}}><<lingo RemoveTags>><$action-listops $tiddler=<<currentTiddler>> $field=\"text\" $subfilter={{{ [<currentTiddler>get[tags]] }}}/><$action-setfield $tiddler=<<currentTiddler>> tags=\"\"/></$button></$list></$vars> |\n|<$link to=\"$:/config/AutoFocus\"><<lingo AutoFocus/Prompt>></$link> |{{$:/snippets/minifocusswitcher}} |\n|<<lingo Language/Prompt>> |{{$:/snippets/minilanguageswitcher}} |\n|<<lingo Tiddlers/Prompt>> |<<show-filter-count \"[!is[system]sort[title]]\">> |\n|<<lingo Tags/Prompt>> |<<show-filter-count \"[tags[]sort[title]]\">> |\n|<<lingo SystemTiddlers/Prompt>> |<<show-filter-count \"[is[system]sort[title]]\">> |\n|<<lingo ShadowTiddlers/Prompt>> |<<show-filter-count \"[all[shadows]sort[title]]\">> |\n|<<lingo OverriddenShadowTiddlers/Prompt>> |<<show-filter-count \"[is[tiddler]is[shadow]sort[title]]\">> |\n"},"$:/core/ui/ControlPanel/EditTemplateBody":{"title":"$:/core/ui/ControlPanel/EditTemplateBody","tags":"$:/tags/ControlPanel/Cascades","caption":"{{$:/language/ControlPanel/EditTemplateBody/Caption}}","text":"\\define lingo-base() $:/language/ControlPanel/EditTemplateBody/\n\n<<lingo Hint>>\n\n{{$:/tags/EditTemplateBodyFilter||$:/snippets/ListTaggedCascade}}\n"},"$:/core/ui/ControlPanel/FieldEditor":{"title":"$:/core/ui/ControlPanel/FieldEditor","tags":"$:/tags/ControlPanel/Cascades","caption":"{{$:/language/ControlPanel/FieldEditor/Caption}}","text":"\\define lingo-base() $:/language/ControlPanel/FieldEditor/\n\n<<lingo Hint>>\n\n{{$:/tags/FieldEditorFilter||$:/snippets/ListTaggedCascade}}\n"},"$:/core/ui/ControlPanel/StoryTiddler":{"title":"$:/core/ui/ControlPanel/StoryTiddler","tags":"$:/tags/ControlPanel/Cascades","caption":"{{$:/language/ControlPanel/StoryTiddler/Caption}}","text":"\\define lingo-base() $:/language/ControlPanel/StoryTiddler/\n\n<<lingo Hint>>\n\n{{$:/tags/StoryTiddlerTemplateFilter||$:/snippets/ListTaggedCascade}}\n"},"$:/core/ui/ControlPanel/TiddlerColour":{"title":"$:/core/ui/ControlPanel/TiddlerColour","tags":"$:/tags/ControlPanel/Cascades","caption":"{{$:/language/ControlPanel/TiddlerColour/Caption}}","text":"\\define lingo-base() $:/language/ControlPanel/TiddlerColour/\n\n<<lingo Hint>>\n\n{{$:/tags/TiddlerColourFilter||$:/snippets/ListTaggedCascade}}\n"},"$:/core/ui/ControlPanel/TiddlerIcon":{"title":"$:/core/ui/ControlPanel/TiddlerIcon","tags":"$:/tags/ControlPanel/Cascades","caption":"{{$:/language/ControlPanel/TiddlerIcon/Caption}}","text":"\\define lingo-base() $:/language/ControlPanel/TiddlerIcon/\n\n<<lingo Hint>>\n\n{{$:/tags/TiddlerIconFilter||$:/snippets/ListTaggedCascade}}\n"},"$:/core/ui/ControlPanel/ViewTemplateBody":{"title":"$:/core/ui/ControlPanel/ViewTemplateBody","tags":"$:/tags/ControlPanel/Cascades","caption":"{{$:/language/ControlPanel/ViewTemplateBody/Caption}}","text":"\\define lingo-base() $:/language/ControlPanel/ViewTemplateBody/\n\n<<lingo Hint>>\n\n{{$:/tags/ViewTemplateBodyFilter||$:/snippets/ListTaggedCascade}}\n"},"$:/core/ui/ControlPanel/ViewTemplateSubtitle":{"title":"$:/core/ui/ControlPanel/ViewTemplateSubtitle","tags":"$:/tags/ControlPanel/Cascades","caption":"{{$:/language/ControlPanel/ViewTemplateSubtitle/Caption}}","text":"\\define lingo-base() $:/language/ControlPanel/ViewTemplateSubtitle/\n\n<<lingo Hint>>\n\n{{$:/tags/ViewTemplateSubtitleFilter||$:/snippets/ListTaggedCascade}}\n"},"$:/core/ui/ControlPanel/ViewTemplateTags":{"title":"$:/core/ui/ControlPanel/ViewTemplateTags","tags":"$:/tags/ControlPanel/Cascades","caption":"{{$:/language/ControlPanel/ViewTemplateTags/Caption}}","text":"\\define lingo-base() $:/language/ControlPanel/ViewTemplateTags/\n\n<<lingo Hint>>\n\n{{$:/tags/ViewTemplateTagsFilter||$:/snippets/ListTaggedCascade}}\n"},"$:/core/ui/ControlPanel/ViewTemplateTitle":{"title":"$:/core/ui/ControlPanel/ViewTemplateTitle","tags":"$:/tags/ControlPanel/Cascades","caption":"{{$:/language/ControlPanel/ViewTemplateTitle/Caption}}","text":"\\define lingo-base() $:/language/ControlPanel/ViewTemplateTitle/\n\n<<lingo Hint>>\n\n{{$:/tags/ViewTemplateTitleFilter||$:/snippets/ListTaggedCascade}}\n"},"$:/core/ui/ControlPanel/Cascades":{"title":"$:/core/ui/ControlPanel/Cascades","tags":"$:/tags/ControlPanel/Advanced","caption":"{{$:/language/ControlPanel/Cascades/Caption}}","text":"\\whitespace trim\n{{$:/language/ControlPanel/Cascades/Hint}}\n\n<div class=\"tc-control-panel\">\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Cascades]!has[draft.of]]\" default=\"$:/core/ui/ControlPanel/StoryTiddler\"/>\n</div>\n"},"$:/core/ui/ControlPanel/EditorTypes":{"title":"$:/core/ui/ControlPanel/EditorTypes","tags":"$:/tags/ControlPanel/Advanced","caption":"{{$:/language/ControlPanel/EditorTypes/Caption}}","text":"\\define lingo-base() $:/language/ControlPanel/EditorTypes/\n\\whitespace trim\n\n<<lingo Hint>>\n\n<table>\n<tbody>\n<tr>\n<th><<lingo Type/Caption>></th>\n<th><<lingo Editor/Caption>></th>\n</tr>\n<$list filter=\"[all[shadows+tiddlers]prefix[$:/config/EditorTypeMappings/]sort[title]]\">\n<tr>\n<td>\n<$link>\n<$list filter=\"[all[current]removeprefix[$:/config/EditorTypeMappings/]]\">\n<$text text={{!!title}}/>\n</$list>\n</$link>\n</td>\n<td>\n<$view field=\"text\"/>\n</td>\n</tr>\n</$list>\n</tbody>\n</table>\n"},"$:/core/ui/ControlPanel/Info":{"title":"$:/core/ui/ControlPanel/Info","tags":"$:/tags/ControlPanel","caption":"{{$:/language/ControlPanel/Info/Caption}}","text":"\\whitespace trim\n{{$:/language/ControlPanel/Info/Hint}}\n\n<div class=\"tc-control-panel\">\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Info]!has[draft.of]]\" default=\"$:/core/ui/ControlPanel/Basics\" explicitState=\"$:/state/tab--2112689675\"/>\n</div>\n"},"$:/core/ui/ControlPanel/KeyboardShortcuts":{"title":"$:/core/ui/ControlPanel/KeyboardShortcuts","tags":"$:/tags/ControlPanel","caption":"{{$:/language/ControlPanel/KeyboardShortcuts/Caption}}","text":"\\define lingo-base() $:/language/ControlPanel/KeyboardShortcuts/\n\n\\define new-shortcut(title)\n\\whitespace trim\n<div class=\"tc-dropdown-item-plain\">\n<$edit-shortcut tiddler=\"$title$\" placeholder={{$:/language/ControlPanel/KeyboardShortcuts/Add/Prompt}} focus=\"true\" style=\"width:auto;\"/>\n&#32;\n<$button>\n<<lingo Add/Caption>>\n<$action-listops\n\t$tiddler=\"$(shortcutTitle)$\"\n\t$field=\"text\"\n\t$subfilter=\"[{$title$}]\"\n/>\n<$action-deletetiddler\n\t$tiddler=\"$title$\"\n/>\n</$button>\n</div>\n\\end\n\n\\define shortcut-list-item(caption)\n\\whitespace trim\n<td>\n</td>\n<td style=\"text-align:right;font-size:0.7em;\">\n<<lingo Platform/$caption$>>\n</td>\n<td>\n<div style=\"position:relative;\">\n<$button popup=<<qualify \"$:/state/dropdown/$(shortcutTitle)$\">> class=\"tc-btn-invisible\">\n{{$:/core/images/edit-button}}\n</$button>\n&#32;\n<$macrocall $name=\"displayshortcuts\" $output=\"text/html\" shortcuts={{$(shortcutTitle)$}} prefix=\"<kbd>\" separator=\"</kbd> <kbd>\" suffix=\"</kbd>\"/>\n\n<$reveal state=<<qualify \"$:/state/dropdown/$(shortcutTitle)$\">> type=\"popup\" position=\"below\" animate=\"yes\">\n<div class=\"tc-block-dropdown-wrapper\">\n<div class=\"tc-block-dropdown tc-edit-type-dropdown tc-popup-keep\">\n<$list\n\tfilter=\"[list[$(shortcutTitle)$!!text]sort[title]]\"\n\tvariable=\"shortcut\"\n\temptyMessage=\"<div class='tc-dropdown-item-plain'>//<<lingo NoShortcuts/Caption>>//</div>\">\n<div class=\"tc-dropdown-item-plain\">\n<$button class=\"tc-btn-invisible\" tooltip={{$:/language/ControlPanel/KeyboardShortcuts/Remove/Hint}}>\n<$action-listops\n\t$tiddler=\"$(shortcutTitle)$\"\n\t$field=\"text\"\n\t$subfilter=\"+[remove<shortcut>]\"\n/>\n<small>{{$:/core/images/close-button}}</small>\n</$button>\n&#32;\n<kbd>\n<$macrocall $name=\"displayshortcuts\" $output=\"text/html\" shortcuts=<<shortcut>>/>\n</kbd>\n</div>\n</$list>\n<hr/>\n<$macrocall $name=\"new-shortcut\" title=<<qualify \"$:/state/new-shortcut/$(shortcutTitle)$\">>/>\n</div>\n</div>\n</$reveal>\n</div>\n</td>\n\\end\n\n\\define shortcut-list(caption,prefix)\n\\whitespace trim\n<tr>\n<$list filter=\"[[$prefix$$(shortcutName)$]]\" variable=\"shortcutTitle\">\n<<shortcut-list-item \"$caption$\">>\n</$list>\n</tr>\n\\end\n\n\\define shortcut-editor()\n\\whitespace trim\n<<shortcut-list \"All\" \"$:/config/shortcuts/\">> \n<<shortcut-list \"Mac\" \"$:/config/shortcuts-mac/\">>\n<<shortcut-list \"NonMac\" \"$:/config/shortcuts-not-mac/\">>\n<<shortcut-list \"Linux\" \"$:/config/shortcuts-linux/\">>\n<<shortcut-list \"NonLinux\" \"$:/config/shortcuts-not-linux/\">>\n<<shortcut-list \"Windows\" \"$:/config/shortcuts-windows/\">>\n<<shortcut-list \"NonWindows\" \"$:/config/shortcuts-not-windows/\">>\n\\end\n\n\\define shortcut-preview()\n<$macrocall $name=\"displayshortcuts\" $output=\"text/html\" shortcuts={{$(shortcutPrefix)$$(shortcutName)$}} prefix=\"<kbd>\" separator=\"</kbd> <kbd>\" suffix=\"</kbd>\"/>\n\\end\n\n\\define shortcut-item-inner()\n\\whitespace trim\n<tr>\n<td>\n<$reveal type=\"nomatch\" state=<<dropdownStateTitle>> text=\"open\">\n<$button class=\"tc-btn-invisible\">\n<$action-setfield\n\t$tiddler=<<dropdownStateTitle>>\n\t$value=\"open\"\n/>\n{{$:/core/images/right-arrow}}\n</$button>\n</$reveal>\n<$reveal type=\"match\" state=<<dropdownStateTitle>> text=\"open\">\n<$button class=\"tc-btn-invisible\">\n<$action-setfield\n\t$tiddler=<<dropdownStateTitle>>\n\t$value=\"close\"\n/>\n{{$:/core/images/down-arrow}}\n</$button>\n</$reveal>\n&#32;\n''<$text text=<<shortcutName>>/>''\n</td>\n<td>\n<$transclude tiddler=\"$:/config/ShortcutInfo/$(shortcutName)$\"/>\n</td>\n<td>\n<$list filter=\"$:/config/shortcuts/ $:/config/shortcuts-mac/ $:/config/shortcuts-not-mac/ $:/config/shortcuts-linux/ $:/config/shortcuts-not-linux/ $:/config/shortcuts-windows/ $:/config/shortcuts-not-windows/\" variable=\"shortcutPrefix\">\n<<shortcut-preview>>\n</$list>\n</td>\n</tr>\n<$set name=\"dropdownState\" value={{$(dropdownStateTitle)$}}>\n<$list filter=\"[<dropdownState>match[open]]\" variable=\"listItem\">\n<<shortcut-editor>>\n</$list>\n</$set>\n\\end\n\n\\define shortcut-item()\n\\whitespace trim\n<$set name=\"dropdownStateTitle\" value=<<qualify \"$:/state/dropdown/keyboardshortcut/$(shortcutName)$\">>>\n<<shortcut-item-inner>>\n</$set>\n\\end\n\\whitespace trim\n\n<table>\n<tbody>\n<$list filter=\"[all[shadows+tiddlers]removeprefix[$:/config/ShortcutInfo/]]\" variable=\"shortcutName\">\n<<shortcut-item>>\n</$list>\n</tbody>\n</table>\n"},"$:/core/ui/ControlPanel/LoadedModules":{"title":"$:/core/ui/ControlPanel/LoadedModules","tags":"$:/tags/ControlPanel/Advanced","caption":"{{$:/language/ControlPanel/LoadedModules/Caption}}","text":"\\define lingo-base() $:/language/ControlPanel/\n<<lingo LoadedModules/Hint>>\n\n{{$:/snippets/modules}}\n"},"$:/core/ui/ControlPanel/Modals/AddPlugins":{"title":"$:/core/ui/ControlPanel/Modals/AddPlugins","subtitle":"{{$:/core/images/download-button}} {{$:/language/ControlPanel/Plugins/Add/Caption}}","text":"\\define install-plugin-actions()\n\\whitespace trim\n<$action-sendmessage $message=\"tm-load-plugin-from-library\" url={{!!url}} title={{$(assetInfo)$!!original-title}}/>\n<$set name=\"url\" value={{!!url}}>\n<$set name=\"currentTiddler\" value=<<assetInfo>>>\n<$list filter=\"[enlist{!!dependents}] [{!!parent-plugin}] +[sort[name]]\" variable=\"dependency\">\n<$action-sendmessage $message=\"tm-load-plugin-from-library\" url=<<url>> title=<<dependency>>/>\n</$list>\n</$set>\n</$set>\n\\end\n\n\\define install-plugin-button()\n\\whitespace trim\n<div>\n<$set name=\"libraryVersion\" value={{{ [<assetInfo>get[version]] }}}>\n<$set name=\"installedVersion\" value={{{ [<assetInfo>get[original-title]get[version]] }}}>\n<$set name=\"reinstall-type\" value={{{ [<libraryVersion>compare:version:eq<installedVersion>then[tc-reinstall]] [<libraryVersion>compare:version:gt<installedVersion>then[tc-reinstall-upgrade]] [<libraryVersion>compare:version:lt<installedVersion>then[tc-reinstall-downgrade]] }}}>\n<$button actions=<<install-plugin-actions>> class={{{ [<assetInfo>get[original-title]has[version]then<reinstall-type>] tc-btn-invisible tc-install-plugin +[join[ ]] }}}>\n{{$:/core/images/download-button}}\n&#32;\n<$list filter=\"[<assetInfo>get[original-title]get[version]]\" variable=\"ignore\" emptyMessage=\"{{$:/language/ControlPanel/Plugins/Install/Caption}}\">\n<$list filter=\"[<libraryVersion>compare:version:gt<installedVersion>]\" variable=\"ignore\" emptyMessage=\"\n\\whitespace trim\n<$list filter='[<libraryVersion>compare:version:lt<installedVersion>]' variable='ignore' emptyMessage='{{$:/language/ControlPanel/Plugins/Reinstall/Caption}}'>\n{{$:/language/ControlPanel/Plugins/Downgrade/Caption}}\n</$list>\n\">\n{{$:/language/ControlPanel/Plugins/Update/Caption}}\n</$list>\n</$list>\n</$button>\n<div>\n</div>\n<$reveal stateTitle=<<assetInfo>> stateField=\"requires-reload\" type=\"match\" text=\"yes\">{{$:/language/ControlPanel/Plugins/PluginWillRequireReload}}</$reveal>\n</$set>\n</$set>\n</$set>\n</div>\n\\end\n\n\\define popup-state-macro()\n$:/state/add-plugin-info/$(connectionTiddler)$/$(assetInfo)$\n\\end\n\n\\define display-plugin-info(type)\n\\whitespace trim\n<$set name=\"popup-state\" value=<<popup-state-macro>>>\n<div class=\"tc-plugin-info\">\n<div class=\"tc-plugin-info-chunk tc-plugin-info-toggle\">\n<$reveal type=\"nomatch\" state=<<popup-state>> text=\"yes\">\n<$button class=\"tc-btn-invisible tc-btn-dropdown\" set=<<popup-state>> setTo=\"yes\">\n{{$:/core/images/chevron-right}}\n</$button>\n</$reveal>\n<$reveal type=\"match\" state=<<popup-state>> text=\"yes\">\n<$button class=\"tc-btn-invisible tc-btn-dropdown\" set=<<popup-state>> setTo=\"no\">\n{{$:/core/images/chevron-down}}\n</$button>\n</$reveal>\n</div>\n<div class=\"tc-plugin-info-chunk tc-plugin-info-icon\">\n<$list filter=\"[<assetInfo>has[icon]]\" emptyMessage=\"\"\"<$transclude tiddler=\"$:/core/images/plugin-generic-$type$\"/>\"\"\">\n<img src={{$(assetInfo)$!!icon}}/>\n</$list>\n</div>\n<div class=\"tc-plugin-info-chunk tc-plugin-info-description\">\n<h1><strong><$text text={{{ [<assetInfo>get[name]] ~[<assetInfo>get[original-title]split[/]last[1]] }}}/></strong>:\n&#32;\n<$view tiddler=<<assetInfo>> field=\"description\"/>\n</h1>\n<h2><$view tiddler=<<assetInfo>> field=\"original-title\"/></h2>\n<div>\n<%if [<assetInfo>get[stability]match[STABILITY_0_DEPRECATED]] %>\n\t<span class=\"tc-plugin-info-stability tc-plugin-info-stability-deprecated\">{{$:/language/ControlPanel/Plugins/Stability/Deprecated}}</span>\n<%elseif [<assetInfo>get[stability]match[STABILITY_1_EXPERIMENTAL]] %>\n\t<span class=\"tc-plugin-info-stability tc-plugin-info-stability-experimental\">{{$:/language/ControlPanel/Plugins/Stability/Experimental}}</span>\n<%elseif [<assetInfo>get[stability]match[STABILITY_2_STABLE]] %>\n\t<span class=\"tc-plugin-info-stability tc-plugin-info-stability-stable\">{{$:/language/ControlPanel/Plugins/Stability/Stable}}</span>\n<%elseif [<assetInfo>get[stability]match[STABILITY_3_LEGACY]] %>\n\t<span class=\"tc-plugin-info-stability tc-plugin-info-stability-legacy\">{{$:/language/ControlPanel/Plugins/Stability/Legacy}}</span>\n<%endif%>\n<em><$view tiddler=<<assetInfo>> field=\"version\"/></em></div>\n<$list filter=\"[<assetInfo>get[original-title]get[version]]\" variable=\"installedVersion\"><div><em>{{$:/language/ControlPanel/Plugins/AlreadyInstalled/Hint}}</em></div></$list>\n</div>\n<div class=\"tc-plugin-info-chunk tc-plugin-info-buttons\">\n<<install-plugin-button>>\n</div>\n</div>\n<$set name=\"original-title\" value={{{ [<assetInfo>get[original-title]] }}}>\n<$reveal type=\"match\" text=\"yes\" state=<<popup-state>>>\n<div class=\"tc-plugin-info-dropdown\">\n<$list filter=\"[enlist{!!dependents}] [<currentTiddler>get[parent-plugin]] +[limit[1]] ~[<assetInfo>get[original-title]!is[tiddler]]\" variable=\"ignore\">\n<div class=\"tc-plugin-info-dropdown-message\">\n<$list filter=\"[<assetInfo>get[original-title]!is[tiddler]]\">\n{{$:/language/ControlPanel/Plugins/NotInstalled/Hint}}\n</$list>\n<$set name=\"currentTiddler\" value=<<assetInfo>>>\n<$list filter=\"[enlist{!!dependents}] [<currentTiddler>get[parent-plugin]] +[limit[1]]\" variable=\"ignore\">\n<div>\n{{$:/language/ControlPanel/Plugins/AlsoRequires}}&#32;\n<$list filter=\"[enlist{!!dependents}] [{!!parent-plugin}] +[sort[name]]\" variable=\"dependency\">\n<$text text=<<dependency>>/>&#32;\n</$list>\n</div>\n</$list>\n</$set>\n</div>\n</$list>\n<div class=\"tc-plugin-info-dropdown-body\">\n<$transclude tiddler=<<assetInfo>> field=\"readme\" mode=\"block\"/>\n</div>\n<$list filter=\"[all[tiddlers+shadows]tag[$:/tags/RemoteAssetInfo]server-url{!!url}original-plugin-type[$type$]has[parent-plugin]parent-plugin<original-title>limit[1]]\" variable=\"ignore\">\n<div class=\"tc-plugin-info-sub-plugins\">\n<$list filter=\"[all[tiddlers+shadows]tag[$:/tags/RemoteAssetInfo]server-url{!!url}original-plugin-type[$type$]has[parent-plugin]parent-plugin<original-title>sort[name]]\" variable=\"assetInfo\">\n<<display-plugin-info \"$type$\">>\n</$list>\n</div>\n</$list>\n</div>\n</$reveal>\n<$list filter=\"[all[tiddlers+shadows]tag[$:/tags/RemoteAssetInfo]server-url{!!url}original-plugin-type[$type$]has[parent-plugin]parent-plugin<original-title>limit[1]]\" variable=\"ignore\">\n<$reveal type=\"nomatch\" text=\"yes\" state=<<popup-state>> tag=\"div\" class=\"tc-plugin-info-sub-plugin-indicator\">\n<$wikify name=\"count\" text=\"\"\"<$count filter=\"[all[tiddlers+shadows]tag[$:/tags/RemoteAssetInfo]server-url{!!url}original-plugin-type[$type$]has[parent-plugin]parent-plugin<original-title>]\"/>\"\"\">\n<$button class=\"tc-btn-invisible\" set=<<popup-state>> setTo=\"yes\">\n{{$:/language/ControlPanel/Plugins/SubPluginPrompt}}\n</$button>\n</$wikify>\n</$reveal>\n</$list>\n</$set>\n</$set>\n\\end\n\n\\define load-plugin-library-button()\n\\whitespace trim\n<$list filter=\"[<currentTiddler>get[enabled]else[yes]match[yes]]\" variable=\"ignore\">\n<$button class=\"tc-btn-big-green\">\n<$action-sendmessage $message=\"tm-load-plugin-library\" url={{!!url}} infoTitlePrefix=\"$:/temp/RemoteAssetInfo/\"/>\n{{$:/core/images/chevron-right}}&#32;{{$:/language/ControlPanel/Plugins/OpenPluginLibrary}}\n</$button>\n</$list>\n\\end\n\n\\define display-server-assets(type)\n\\whitespace trim\n{{$:/language/Search/Search}}:\n&#32;\n<$edit-text tiddler=\"\"\"$:/temp/RemoteAssetSearch/$(currentTiddler)$\"\"\" default=\"\" type=\"search\" tag=\"input\"/>\n&#32;\n<$reveal state=\"\"\"$:/temp/RemoteAssetSearch/$(currentTiddler)$\"\"\" type=\"nomatch\" text=\"\">\n<$button class=\"tc-btn-invisible\">\n<$action-setfield $tiddler=\"\"\"$:/temp/RemoteAssetSearch/$(currentTiddler)$\"\"\" $field=\"text\" $value=\"\"/>\n{{$:/core/images/close-button}}\n</$button>\n</$reveal>\n<div class=\"tc-plugin-library-listing\">\n<$list filter=\"[all[tiddlers+shadows]tag[$:/tags/RemoteAssetInfo]server-url{!!url}original-plugin-type[$type$]search:author,description,original-title,readme,title{$:/temp/RemoteAssetSearch/$(currentTiddler)$}sort[name]]\" variable=\"assetInfo\">\n<$list filter=\"[[$:/temp/RemoteAssetSearch/$(currentTiddler)$]has[text]] ~[<assetInfo>!has[parent-plugin]]\" variable=\"ignore\"><!-- Hide sub-plugins if we're not searching -->\n<<display-plugin-info \"$type$\">>\n</$list>\n</$list>\n</div>\n\\end\n\n\\define display-server-connection()\n\\whitespace trim\n<$list filter=\"[all[tiddlers+shadows]tag[$:/tags/ServerConnection]suffix{!!url}]\" variable=\"connectionTiddler\" emptyMessage=<<load-plugin-library-button>>>\n\n<$set name=\"transclusion\" value=<<connectionTiddler>>>\n\n<<tabs \"[[$:/core/ui/ControlPanel/Plugins/Add/Updates]] [[$:/core/ui/ControlPanel/Plugins/Add/Plugins]] [[$:/core/ui/ControlPanel/Plugins/Add/Themes]] [[$:/core/ui/ControlPanel/Plugins/Add/Languages]]\" \"$:/core/ui/ControlPanel/Plugins/Add/Plugins\">>\n\n</$set>\n\n</$list>\n\\end\n\n\\define close-library-button()\n\\whitespace trim\n<$reveal type='nomatch' state='$:/temp/ServerConnection/$(PluginLibraryURL)$' text=''>\n<$button class='tc-btn-big-green'>\n<$action-sendmessage $message=\"tm-unload-plugin-library\" url={{!!url}}/>\n{{$:/core/images/chevron-left}}&#32;{{$:/language/ControlPanel/Plugins/ClosePluginLibrary}}\n<$action-deletetiddler $filter=\"[prefix[$:/temp/ServerConnection/$(PluginLibraryURL)$]][prefix[$:/temp/RemoteAssetInfo/$(PluginLibraryURL)$]]\"/>\n</$button>\n</$reveal>\n\\end\n\n\\define plugin-library-listing()\n\\whitespace trim\n<div class=\"tc-tab-set\">\n<$set name=\"defaultTab\" value={{{ [all[tiddlers+shadows]tag[$:/tags/PluginLibrary]] }}}>\n<div class=\"tc-tab-buttons\">\n<$list filter=\"[all[tiddlers+shadows]tag[$:/tags/PluginLibrary]]\">\n<$button set=<<qualify \"$:/state/addplugins/tab\">> setTo=<<currentTiddler>> default=<<defaultTab>> selectedClass=\"tc-tab-selected\">\n<$set name=\"tv-wikilinks\" value=\"no\">\n<$transclude field=\"caption\"/>\n</$set>\n</$button>\n</$list>\n</div>\n<div class=\"tc-tab-divider\"/>\n<div class=\"tc-tab-content\">\n<$list filter=\"[all[tiddlers+shadows]tag[$:/tags/PluginLibrary]]\">\n<$reveal type=\"match\" state=<<qualify \"$:/state/addplugins/tab\">> text=<<currentTiddler>> default=<<defaultTab>>>\n<h2><$link><$transclude field=\"caption\"><$view field=\"title\"/></$transclude></$link></h2>\n//<$view field=\"url\"/>//\n<$transclude mode=\"block\"/>\n<$set name=PluginLibraryURL value={{!!url}}>\n<<close-library-button>>\n</$set>\n&#32;\n<<display-server-connection>>\n</$reveal>\n</$list>\n</div>\n</$set>\n</div>\n\\end\n\n\\import [subfilter{$:/core/config/GlobalImportFilter}]\n\\whitespace trim\n\n<div>\n<<plugin-library-listing>>\n</div>\n"},"$:/core/ui/ControlPanel/Palette":{"title":"$:/core/ui/ControlPanel/Palette","tags":"$:/tags/ControlPanel/Appearance","caption":"{{$:/language/ControlPanel/Palette/Caption}}","text":"\\define lingo-base() $:/language/ControlPanel/Palette/\n\n{{$:/snippets/paletteswitcher}}\n\n<$reveal type=\"nomatch\" state=\"$:/state/ShowPaletteEditor\" text=\"yes\">\n\n<$button set=\"$:/state/ShowPaletteEditor\" setTo=\"yes\"><<lingo ShowEditor/Caption>></$button>\n\n</$reveal>\n\n<$reveal type=\"match\" state=\"$:/state/ShowPaletteEditor\" text=\"yes\">\n\n<$button set=\"$:/state/ShowPaletteEditor\" setTo=\"no\"><<lingo HideEditor/Caption>></$button>\n{{$:/PaletteManager}}\n\n</$reveal>\n\n"},"$:/core/ui/ControlPanel/Parsing":{"title":"$:/core/ui/ControlPanel/Parsing","tags":"$:/tags/ControlPanel/Advanced","caption":"{{$:/language/ControlPanel/Parsing/Caption}}","text":"\\define lingo-base() $:/language/ControlPanel/Parsing/\n\n\\define toggle(Type)\n\\whitespace trim\n<$checkbox\ntiddler=\"\"\"$:/config/WikiParserRules/$Type$/$(rule)$\"\"\"\nfield=\"text\"\nchecked=\"enable\"\nunchecked=\"disable\"\ndefault=\"enable\">\n<span class=\"tc-small-gap-left\"><<rule>></span>\n</$checkbox>\n\\end\n\n\\define rules(type,Type)\n\\whitespace trim\n<$list filter=\"[wikiparserrules[$type$]]\" variable=\"rule\">\n<dd><<toggle $Type$>></dd>\n</$list>\n\\end\n\\whitespace trim\n\n<<lingo Hint>>\n\n<dl>\n<dt><<lingo Pragma/Caption>></dt>\n<<rules pragma Pragma>>\n<dt><<lingo Inline/Caption>></dt>\n<<rules inline Inline>>\n<dt><<lingo Block/Caption>></dt>\n<<rules block Block>>\n</dl>"},"$:/core/ui/ControlPanel/Plugins/Add/Languages":{"title":"$:/core/ui/ControlPanel/Plugins/Add/Languages","caption":"{{$:/language/ControlPanel/Plugins/Languages/Caption}} (<$count filter=\"[all[tiddlers+shadows]tag[$:/tags/RemoteAssetInfo]server-url{!!url}original-plugin-type[language]]\"/>)","text":"<<display-server-assets language>>\n"},"$:/core/ui/ControlPanel/Plugins/Add/Plugins":{"title":"$:/core/ui/ControlPanel/Plugins/Add/Plugins","caption":"{{$:/language/ControlPanel/Plugins/Plugins/Caption}}  (<$count filter=\"[all[tiddlers+shadows]tag[$:/tags/RemoteAssetInfo]server-url{!!url}original-plugin-type[plugin]]\"/>)","text":"<<display-server-assets plugin>>\n"},"$:/core/ui/ControlPanel/Plugins/Add/Themes":{"title":"$:/core/ui/ControlPanel/Plugins/Add/Themes","caption":"{{$:/language/ControlPanel/Plugins/Themes/Caption}}  (<$count filter=\"[all[tiddlers+shadows]tag[$:/tags/RemoteAssetInfo]server-url{!!url}original-plugin-type[theme]]\"/>)","text":"<<display-server-assets theme>>\n"},"$:/core/ui/ControlPanel/Plugins/Add/Updates":{"title":"$:/core/ui/ControlPanel/Plugins/Add/Updates","caption":"<$importvariables filter=\"$:/core/ui/ControlPanel/Plugins/Add/Updates\">{{$:/language/ControlPanel/Plugins/Updates/Caption}} (<<update-count>>)</$importvariables>","text":"\\define each-updateable-plugin(body)\n\\whitespace trim\n<$list filter=\"[all[tiddlers+shadows]tag[$:/tags/RemoteAssetInfo]server-url{!!url}sort[title]]\" variable=\"assetInfo\">\n<$set name=\"libraryVersion\" value={{{ [<assetInfo>get[version]] }}}>\n<$list filter=\"[<assetInfo>get[original-title]has[version]!version<libraryVersion>]\" variable=\"ignore\">\n<$set name=\"installedVersion\" value={{{ [<assetInfo>get[original-title]get[version]] }}}>\n<$list filter=\"[<installedversion>!match<libraryVersion>]\" variable=\"ignore\">\n$body$\n</$list>\n</$set>\n</$list>\n</$set>\n</$list>\n\\end\n\n\\define update-all-actions()\n<$macrocall $name=\"each-updateable-plugin\" body=\"\"\"\n<<install-plugin-actions>>\n\"\"\"/>\n\\end\n\n\\define update-count()\n<$wikify name=\"count-filter\" text=<<each-updateable-plugin \"&#91;&#91;<$text text=<<assetInfo>>/>]]\">>><$count filter=<<count-filter>>/></$wikify>\n\\end\n\n\\whitespace trim\n<$button actions=<<update-all-actions>> class=\"tc-btn-invisible tc-install-plugin tc-reinstall-upgrade\">\n{{$:/core/images/download-button}}\n&#32;\n{{||$:/language/ControlPanel/Plugins/Updates/UpdateAll/Caption}}\n</$button>\n\n<div class=\"tc-plugin-library-listing\">\n<$macrocall $name=\"each-updateable-plugin\" body=\"\"\"\n<$macrocall $name=\"display-plugin-info\" type={{{ [<assetInfo>get[original-plugin-type]] }}}/>\n\"\"\"/>\n</div>\n"},"$:/core/ui/ControlPanel/Plugins/AddPlugins":{"title":"$:/core/ui/ControlPanel/Plugins/AddPlugins","text":"\\define lingo-base() $:/language/ControlPanel/Plugins/\n\\whitespace trim\n\n<$button message=\"tm-modal\" param=\"$:/core/ui/ControlPanel/Modals/AddPlugins\" tooltip={{$:/language/ControlPanel/Plugins/Add/Hint}} class=\"tc-btn-big-green tc-primary-btn\">\n{{$:/core/images/download-button}}\n&#32;\n<<lingo Add/Caption>>\n</$button>\n"},"$:/core/ui/ControlPanel/Plugins/Installed/Languages":{"title":"$:/core/ui/ControlPanel/Plugins/Installed/Languages","tags":"$:/tags/ControlPanel/Plugins","caption":"{{$:/language/ControlPanel/Plugins/Languages/Caption}} (<$count filter=\"[!has[draft.of]plugin-type[language]]\"/>)","text":"<<plugin-table language>>\n"},"$:/core/ui/ControlPanel/Plugins/Installed/Plugins":{"title":"$:/core/ui/ControlPanel/Plugins/Installed/Plugins","tags":"$:/tags/ControlPanel/Plugins","caption":"{{$:/language/ControlPanel/Plugins/Plugins/Caption}} (<$count filter=\"[!has[draft.of]plugin-type[plugin]]\"/>)","text":"<<plugin-table plugin>>\n"},"$:/core/ui/ControlPanel/Plugins/Installed/Themes":{"title":"$:/core/ui/ControlPanel/Plugins/Installed/Themes","tags":"$:/tags/ControlPanel/Plugins","caption":"{{$:/language/ControlPanel/Plugins/Themes/Caption}} (<$count filter=\"[!has[draft.of]plugin-type[theme]]\"/>)","text":"<<plugin-table theme>>\n"},"$:/core/ui/ControlPanel/Plugins":{"title":"$:/core/ui/ControlPanel/Plugins","tags":"$:/tags/ControlPanel","caption":"{{$:/language/ControlPanel/Plugins/Caption}}","text":"\\define lingo-base() $:/language/ControlPanel/Plugins/\n\n\\define plugin-table(type)\n\\whitespace trim\n<$set name=\"plugin-type\" value=\"\"\"$type$\"\"\">\n<$set name=\"qualified-state\" value=<<qualify \"$:/state/plugin-info\">>>\n<$list filter=\"[!has[draft.of]plugin-type[$type$]sort[name]]\" emptyMessage=<<lingo \"Empty/Hint\">> template=\"$:/core/ui/Components/plugin-info\"/>\n</$set>\n</$set>\n\\end\n\n{{$:/core/ui/ControlPanel/Plugins/AddPlugins}}\n\n<<lingo Installed/Hint>>\n\n<$macrocall $name=\"tabs\" tabsList=\"[all[tiddlers+shadows]tag[$:/tags/ControlPanel/Plugins]!has[draft.of]]\" default=\"$:/core/ui/ControlPanel/Plugins/Installed/Plugins\" explicitState=\"$:/state/tab--86143343\"/>\n"},"$:/core/ui/ControlPanel/Saving/DownloadSaver":{"title":"$:/core/ui/ControlPanel/Saving/DownloadSaver","tags":"$:/tags/ControlPanel/Saving","caption":"{{$:/language/ControlPanel/Saving/DownloadSaver/Caption}}","text":"\\whitespace trim\n\\define lingo-base() $:/language/ControlPanel/Saving/DownloadSaver/\n\n<div class=\"tc-control-panel-saving\" data-setting-title=<<currentTab>>>\n\n<<lingo Hint>>\n\n!!.tc-control-panel-accent <$link to=\"$:/config/DownloadSaver/AutoSave\"><<lingo AutoSave/Hint>></$link>\n\n<$checkbox tiddler=\"$:/config/DownloadSaver/AutoSave\"\n\tfield=\"text\" checked=\"yes\" unchecked=\"no\" default=\"no\"\n\tclass=\"tc-control-panel-item\"\n>\n\t<span class=\"tc-tiny-gap-left\"><<lingo AutoSave/Description>></span>\n</$checkbox>\n</div>"},"$:/core/ui/ControlPanel/Saving/General":{"title":"$:/core/ui/ControlPanel/Saving/General","tags":"$:/tags/ControlPanel/Saving","caption":"{{$:/language/ControlPanel/Saving/General/Caption}}","list-before":"","text":"\\whitespace trim\n\\define lingo-base() $:/language/ControlPanel/Settings/\n\n<div class=\"tc-control-panel-saving\" data-setting-title=<<currentTab>>>\n\n{{$:/language/ControlPanel/Saving/General/Hint}}\n\n!!.tc-control-panel-accent <$link to=\"$:/config/AutoSave\"><<lingo AutoSave/Caption>></$link>\n\n<<lingo AutoSave/Hint>>\n\n<$radio tiddler=\"$:/config/AutoSave\" value=\"yes\">\n\t<span class=\"tc-tiny-gap-left\"><<lingo AutoSave/Enabled/Description>></span>\n</$radio>\n\n<$radio tiddler=\"$:/config/AutoSave\" value=\"no\">\n\t<span class=\"tc-tiny-gap-left\"><<lingo AutoSave/Disabled/Description>></span>\n</$radio>\n</div>"},"$:/core/ui/ControlPanel/Saving/GitHub":{"title":"$:/core/ui/ControlPanel/Saving/GitHub","tags":"$:/tags/ControlPanel/Saving","caption":"{{$:/language/ControlPanel/Saving/GitService/GitHub/Caption}}","text":"\\define lingo-base() $:/language/ControlPanel/Saving/GitService/\n\\define service-name() ~GitHub\n\n<<lingo Description>>\n\n|<<lingo UserName>> |<$edit-text tiddler=\"$:/GitHub/Username\" default=\"\" tag=\"input\"/> |\n|<<lingo GitHub/Password>> |<$password name=\"github\"/> |\n|<<lingo Repo>> |<$edit-text tiddler=\"$:/GitHub/Repo\" default=\"\" tag=\"input\"/> |\n|<<lingo Branch>> |<$edit-text tiddler=\"$:/GitHub/Branch\" default=\"main\" tag=\"input\"/> |\n|<<lingo Path>> |<$edit-text tiddler=\"$:/GitHub/Path\" default=\"\" tag=\"input\"/> |\n|<<lingo Filename>> |<$edit-text tiddler=\"$:/GitHub/Filename\" default=\"\" tag=\"input\"/> |\n|<<lingo ServerURL>> |<$edit-text tiddler=\"$:/GitHub/ServerURL\" default=\"https://api.github.com\" tag=\"input\" type=\"url\"/> |"},"$:/core/ui/ControlPanel/Saving/GitLab":{"title":"$:/core/ui/ControlPanel/Saving/GitLab","tags":"$:/tags/ControlPanel/Saving","caption":"{{$:/language/ControlPanel/Saving/GitService/GitLab/Caption}}","text":"\\define lingo-base() $:/language/ControlPanel/Saving/GitService/\n\\define service-name() ~GitLab\n\n<<lingo Description>>\n\n|<<lingo UserName>> |<$edit-text tiddler=\"$:/GitLab/Username\" default=\"\" tag=\"input\"/> |\n|<<lingo GitLab/Password>> |<$password name=\"gitlab\"/> |\n|<<lingo Repo>> |<$edit-text tiddler=\"$:/GitLab/Repo\" default=\"\" tag=\"input\"/> |\n|<<lingo Branch>> |<$edit-text tiddler=\"$:/GitLab/Branch\" default=\"master\" tag=\"input\"/> |\n|<<lingo Path>> |<$edit-text tiddler=\"$:/GitLab/Path\" default=\"\" tag=\"input\"/> |\n|<<lingo Filename>> |<$edit-text tiddler=\"$:/GitLab/Filename\" default=\"\" tag=\"input\"/> |\n|<<lingo ServerURL>> |<$edit-text tiddler=\"$:/GitLab/ServerURL\" default=\"https://gitlab.com/api/v4\" tag=\"input\" type=\"url\"/> |"},"$:/core/ui/ControlPanel/Saving/TiddlySpot":{"title":"$:/core/ui/ControlPanel/Saving/TiddlySpot","tags":"$:/tags/ControlPanel/Saving","caption":"{{$:/language/ControlPanel/Saving/TiddlySpot/Caption}}","text":"\\define lingo-base() $:/language/ControlPanel/Saving/TiddlySpot/\n\n\\define siteURL(path)\nhttp://$(userName)$.tiddlyspot.com/$path$/\n\\end\n\\define siteLink(path)\n\\whitespace trim\n<$reveal type=\"nomatch\" state=\"$:/UploadName\" text=\"\">\n<$set name=\"userName\" value={{$:/UploadName}}>\n<$reveal type=\"match\" state=\"$:/UploadURL\" text=\"\">\n<<siteURL $path$>>\n</$reveal>\n<$reveal type=\"nomatch\" state=\"$:/UploadURL\" text=\"\">\n<$macrocall $name=resolvePath source={{$:/UploadBackupDir}} root={{$:/UploadURL}}/>\n</$reveal>\n</$set>\n</$reveal>\n\\end\n\n<div class=\"tc-message-box\">\n\n<<lingo ReadOnly>>\n\n</div>\n\n<<lingo Description>>\n\n|<<lingo UserName>> |<$edit-text tiddler=\"$:/UploadName\" default=\"\" tag=\"input\"/> |\n|<<lingo Password>> |<$password name=\"upload\"/> |\n\n''<<lingo Advanced/Heading>>''\n\n|<<lingo ServerURL>>  |<$edit-text tiddler=\"$:/UploadURL\" default=\"\" tag=\"input\" type=\"url\"/> |\n|<<lingo Filename>> |<$edit-text tiddler=\"$:/UploadFilename\" default=\"index.html\" tag=\"input\"/> |\n|<<lingo UploadDir>> |<$edit-text tiddler=\"$:/UploadDir\" default=\".\" tag=\"input\"/> |\n|<<lingo BackupDir>> |<$edit-text tiddler=\"$:/UploadBackupDir\" default=\".\" tag=\"input\"/> |\n\n<<lingo TiddlySpot/Hint>>\n"},"$:/core/ui/ControlPanel/Saving/Gitea":{"title":"$:/core/ui/ControlPanel/Saving/Gitea","tags":"$:/tags/ControlPanel/Saving","caption":"{{$:/language/ControlPanel/Saving/GitService/Gitea/Caption}}","text":"\\define lingo-base() $:/language/ControlPanel/Saving/GitService/\n\\define service-name() ~Gitea\n\n<<lingo Description>>\n\n|<<lingo UserName>> |<$edit-text tiddler=\"$:/Gitea/Username\" default=\"\" tag=\"input\"/> |\n|<<lingo Gitea/Password>> |<$password name=\"Gitea\"/> |\n|<<lingo Repo>> |<$edit-text tiddler=\"$:/Gitea/Repo\" default=\"\" tag=\"input\"/> |\n|<<lingo Branch>> |<$edit-text tiddler=\"$:/Gitea/Branch\" default=\"master\" tag=\"input\"/> |\n|<<lingo Path>> |<$edit-text tiddler=\"$:/Gitea/Path\" default=\"\" tag=\"input\"/> |\n|<<lingo Filename>> |<$edit-text tiddler=\"$:/Gitea/Filename\" default=\"\" tag=\"input\"/> |\n|<<lingo ServerURL>> |<$edit-text tiddler=\"$:/Gitea/ServerURL\" default=\"https://gitea/api/v1\" tag=\"input\" type=\"url\"/> |\n"},"$:/core/ui/ControlPanel/Saving":{"title":"$:/core/ui/ControlPanel/Saving","tags":"$:/tags/ControlPanel","caption":"{{$:/language/ControlPanel/Saving/Caption}}","text":"\\whitespace trim\n{{$:/language/ControlPanel/Saving/Hint}}\n\n<div class=\"tc-control-panel\">\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Saving]!has[draft.of]]\" default=\"$:/core/ui/ControlPanel/Saving/General\" explicitState=\"$:/state/tab-2065006209\"/>\n</div>\n"},"$:/core/buttonstyles/Borderless":{"title":"$:/core/buttonstyles/Borderless","tags":"$:/tags/ToolbarButtonStyle","caption":"{{$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Borderless}}","text":"tc-btn-invisible"},"$:/core/buttonstyles/Boxed":{"title":"$:/core/buttonstyles/Boxed","tags":"$:/tags/ToolbarButtonStyle","caption":"{{$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Boxed}}","text":"tc-btn-boxed"},"$:/core/buttonstyles/Rounded":{"title":"$:/core/buttonstyles/Rounded","tags":"$:/tags/ToolbarButtonStyle","caption":"{{$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Rounded}}","text":"tc-btn-rounded"},"$:/core/ui/ControlPanel/Settings/CamelCase":{"title":"$:/core/ui/ControlPanel/Settings/CamelCase","tags":"$:/tags/ControlPanel/Settings","caption":"{{$:/language/ControlPanel/Settings/CamelCase/Caption}}","text":"\\whitespace trim\n\\define lingo-base() $:/language/ControlPanel/Settings/CamelCase/\n\n<<lingo Hint>>\n\n<$checkbox tiddler=\"$:/config/WikiParserRules/Inline/wikilink\"\n\tfield=\"text\" checked=\"enable\" unchecked=\"disable\" default=\"enable\"\n\tclass=\"tc-control-panel-item\"\n>\n\t<$link to=\"$:/config/WikiParserRules/Inline/wikilink\" class=\"tc-tiny-gap-left\">\n\t\t<<lingo Description>>\n\t</$link>\n</$checkbox>\n"},"$:/core/ui/ControlPanel/Settings/DefaultMoreSidebarTab":{"title":"$:/core/ui/ControlPanel/Settings/DefaultMoreSidebarTab","caption":"{{$:/language/ControlPanel/Settings/DefaultMoreSidebarTab/Caption}}","tags":"$:/tags/ControlPanel/Settings","text":"\\whitespace trim\n\\define lingo-base() $:/language/ControlPanel/Settings/DefaultMoreSidebarTab/\n\n<$link to=\"$:/config/DefaultMoreSidebarTab\" class=\"tc-control-panel-item\">\n\t<<lingo Hint>>\n</$link>\n\n<$select tiddler=\"$:/config/DefaultMoreSidebarTab\" class=\"tc-select\">\n\t<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/MoreSideBar]!has[draft.of]]\">\n\t\t<option value=<<currentTiddler>>><$transclude field=\"caption\">\n\t\t\t<$text text=<<currentTiddler>>/>\n\t\t\t</$transclude>\n\t\t</option>\n\t</$list>\n</$select>\n"},"$:/core/ui/ControlPanel/Settings/DefaultSidebarTab":{"title":"$:/core/ui/ControlPanel/Settings/DefaultSidebarTab","caption":"{{$:/language/ControlPanel/Settings/DefaultSidebarTab/Caption}}","tags":"$:/tags/ControlPanel/Settings","text":"\\define lingo-base() $:/language/ControlPanel/Settings/DefaultSidebarTab/\n\\whitespace trim\n\n<$link to=\"$:/config/DefaultSidebarTab\" class=\"tc-control-panel-item\">\n\t<<lingo Hint>>\n</$link>\n\n<$select tiddler=\"$:/config/DefaultSidebarTab\" class=\"tc-select\">\n\t<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/SideBar]!has[draft.of]]\">\n\t\t<option value=<<currentTiddler>>>\n\t\t\t<$transclude field=\"caption\">\n\t\t\t\t<$text text=<<currentTiddler>>/>\n\t\t\t</$transclude>\n\t\t</option>\n\t</$list>\n</$select>\n"},"$:/core/ui/ControlPanel/Settings/EditorToolbar":{"title":"$:/core/ui/ControlPanel/Settings/EditorToolbar","tags":"$:/tags/ControlPanel/Settings","caption":"{{$:/language/ControlPanel/Settings/EditorToolbar/Caption}}","text":"\\whitespace trim\n\\define lingo-base() $:/language/ControlPanel/Settings/EditorToolbar/\n<<lingo Hint>>\n\n<$checkbox tiddler=\"$:/config/TextEditor/EnableToolbar\"\n\tfield=\"text\" checked=\"yes\" unchecked=\"no\" default=\"yes\"\n\tclass=\"tc-control-panel-item\"\n>\n\t<$link to=\"$:/config/TextEditor/EnableToolbar\" class=\"tc-tiny-gap-left\">\n\t\t<<lingo Description>>\n\t</$link>\n</$checkbox>\n"},"$:/core/ui/ControlPanel/Settings/InfoPanelMode":{"title":"$:/core/ui/ControlPanel/Settings/InfoPanelMode","tags":"$:/tags/ControlPanel/Settings","caption":"{{$:/language/ControlPanel/Settings/InfoPanelMode/Caption}}","text":"\\whitespace trim\n\\define lingo-base() $:/language/ControlPanel/Settings/InfoPanelMode/\n\n<$link to=\"$:/config/TiddlerInfo/Mode\" class=\"tc-control-panel-item\">\n\t<<lingo Hint>>\n</$link>\n\n<$radio tiddler=\"$:/config/TiddlerInfo/Mode\" value=\"popup\">\n\t<span class=\"tc-tiny-gap-left\"><<lingo Popup/Description>></span>\n</$radio>\n\n<$radio tiddler=\"$:/config/TiddlerInfo/Mode\" value=\"sticky\">\n\t<span class=\"tc-tiny-gap-left\"><<lingo Sticky/Description>></span>\n</$radio>\n"},"$:/core/ui/ControlPanel/Settings/LinkToBehaviour":{"title":"$:/core/ui/ControlPanel/Settings/LinkToBehaviour","tags":"$:/tags/ControlPanel/Settings","caption":"{{$:/language/ControlPanel/Settings/LinkToBehaviour/Caption}}","text":"\\whitespace trim\n\\define lingo-base() $:/language/ControlPanel/Settings/LinkToBehaviour/\n\n<$link to=\"$:/config/Navigation/openLinkFromInsideRiver\" class=\"tc-control-panel-item\">\n\t<<lingo \"InsideRiver/Hint\">>\n</$link>\n\n<$select tiddler=\"$:/config/Navigation/openLinkFromInsideRiver\" class=\"tc-select\">\n\t<option value=\"above\"><<lingo \"OpenAbove\">></option>\n\t<option value=\"below\"><<lingo \"OpenBelow\">></option>\n\t<option value=\"top\"><<lingo \"OpenAtTop\">></option>\n\t<option value=\"bottom\"><<lingo \"OpenAtBottom\">></option>\n</$select>\n\n<$link to=\"$:/config/Navigation/openLinkFromOutsideRiver\" class=\"tc-control-panel-item\">\n\t<<lingo \"OutsideRiver/Hint\">>\n</$link>\n\n<$select tiddler=\"$:/config/Navigation/openLinkFromOutsideRiver\" class=\"tc-select\">\n\t<option value=\"top\"><<lingo \"OpenAtTop\">></option>\n\t<option value=\"bottom\"><<lingo \"OpenAtBottom\">></option>\n</$select>\n"},"$:/core/ui/ControlPanel/Settings/MissingLinks":{"title":"$:/core/ui/ControlPanel/Settings/MissingLinks","tags":"$:/tags/ControlPanel/Settings","caption":"{{$:/language/ControlPanel/Settings/MissingLinks/Caption}}","text":"\\whitespace trim\n\\define lingo-base() $:/language/ControlPanel/Settings/MissingLinks/\n<<lingo Hint>>\n\n<$checkbox tiddler=\"$:/config/MissingLinks\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"yes\">\n\t<$link to=\"$:/config/MissingLinks\" class=\"tc-control-panel-item\">\n\t\t<span class=\"tc-tiny-gap-left\"><<lingo Description>></span>\n\t</$link>\n</$checkbox>\n"},"$:/core/ui/ControlPanel/Settings/NavigationAddressBar":{"title":"$:/core/ui/ControlPanel/Settings/NavigationAddressBar","tags":"$:/tags/ControlPanel/Settings","caption":"{{$:/language/ControlPanel/Settings/NavigationAddressBar/Caption}}","text":"\\whitespace trim\n\\define lingo-base() $:/language/ControlPanel/Settings/NavigationAddressBar/\n\n<$link to=\"$:/config/Navigation/UpdateAddressBar\" class=\"tc-control-panel-item\">\n\t<<lingo Hint>>\n</$link>\n\n<$radio tiddler=\"$:/config/Navigation/UpdateAddressBar\" value=\"permaview\">\n\t<span class=\"tc-tiny-gap-left\"><<lingo Permaview/Description>></span>\n</$radio>\n\n<$radio tiddler=\"$:/config/Navigation/UpdateAddressBar\" value=\"permalink\">\n\t<span class=\"tc-tiny-gap-left\"><<lingo Permalink/Description>></span>\n</$radio>\n\n<$radio tiddler=\"$:/config/Navigation/UpdateAddressBar\" value=\"no\">\n\t<span class=\"tc-tiny-gap-left\"><<lingo No/Description>></span>\n</$radio>\n"},"$:/core/ui/ControlPanel/Settings/NavigationHistory":{"title":"$:/core/ui/ControlPanel/Settings/NavigationHistory","tags":"$:/tags/ControlPanel/Settings","caption":"{{$:/language/ControlPanel/Settings/NavigationHistory/Caption}}","text":"\\whitespace trim\n\\define lingo-base() $:/language/ControlPanel/Settings/NavigationHistory/\n\n<$link to=\"$:/config/Navigation/UpdateHistory\" class=\"tc-control-panel-item\">\n\t<<lingo Hint>>\n</$link>\n\n<$radio tiddler=\"$:/config/Navigation/UpdateHistory\" value=\"yes\">\n\t<span class=\"tc-tiny-gap-left\"><<lingo Yes/Description>></span>\n</$radio>\n\n<$radio tiddler=\"$:/config/Navigation/UpdateHistory\" value=\"no\">\n\t<span class=\"tc-tiny-gap-left\"><<lingo No/Description>></span>\n</$radio>\n"},"$:/core/ui/ControlPanel/Settings/NavigationPermalinkviewMode":{"title":"$:/core/ui/ControlPanel/Settings/NavigationPermalinkviewMode","tags":"$:/tags/ControlPanel/Settings","caption":"{{$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/Caption}}","text":"\\whitespace trim\n\\define lingo-base() $:/language/ControlPanel/Settings/NavigationPermalinkviewMode/\n<<lingo Hint>>\n\n<$checkbox tiddler=\"$:/config/Navigation/Permalinkview/CopyToClipboard\"\n\tfield=\"text\" checked=\"yes\" unchecked=\"no\" default=\"yes\"\n\tclass=\"tc-control-panel-item\"\n>\n\t<$link to=\"$:/config/Navigation/Permalinkview/CopyToClipboard\" class=\"tc-tiny-gap-left\">\n\t\t<<lingo CopyToClipboard/Description>>\n\t</$link>\n</$checkbox>\n\n<$checkbox tiddler=\"$:/config/Navigation/Permalinkview/UpdateAddressBar\"\n\tfield=\"text\" checked=\"yes\" unchecked=\"no\" default=\"yes\"\n\tclass=\"tc-control-panel-item\"\n>\n\t<$link to=\"$:/config/Navigation/Permalinkview/UpdateAddressBar\" class=\"tc-tiny-gap-left\">\n\t\t<<lingo UpdateAddressBar/Description>>\n\t</$link>\n</$checkbox>\n"},"$:/core/ui/ControlPanel/Settings/PerformanceInstrumentation":{"title":"$:/core/ui/ControlPanel/Settings/PerformanceInstrumentation","tags":"$:/tags/ControlPanel/Settings","caption":"{{$:/language/ControlPanel/Settings/PerformanceInstrumentation/Caption}}","text":"\\whitespace trim\n\\define lingo-base() $:/language/ControlPanel/Settings/PerformanceInstrumentation/\n<<lingo Hint>>\n\n<$checkbox tiddler=\"$:/config/Performance/Instrumentation\"\n\tfield=\"text\" checked=\"yes\" unchecked=\"no\" default=\"no\"\n\tclass=\"tc-control-panel-item\"\n>\n\t<$link to=\"$:/config/Performance/Instrumentation\" class=\"tc-tiny-gap-left\">\n\t\t<<lingo Description>>\n\t</$link>\n</$checkbox>\n"},"$:/core/ui/ControlPanel/Settings/RecentLimit":{"title":"$:/core/ui/ControlPanel/Settings/RecentLimit","tags":"$:/tags/ControlPanel/Settings","caption":"{{$:/language/ControlPanel/Settings/RecentLimit/Caption}}","text":"\\whitespace trim\n\\procedure lingo-base() $:/language/ControlPanel/Settings/RecentLimit/\n<<lingo Hint>>\n\n|tc-table-no-border|k\n|<$link to=\"$:/config/RecentLimit\"><<lingo Caption>></$link> |<$edit-text tiddler=\"$:/config/RecentLimit\" tag=\"input\" type=\"number\"/> |\n"},"$:/core/ui/ControlPanel/Settings/TitleLinks":{"title":"$:/core/ui/ControlPanel/Settings/TitleLinks","tags":"$:/tags/ControlPanel/Settings","caption":"{{$:/language/ControlPanel/Settings/TitleLinks/Caption}}","text":"\\whitespace trim\n\\define lingo-base() $:/language/ControlPanel/Settings/TitleLinks/\n\n<$link to=\"$:/config/Tiddlers/TitleLinks\" class=\"tc-control-panel-item\">\n\t<<lingo Hint>>\n</$link>\n\n<$radio tiddler=\"$:/config/Tiddlers/TitleLinks\" value=\"yes\">\n\t<span class=\"tc-tiny-gap-left\"><<lingo Yes/Description>></span>\n</$radio>\n\n<$radio tiddler=\"$:/config/Tiddlers/TitleLinks\" value=\"no\">\n\t<span class=\"tc-tiny-gap-left\"><<lingo No/Description>></span>\n</$radio>\n"},"$:/core/ui/ControlPanel/Settings/ToolbarButtonStyle":{"title":"$:/core/ui/ControlPanel/Settings/ToolbarButtonStyle","tags":"$:/tags/ControlPanel/Settings","caption":"{{$:/language/ControlPanel/Settings/ToolbarButtonStyle/Caption}}","text":"\\whitespace trim\n\\define lingo-base() $:/language/ControlPanel/Settings/ToolbarButtonStyle/\n\n<$link to=\"$:/config/Toolbar/ButtonClass\" class=\"tc-control-panel-item\">\n\t<<lingo \"Hint\">>\n</$link>\n\n<$select tiddler=\"$:/config/Toolbar/ButtonClass\" class=\"tc-select\">\n\t<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/ToolbarButtonStyle]]\">\n\t\t<option value={{!!text}}>{{!!caption}}</option>\n\t</$list>\n</$select>\n"},"$:/core/ui/ControlPanel/Settings/ToolbarButtons":{"title":"$:/core/ui/ControlPanel/Settings/ToolbarButtons","tags":"$:/tags/ControlPanel/Settings","caption":"{{$:/language/ControlPanel/Settings/ToolbarButtons/Caption}}","text":"\\whitespace trim\n\\define lingo-base() $:/language/ControlPanel/Settings/ToolbarButtons/\n<<lingo Hint>>\n\n<$checkbox tiddler=\"$:/config/Toolbar/Icons\"\n\tfield=\"text\" checked=\"yes\" unchecked=\"no\" default=\"yes\"\n\tclass=\"tc-control-panel-item\"\n>\n\t<$link to=\"$:/config/Toolbar/Icons\" class=\"tc-tiny-gap-left\">\n\t\t<<lingo Icons/Description>>\n\t</$link>\n</$checkbox>\n\n<$checkbox tiddler=\"$:/config/Toolbar/Text\"\n\tfield=\"text\" checked=\"yes\" unchecked=\"no\" default=\"no\"\n\tclass=\"tc-control-panel-item\"\n>\n\t<$link to=\"$:/config/Toolbar/Text\" class=\"tc-tiny-gap-left\">\n\t\t<<lingo Text/Description>>\n\t</$link>\n</$checkbox>\n"},"$:/core/ui/ControlPanel/Settings":{"title":"$:/core/ui/ControlPanel/Settings","tags":"$:/tags/ControlPanel","caption":"{{$:/language/ControlPanel/Settings/Caption}}","text":"<div class=\"tc-control-panel\">\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/ControlPanel/SettingsTab]!has[draft.of]]\" default=\"$:/core/ui/ControlPanel/Settings/TiddlyWiki\" explicitState=\"$:/state/tab--697582678\"/>\n</div>"},"$:/core/ui/ControlPanel/SocialCard":{"title":"$:/core/ui/ControlPanel/SocialCard","tags":"$:/tags/ControlPanel/Advanced","caption":"{{$:/language/ControlPanel/SocialCard/Caption}}","text":"\\define lingo-base() $:/language/ControlPanel/\n\n<<lingo SocialCard/Hint>>\n\n|<$link to=\"$:/SiteTitle\"><<lingo Basics/Title/Prompt>></$link> |<$edit-text tiddler=\"$:/SiteTitle\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/SiteSubtitle\"><<lingo Basics/Subtitle/Prompt>></$link> |<$edit-text tiddler=\"$:/SiteSubtitle\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/SiteDomain\"><<lingo SocialCard/Domain/Prompt>></$link> |<$edit-text tiddler=\"$:/SiteDomain\" default=\"\" tag=\"input\" type=\"url\"/> |\n|<$link to=\"$:/SiteUrl\"><<lingo SocialCard/Url/Prompt>></$link> |<$edit-text tiddler=\"$:/SiteUrl\" default=\"\" tag=\"input\" type=\"url\"/> |\n|<$link to=\"$:/SitePreviewUrl\"><<lingo SocialCard/PreviewUrl/Prompt>></$link> |<$edit-text tiddler=\"$:/SitePreviewUrl\" default=\"\" tag=\"input\" type=\"url\"/> |\n\n<%if [[$:/SitePreviewUrl]get[text]else[]!is[blank]] %>\n<div>\n<div>\n<<lingo SocialCard/PreviewUrl/Preview>>\n</div>\n<img src={{$:/SitePreviewUrl}}/>\n</div>\n<%endif%>"},"$:/core/ui/ControlPanel/StoryView":{"title":"$:/core/ui/ControlPanel/StoryView","tags":"$:/tags/ControlPanel/Appearance","caption":"{{$:/language/ControlPanel/StoryView/Caption}}","text":"{{$:/snippets/viewswitcher}}\n"},"$:/core/ui/ControlPanel/Stylesheets":{"title":"$:/core/ui/ControlPanel/Stylesheets","tags":"$:/tags/ControlPanel/Advanced","caption":"{{$:/language/ControlPanel/Stylesheets/Caption}}","text":"\\define lingo-base() $:/language/ControlPanel/\n\n<<lingo Stylesheets/Hint>>\n\n{{$:/snippets/peek-stylesheets}}\n"},"$:/core/ui/ControlPanel/TestCases":{"title":"$:/core/ui/ControlPanel/TestCases","tags":"$:/tags/ControlPanel/Advanced","caption":"{{$:/language/ControlPanel/TestCases/Caption}}","text":"\\whitespace trim\n{{$:/language/ControlPanel/TestCases/Hint}}\n\n<div class=\"tc-control-panel\">\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/ControlPanel/TestCases]!has[draft.of]]\" default=\"$:/core/ui/ControlPanel/TestCases/All\"/>\n</div>\n"},"$:/core/ui/ControlPanel/TestCases/All":{"title":"$:/core/ui/ControlPanel/TestCases/All","tags":"$:/tags/ControlPanel/TestCases","caption":"{{$:/language/ControlPanel/TestCases/All/Caption}}","text":"\\define lingo-base() $:/language/ControlPanel/\n<<lingo TestCases/All/Hint>>\n\n<$list filter=\"[all[tiddlers+shadows]tag[$:/tags/wiki-test-spec]type[text/vnd.tiddlywiki-multiple]] [all[tiddlers+shadows]tag[$:/tags/wiki-test-spec-failing]type[text/vnd.tiddlywiki-multiple]]\">\n\n<h2>\n\n<$link>\n\n<$text text=<<currentTiddler>>/>\n\n</$link>\n\n</h2>\n\n<$transclude\n\t$tiddler=\"$:/core/ui/TestCaseTemplate\"\n/>\n\n</$list>\n"},"$:/core/ui/ControlPanel/TestCases/Failed":{"title":"$:/core/ui/ControlPanel/TestCases/Failed","tags":"$:/tags/ControlPanel/TestCases","caption":"{{$:/language/ControlPanel/TestCases/Failed/Caption}}","text":"\\define lingo-base() $:/language/ControlPanel/\n<<lingo TestCases/Failed/Hint>>\n\n<$list filter=\"[all[tiddlers+shadows]tag[$:/tags/wiki-test-spec]type[text/vnd.tiddlywiki-multiple]] [all[tiddlers+shadows]tag[$:/tags/wiki-test-spec-failing]type[text/vnd.tiddlywiki-multiple]]\">\n\n<$transclude\n\t$tiddler=\"$:/core/ui/TestCaseTemplate\"\n\thideIfPass=\"yes\"\n/>\n\n</$list>\n"},"$:/core/ui/ControlPanel/Theme":{"title":"$:/core/ui/ControlPanel/Theme","tags":"$:/tags/ControlPanel/Appearance","caption":"{{$:/language/ControlPanel/Theme/Caption}}","text":"{{$:/snippets/themeswitcher}}\n"},"$:/core/ui/ControlPanel/TiddlerFields":{"title":"$:/core/ui/ControlPanel/TiddlerFields","tags":"$:/tags/ControlPanel/Advanced","caption":"{{$:/language/ControlPanel/TiddlerFields/Caption}}","text":"\\define lingo-base() $:/language/ControlPanel/\n\n<<lingo TiddlerFields/Hint>>\n\n{{$:/snippets/allfields}}"},"$:/core/ui/ControlPanel/Settings/TiddlyWiki":{"title":"$:/core/ui/ControlPanel/Settings/TiddlyWiki","tags":"$:/tags/ControlPanel/SettingsTab","caption":"TiddlyWiki","list-before":"","text":"\\define lingo-base() $:/language/ControlPanel/Settings/\n\n<<lingo Hint>>\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Settings]]\">\n\n<div class=\"tc-control-panel-setting\" data-setting-title=<<currentTiddler>> >\n\n!!.tc-control-panel-accent <$link><$transclude field=\"caption\"/></$link>\n\n<$transclude/>\n\n</div>\n\n</$list>\n"},"$:/core/ui/ControlPanel/Toolbars/EditToolbar":{"title":"$:/core/ui/ControlPanel/Toolbars/EditToolbar","tags":"$:/tags/ControlPanel/Toolbars","caption":"{{$:/language/ControlPanel/Toolbars/EditToolbar/Caption}}","text":"\\define lingo-base() $:/language/TiddlerInfo/\n\n\\define config-base() $:/config/EditToolbarButtons/Visibility/\n\n{{$:/language/ControlPanel/Toolbars/EditToolbar/Hint}}\n\n<$set name=\"tv-config-toolbar-icons\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-text\" value=\"yes\">\n\n<$macrocall $name=\"list-tagged-draggable\" tag=\"$:/tags/EditToolbar\" itemTemplate=\"$:/core/ui/ControlPanel/Toolbars/ItemTemplate\"/>\n\n</$set>\n\n</$set>"},"$:/core/ui/ControlPanel/Toolbars/EditorItemTemplate":{"title":"$:/core/ui/ControlPanel/Toolbars/EditorItemTemplate","text":"\\define config-title()\n$(config-base)$$(currentTiddler)$\n\\end\n\\whitespace trim\n\n<$draggable tiddler=<<currentTiddler>>>\n<$checkbox tiddler=<<config-title>> field=\"text\" checked=\"show\" unchecked=\"hide\" default=\"show\"/>\n&#32;\n<span class=\"tc-icon-wrapper\"><$transclude tiddler={{!!icon}}/></span>\n&#32;\n<$transclude field=\"caption\"/>\n&#32;--&#32;\n<i class=\"tc-muted\"><$transclude field=\"description\"/></i>\n</$draggable>\n"},"$:/core/ui/ControlPanel/Toolbars/EditorToolbar":{"title":"$:/core/ui/ControlPanel/Toolbars/EditorToolbar","tags":"$:/tags/ControlPanel/Toolbars","caption":"{{$:/language/ControlPanel/Toolbars/EditorToolbar/Caption}}","text":"\\define lingo-base() $:/language/TiddlerInfo/\n\n\\define config-base() $:/config/EditorToolbarButtons/Visibility/\n\n{{$:/language/ControlPanel/Toolbars/EditorToolbar/Hint}}\n\n<$macrocall $name=\"list-tagged-draggable\" tag=\"$:/tags/EditorToolbar\" itemTemplate=\"$:/core/ui/ControlPanel/Toolbars/EditorItemTemplate\"/>\n"},"$:/core/ui/ControlPanel/Toolbars/ItemTemplate":{"title":"$:/core/ui/ControlPanel/Toolbars/ItemTemplate","text":"\\define config-title()\n$(config-base)$$(currentTiddler)$\n\\end\n\\whitespace trim\n\n<$draggable tiddler=<<currentTiddler>>>\n<$checkbox tiddler=<<config-title>> field=\"text\" checked=\"show\" unchecked=\"hide\" default=\"show\"/>\n&#32;\n<span class=\"tc-icon-wrapper\">\n&#32;\n<$transclude field=\"caption\"/>\n&#32;\n<i class=\"tc-muted\">\n--&#32;\n<$transclude field=\"description\"/>\n</i></span>\n</$draggable>\n"},"$:/core/ui/ControlPanel/Toolbars/PageControls":{"title":"$:/core/ui/ControlPanel/Toolbars/PageControls","tags":"$:/tags/ControlPanel/Toolbars","caption":"{{$:/language/ControlPanel/Toolbars/PageControls/Caption}}","text":"\\define lingo-base() $:/language/TiddlerInfo/\n\n\\define config-base() $:/config/PageControlButtons/Visibility/\n\n{{$:/language/ControlPanel/Toolbars/PageControls/Hint}}\n\n<$set name=\"tv-config-toolbar-icons\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-text\" value=\"yes\">\n\n<$macrocall $name=\"list-tagged-draggable\" tag=\"$:/tags/PageControls\" itemTemplate=\"$:/core/ui/ControlPanel/Toolbars/ItemTemplate\"/>\n\n</$set>\n\n</$set>\n"},"$:/core/ui/ControlPanel/Toolbars/ViewToolbar":{"title":"$:/core/ui/ControlPanel/Toolbars/ViewToolbar","tags":"$:/tags/ControlPanel/Toolbars","caption":"{{$:/language/ControlPanel/Toolbars/ViewToolbar/Caption}}","text":"\\define lingo-base() $:/language/TiddlerInfo/\n\n\\define config-base() $:/config/ViewToolbarButtons/Visibility/\n\n{{$:/language/ControlPanel/Toolbars/ViewToolbar/Hint}}\n\n<$set name=\"tv-config-toolbar-icons\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-text\" value=\"yes\">\n\n<$macrocall $name=\"list-tagged-draggable\" tag=\"$:/tags/ViewToolbar\" itemTemplate=\"$:/core/ui/ControlPanel/Toolbars/ItemTemplate\"/>\n\n</$set>\n\n</$set>\n"},"$:/core/ui/ControlPanel/Toolbars":{"title":"$:/core/ui/ControlPanel/Toolbars","tags":"$:/tags/ControlPanel/Appearance","caption":"{{$:/language/ControlPanel/Toolbars/Caption}}","text":"\\whitespace trim\n{{$:/language/ControlPanel/Toolbars/Hint}}\n\n<div class=\"tc-control-panel\">\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Toolbars]!has[draft.of]]\" default=\"$:/core/ui/ControlPanel/Toolbars/ViewToolbar\" class=\"tc-vertical\" explicitState=\"$:/state/tabs/controlpanel/toolbars-1345989671\"/>\n</div>\n"},"$:/ControlPanel":{"title":"$:/ControlPanel","icon":"$:/core/images/options-button","color":"#bbb","text":"\\whitespace trim\n<div class=\"tc-control-panel\">\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/ControlPanel]!has[draft.of]]\" default=\"$:/core/ui/ControlPanel/Info\" explicitState=\"$:/state/tab-1749438307\"/>\n</div>\n"},"$:/core/ui/DefaultSearchResultList":{"title":"$:/core/ui/DefaultSearchResultList","tags":"$:/tags/SearchResults","caption":"{{$:/language/Search/DefaultResults/Caption}}","first-search-filter":"[!is[system]search:title<userInput>sort[title]limit[250]]","second-search-filter":"[!is[system]search<userInput>sort[title]limit[250]]","text":"\\define searchResultList()\n\\whitespace trim\n//<small>{{$:/language/Search/Matches/Title}}</small>//\n\n<$list filter=\"[<userInput>minlength[1]]\" variable=\"ignore\">\n<$list filter={{{ [<configTiddler>get[first-search-filter]] }}} emptyMessage={{$:/language/Search/Matches/NoResult}}>\n<span class={{{[<currentTiddler>addsuffix[-primaryList]] -[<searchListState>get[text]] +[then[]else[tc-list-item-selected]] }}}>\n<$transclude tiddler=\"$:/core/ui/ListItemTemplate\"/>\n</span>\n</$list>\n</$list>\n\n//<small>{{$:/language/Search/Matches/All}}</small>//\n\n<$list filter=\"[<userInput>minlength[1]]\" variable=\"ignore\">\n<$list filter={{{ [<configTiddler>get[second-search-filter]] }}} emptyMessage={{$:/language/Search/Matches/NoResult}}>\n<span class={{{[<currentTiddler>addsuffix[-secondaryList]] -[<searchListState>get[text]] +[then[]else[tc-list-item-selected]] }}}>\n<$transclude tiddler=\"$:/core/ui/ListItemTemplate\"/>\n</span>\n</$list>\n</$list>\n\n\\end\n<<searchResultList>>\n"},"$:/core/ui/DownloadFullWiki":{"title":"$:/core/ui/DownloadFullWiki","text":"\\whitespace trim\n\\rules except wikilink\n\nTo download the standard single-file version of your wiki:\n\n<$wikify name=\"site-title\" text={{$:/config/SaveWikiButton/Filename}}>\n<$let publishFilter=\"\"\"-[[$:/config/SaveWikiButton/Template]] -[[$:/plugins/tiddlywiki/filesystem]] -[[$:/plugins/tiddlywiki/tiddlyweb]]\"\"\">\n<$button tooltip=\"Download fully standalone wiki\" aria-label=\"download full wiki\" class=\"tc-btn-big-green\">\n<$action-sendmessage $message=\"tm-download-file\" $param=\"$:/core/save/all\" publishFilter=<<publishFilter>> filename=<<site-title>>/>\n{{$:/core/images/download-button}}\n<span class=\"tc-tiny-gap-left\">\nDownload full wiki\n</span>\n</$button>\n</$let>\n</$wikify>"},"$:/core/ui/EditTemplate/body/preview/diffs-current":{"title":"$:/core/ui/EditTemplate/body/preview/diffs-current","tags":"$:/tags/EditPreview","caption":"{{$:/language/EditTemplate/Body/Preview/Type/DiffCurrent}}","list-after":"$:/core/ui/EditTemplate/body/preview/output","text":"<$list filter=\"[<currentTiddler>!is[image]]\" emptyMessage={{$:/core/ui/EditTemplate/body/preview/output}}>\n\n<$macrocall $name=\"compareTiddlerText\" sourceTiddlerTitle={{!!draft.of}} destTiddlerTitle=<<currentTiddler>>/>\n\n</$list>\n\n"},"$:/core/ui/EditTemplate/body/preview/diffs-shadow":{"title":"$:/core/ui/EditTemplate/body/preview/diffs-shadow","tags":"$:/tags/EditPreview","caption":"{{$:/language/EditTemplate/Body/Preview/Type/DiffShadow}}","list-after":"$:/core/ui/EditTemplate/body/preview/output","text":"<$list filter=\"[<currentTiddler>!is[image]]\" emptyMessage={{$:/core/ui/EditTemplate/body/preview/output}}>\n\n<$macrocall $name=\"compareTiddlerText\" sourceTiddlerTitle={{{ [{!!draft.of}shadowsource[]] }}} sourceSubTiddlerTitle={{!!draft.of}} destTiddlerTitle=<<currentTiddler>>/>\n\n</$list>\n\n"},"$:/core/ui/EditTemplate/body/preview/output":{"title":"$:/core/ui/EditTemplate/body/preview/output","tags":"$:/tags/EditPreview","caption":"{{$:/language/EditTemplate/Body/Preview/Type/Output}}","text":"\\import [all[shadows+tiddlers]tag[$:/tags/Macro/View]!is[draft]] [all[shadows+tiddlers]tag[$:/tags/Macro/View/Body]!is[draft]] [all[shadows+tiddlers]tag[$:/tags/Global/View]!is[draft]] [all[shadows+tiddlers]tag[$:/tags/Global/View/Body]!is[draft]]\n<$set name=\"tv-tiddler-preview\" value=\"yes\">\n\n<$transclude tiddler={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/ViewTemplateBodyFilter]!is[draft]get[text]] :and[!is[blank]else[$:/core/ui/ViewTemplate/body/default]] }}} />\n\n</$set>\n"},"$:/state/showeditpreview":{"title":"$:/state/showeditpreview","text":"no"},"$:/core/ui/EditTemplate/body/canonical-uri":{"title":"$:/core/ui/EditTemplate/body/canonical-uri","text":"\\define lingo-base() $:/language/EditTemplate/Body/\n\n<div class=\"tc-message-box\">\n\n<<lingo External/Hint>>\n\n<a href={{!!_canonical_uri}}><$text text={{!!_canonical_uri}}/></a>\n\n<$edit-text field=\"_canonical_uri\" class=\"tc-edit-fields\" tabindex={{$:/config/EditTabIndex}} cancelPopups=\"yes\"></$edit-text>\n\n</div>\n"},"$:/core/ui/EditTemplate/body/default":{"title":"$:/core/ui/EditTemplate/body/default","text":"\\function edit-preview-state()\n[{$:/config/ShowEditPreview/PerTiddler}!match[yes]then[$:/state/showeditpreview]] :else[<qualified-preview-state>] +[get[text]] :else[[no]]\n\\end\n\n\\define config-visibility-title()\n$:/config/EditorToolbarButtons/Visibility/$(currentTiddler)$\n\\end\n\n\\define importFileActions()\n<$action-popup $state=<<importState>> $coords=\"(0,0,0,0)\" $floating=\"yes\"/>\n\\end\n\n\\whitespace trim\n<$let\n\tqualified-preview-state=<<qualify \"$:/state/showeditpreview\">>\n\teditPreviewStateTiddler={{{ [{$:/config/ShowEditPreview/PerTiddler}!match[yes]then[$:/state/showeditpreview]] :else[<qualified-preview-state>] }}}\n\timportTitle=<<qualify $:/ImportImage>>\n\timportState=<<qualify $:/state/ImportImage>> >\n<$dropzone importTitle=<<importTitle>> autoOpenOnImport=\"no\" contentTypesFilter={{$:/config/Editor/ImportContentTypesFilter}} class=\"tc-dropzone-editor\" enable={{{ [{$:/config/DragAndDrop/Enable}match[no]] :else[subfilter{$:/config/Editor/EnableImportFilter}then[yes]else[no]] }}} filesOnly=\"yes\" actions=<<importFileActions>> >\n<div>\n<div class={{{ [<edit-preview-state>match[yes]then[tc-tiddler-preview]else[tc-tiddler-preview-hidden]] [[tc-tiddler-editor]] +[join[ ]] }}}>\n\n<$transclude tiddler=\"$:/core/ui/EditTemplate/body/editor\" mode=\"inline\"/>\n\n<$list filter=\"[<editPreviewStateTiddler>get[text]match[yes]]\" variable=\"ignore\">\n\n<div class=\"tc-tiddler-preview-preview\" data-tiddler-title={{!!draft.title}} data-tags={{!!tags}}>\n\n<$transclude tiddler={{$:/state/editpreviewtype}} mode=\"inline\">\n\n<$transclude tiddler=\"$:/core/ui/EditTemplate/body/preview/output\" mode=\"inline\"/>\n\n</$transclude>\n\n</div>\n\n</$list>\n\n</div>\n\n</div>\n\n</$dropzone>\n\n</$let>\n"},"$:/core/ui/EditTemplate/body/editor":{"title":"$:/core/ui/EditTemplate/body/editor","text":"\\whitespace trim\n\n<$edit\n\n  field=\"text\"\n  class=\"tc-edit-texteditor tc-edit-texteditor-body\"\n  placeholder={{$:/language/EditTemplate/Body/Placeholder}}\n  tabindex={{$:/config/EditTabIndex}}\n  focus={{{ [{$:/config/AutoFocus}match[text]then[true]] ~[[false]] }}}\n  cancelPopups=\"yes\"\n  fileDrop={{{ [{$:/config/DragAndDrop/Enable}match[no]] :else[subfilter{$:/config/Editor/EnableImportFilter}then[yes]else[no]] }}}\n\n><$set\n\n  name=\"targetTiddler\"\n  value=<<currentTiddler>>\n\n><$list\n\n  filter=\"[all[shadows+tiddlers]tag[$:/tags/EditorToolbar]!has[draft.of]]\"\n\n><$reveal\n\n  type=\"nomatch\"\n  state=<<config-visibility-title>>\n  text=\"hide\"\n  class=\"tc-text-editor-toolbar-item-wrapper\"\n\n><$transclude\n\n  tiddler=\"$:/core/ui/EditTemplate/body/toolbar/button\"\n  mode=\"inline\"\n\n/></$reveal></$list><$list\n\n  filter=\"[all[shadows+tiddlers]tag[$:/tags/EditorTools]!has[draft.of]]\"\n\n><$list\n\tfilter={{!!condition}}\n\tvariable=\"list-condition\"\n><$transclude/>\n</$list></$list></$set></$edit>\n"},"$:/core/ui/EditTemplate/body/toolbar/button":{"title":"$:/core/ui/EditTemplate/body/toolbar/button","text":"\\define toolbar-button-icon()\n<$list\n\n  filter=\"[all[current]!has[custom-icon]]\"\n  variable=\"no-custom-icon\"\n\n><$transclude\n\n  tiddler={{!!icon}}\n\n/></$list>\n\\end\n\n\\define toolbar-button-tooltip()\n{{!!description}}<$macrocall $name=\"displayshortcuts\" $output=\"text/plain\" shortcuts={{!!shortcuts}} prefix=\"` - [\" separator=\"] [\" suffix=\"]`\"/>\n\\end\n\n\\define toolbar-button()\n<$list\n\n  filter={{!!condition}}\n  variable=\"list-condition\"\n\n><$wikify\n\n  name=\"tooltip-text\"\n  text=<<toolbar-button-tooltip>>\n  mode=\"inline\"\n  output=\"text\"\n\n><$list\n\n  filter=\"[all[current]!has[dropdown]]\"\n  variable=\"no-dropdown\"\n\n><$set name=disabled filter={{!!condition-disabled}}><$button\n\n  class=\"tc-btn-invisible $(buttonClasses)$\"\n  tooltip=<<tooltip-text>>\n  actions={{!!actions}}\n  disabled=<<disabled>>\n\n><span\n\n  data-tw-keyboard-shortcut={{{ [<disabled>match[yes]then[]else{!!shortcuts}] }}}\n\n/><<toolbar-button-icon>><$transclude\n\n  tiddler=<<currentTiddler>>\n  field=\"text\"\n\n/></$button></$set></$list><$list\n\n  filter=\"[all[current]has[dropdown]]\"\n  variable=\"dropdown\"\n\n><$set\n\n  name=\"dropdown-state\"\n  value=<<qualify \"$:/state/EditorToolbarDropdown\">>\n\n><$set name=disabled filter={{!!condition-disabled}}><$button\n\n  popup=<<dropdown-state>>\n  class=\"tc-popup-keep tc-btn-invisible $(buttonClasses)$\"\n  selectedClass=\"tc-selected\"\n  tooltip=<<tooltip-text>>\n  actions={{!!actions}}\n  disabled=<<disabled>>\n\n><span\n\n  data-tw-keyboard-shortcut={{{ [<disabled>match[yes]then[]else{!!shortcuts}] }}}\n\n/><<toolbar-button-icon>><$transclude\n\n  tiddler=<<currentTiddler>>\n  field=\"text\"\n\n/></$button></$set><$reveal\n\n  state=<<dropdown-state>>\n  type=\"popup\"\n  position=\"below\"\n  animate=\"yes\"\n  tag=\"span\"\n\n><div\n\n  class=\"tc-drop-down tc-popup-keep\"\n\n><$transclude\n\n  tiddler={{!!dropdown}}\n  mode=\"block\"\n\n/></div></$reveal></$set></$list></$wikify></$list>\n\\end\n\n\\define toolbar-button-outer()\n<$set\n\n  name=\"buttonClasses\"\n  value={{!!button-classes}}\n\n><<toolbar-button>></$set>\n\\end\n\n<<toolbar-button-outer>>"},"$:/core/ui/EditTemplate/body":{"title":"$:/core/ui/EditTemplate/body","tags":"$:/tags/EditTemplate","text":"<$transclude tiddler={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/EditTemplateBodyFilter]!is[draft]get[text]] :and[!is[blank]else[$:/core/ui/EditTemplate/body/default]] }}} />\n"},"$:/core/ui/EditTemplate/controls":{"title":"$:/core/ui/EditTemplate/controls","tags":"$:/tags/EditTemplate","text":"\\define config-title() $:/config/EditToolbarButtons/Visibility/$(listItem)$\n\\whitespace trim\n<div class=\"tc-tiddler-title tc-tiddler-edit-title tc-clearfix\">\n\t<$view field=\"title\"/>\n\t<span class=\"tc-tiddler-controls tc-titlebar\">\n\t\t<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/EditToolbar]!has[draft.of]]\" variable=\"listItem\">\n\t\t\t<$let tv-config-toolbar-class={{{ [enlist<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]] +[join[ ]] }}}>\n\t\t\t\t<$reveal type=\"nomatch\" state=<<config-title>> text=\"hide\">\n\t\t\t\t\t<$transclude $tiddler=<<listItem>>/>\n\t\t\t\t</$reveal>\n\t\t\t</$let>\n\t\t</$list>\n\t</span>\n</div>\n"},"$:/core/ui/EditTemplate/fieldEditor/default":{"title":"$:/core/ui/EditTemplate/fieldEditor/default","text":"<$edit-text tiddler=<<currentTiddler>> field=<<currentField>> tag=\"input\" default=\"\" class=\"tc-edit-texteditor tc-edit-fieldeditor\" placeholder={{$:/language/EditTemplate/Fields/Add/Value/Placeholder}} tabindex={{$:/config/EditTabIndex}} cancelPopups=\"yes\"/>"},"$:/core/ui/EditTemplate/fields":{"title":"$:/core/ui/EditTemplate/fields","tags":"$:/tags/EditTemplate","text":"\\procedure lingo-base() $:/language/EditTemplate/\n\\function tf.config-title() [[$:/config/EditTemplateFields/Visibility/]addsuffix[$(currentField)$]substitute[]get[text]]\n\n\\function tf.config-filter() [[hide]] :except[title<tf.config-title>]\n\n<!-- Beware this is duplicated from EditTemplate.tid. For details see bug #7054 -->\n\\procedure get-field-value-tiddler-filter() [subfilter<get-field-editor-filter>sha256[16]addprefix[/]addprefix<newFieldValueTiddlerPrefix>]\n\\procedure get-field-editor-filter() [<newFieldNameTiddler>get[text]else[]] :cascade[all[shadows+tiddlers]tag[$:/tags/FieldEditorFilter]!is[draft]get[text]] :and[!is[blank]else{$:/core/ui/EditTemplate/fieldEditor/default}]\n\n\\procedure prefix.bracket() [\n\\procedure suffix.bracket() ]\n\n\\function tf.current-tiddler-new-field-selector() [[data-tiddler-title=]addprefix[$(prefix.bracket)$]substitute[]addsuffix<currentTiddlerCSSescaped>addsuffix[$(suffix.bracket)$]substitute[]] .tc-edit-field-add-name-wrapper input :and[join[ ]]\n\n\\procedure new-field-actions()\n\\whitespace trim\n<$action-sendmessage $message=\"tm-add-field\" $name={{{ [<newFieldNameTiddler>get[text]] }}} $value={{{ [<newFieldNameTiddler>get[text]] :map[subfilter<get-field-value-tiddler-filter>get[text]] }}}/>\n<$set name=\"safeNewFieldValueTiddlerPrefix\" value=<<newFieldValueTiddlerPrefix>> emptyValue=<<qualify \"$:/temp/NewFieldValue\">> >\n\t<$action-deletetiddler $filter=\"[<newFieldNameTiddler>] [prefix[$:/temp/NewFieldValue]prefix<safeNewFieldValueTiddlerPrefix>] [<storeTitle>] [<searchListState>]\"/>\n</$set>\n<$action-sendmessage $message=\"tm-focus-selector\" $param=<<tf.current-tiddler-new-field-selector>>/>\n\\end\n\n\\procedure delete-state-tiddlers() <$action-deletetiddler $filter=\"[<newFieldNameTiddler>] [<storeTitle>] [<searchListState>]\"/>\n\n\\procedure cancel-search-actions-inner()\n\\whitespace trim\n<$list\n\tfilter=\"[<storeTitle>has[text]] [<newFieldNameTiddler>has[text]]\"\n\tvariable=\"ignore\"\n\temptyMessage=\"<<cancel-delete-tiddler-actions 'cancel'>>\">\n<<delete-state-tiddlers>>\n</$list>\n\\end\n\n\\procedure cancel-search-actions()\n\\whitespace trim\n<$set name=\"userInput\" value={{{ [<storeTitle>get[text]] }}}>\n<$list\n\tfilter=\"[<newFieldNameTiddler>get[text]!match<userInput>]\"\n\temptyMessage=\"<<cancel-search-actions-inner>>\">\n<$action-setfield $tiddler=<<newFieldNameTiddler>> text=<<userInput>>/><$action-setfield $tiddler=<<refreshTitle>> text=\"yes\"/>\n</$list>\n</$set>\n\\end\n\n\\procedure new-field()\n\\whitespace trim\n<$vars name={{{ [<newFieldNameTiddler>get[text]] }}}>\n<$reveal type=\"nomatch\" text=\"\" default=<<name>>>\n<$button tooltip={{$:/language/EditTemplate/Fields/Add/Button/Hint}}>\n<$action-sendmessage $message=\"tm-add-field\"\n$name=<<name>>\n$value={{{ [subfilter<get-field-value-tiddler-filter>get[text]] }}}/>\n<$set name=\"safeNewFieldValueTiddlerPrefix\" value=<<newFieldValueTiddlerPrefix>> emptyValue=<<qualify \"$:/temp/NewFieldValue\">> >\n\t<$action-deletetiddler $filter=\"[<newFieldNameTiddler>] [prefix[$:/temp/NewFieldValue]prefix<safeNewFieldValueTiddlerPrefix>] [<storeTitle>] [<searchListState>]\"/>\n</$set>\n<<lingo Fields/Add/Button>>\n</$button>\n</$reveal>\n<$reveal type=\"match\" text=\"\" default=<<name>>>\n<$button>\n<<lingo Fields/Add/Button>>\n</$button>\n</$reveal>\n</$vars>\n\\end\n\\whitespace trim\n\n<$set name=\"newFieldValueTiddlerPrefix\" value=<<newFieldValueTiddlerPrefix>> emptyValue=<<qualify \"$:/temp/NewFieldValue\">> >\n<div class=\"tc-edit-fields\">\n<table class={{{ [all[current]fields[]] :filter[lookup[$:/config/EditTemplateFields/Visibility/]!match[hide]] :and[count[]!match[0]] :and[then[tc-edit-fields]] :else[[tc-edit-fields tc-edit-fields-small]] }}}>\n<tbody>\n<$list filter=\"[all[current]fields[]] :and[sort[title]]\" variable=\"currentField\" storyview=\"pop\">\n<$list filter=<<tf.config-filter>> variable=\"temp\">\n<tr class=\"tc-edit-field\">\n<td class=\"tc-edit-field-name\">\n<$text text=<<currentField>>/>:</td>\n<td class=\"tc-edit-field-value\">\n<$keyboard key=\"((delete-field))\" actions=\"\"\"<$action-deletefield $field=<<currentField>>/><$set name=\"currentTiddlerCSSescaped\" value={{{ [<currentTiddler>escapecss[]] }}}><$action-sendmessage $message=\"tm-focus-selector\" $param=<<tf.current-tiddler-new-field-selector>>/></$set>\"\"\">\n<$transclude tiddler={{{ [<currentField>] :cascade[all[shadows+tiddlers]tag[$:/tags/FieldEditorFilter]!is[draft]get[text]] :and[!is[blank]else{$:/core/ui/EditTemplate/fieldEditor/default}] }}} />\n</$keyboard>\n</td>\n<td class=\"tc-edit-field-remove\">\n<$button class=\"tc-btn-invisible\" tooltip={{$:/language/EditTemplate/Field/Remove/Hint}} aria-label={{$:/language/EditTemplate/Field/Remove/Caption}}>\n<$action-deletefield $field=<<currentField>>/>\n{{$:/core/images/delete-button}}\n</$button>\n</td>\n</tr>\n</$list>\n</$list>\n</tbody>\n</table>\n</div>\n\n<$fieldmangler>\n<div class=\"tc-edit-field-add\">\n<em class=\"tc-edit tc-small-gap-right\">\n<<lingo Fields/Add/Prompt>>\n</em>\n<$vars refreshTitle=<<qualify \"$:/temp/fieldname/refresh\">> storeTitle=<<newFieldNameInputTiddler>> searchListState=<<newFieldNameSelectionTiddler>>>\n<div class=\"tc-edit-field-add-name-wrapper\">\n<$transclude $variable=\"keyboard-driven-input\" tiddler=<<newFieldNameTiddler>> storeTitle=<<storeTitle>> refreshTitle=<<refreshTitle>>\n\t\tselectionStateTitle=<<searchListState>> tag=\"input\" default=\"\" placeholder={{$:/language/EditTemplate/Fields/Add/Name/Placeholder}}\n\t\tfocusPopup=<<qualify \"$:/state/popup/field-dropdown\">> class=\"tc-edit-texteditor tc-popup-handle\" tabindex={{$:/config/EditTabIndex}}\n\t\tfocus={{{ [{$:/config/AutoFocus}match[fields]then[true]] :else[[false]] }}} cancelPopups=\"yes\"\n\t\tconfigTiddlerFilter=\"[[$:/config/EditMode/fieldname-filter]]\" inputCancelActions=<<cancel-search-actions>> />\n<$button popup=<<qualify \"$:/state/popup/field-dropdown\">> class=\"tc-btn-invisible tc-btn-dropdown tc-small-gap\" tooltip={{$:/language/EditTemplate/Field/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Field/Dropdown/Caption}}>{{$:/core/images/down-arrow}}</$button>\n<$reveal state=<<qualify \"$:/state/popup/field-dropdown\">> type=\"nomatch\" text=\"\" default=\"\">\n<div class=\"tc-block-dropdown tc-edit-type-dropdown\">\n<$set name=\"tv-show-missing-links\" value=\"yes\">\n<$linkcatcher to=<<newFieldNameTiddler>>>\n<div class=\"tc-dropdown-item\">\n<<lingo Fields/Add/Dropdown/User>>\n</div>\n<$set name=\"newFieldName\" value={{{ [<storeTitle>get[text]] }}}>\n<$list filter=\"[!is[shadow]!is[system]fields[]search:title<newFieldName>sort[]] :except[[created]] :except[[creator]] :except[[draft.of]] :except[[draft.title]] :except[[modified]] :except[[modifier]] :except[[tags]] :except[[text]] :except[[title]] :except[[type]]\"  variable=\"currentField\">\n<$list filter=\"[<currentField>addsuffix[-primaryList]] :except[<searchListState>get[text]]\" emptyMessage=\"\"\"<$link to=<<currentField>> class=\"tc-list-item-selected\"><$text text=<<currentField>>/></$link>\"\"\">\n<$link to=<<currentField>>>\n<$text text=<<currentField>>/>\n</$link>\n</$list>\n</$list>\n<div class=\"tc-dropdown-item\">\n<<lingo Fields/Add/Dropdown/System>>\n</div>\n<$list filter=\"[fields[]search:title<newFieldName>sort[]] :except[!is[shadow]!is[system]fields[]]\" variable=\"currentField\">\n<$list filter=\"[<currentField>addsuffix[-secondaryList]] :except[<searchListState>get[text]]\" emptyMessage=\"\"\"<$link to=<<currentField>> class=\"tc-list-item-selected\"><$text text=<<currentField>>/></$link>\"\"\">\n<$link to=<<currentField>>>\n<$text text=<<currentField>>/>\n</$link>\n</$list>\n</$list>\n</$set>\n</$linkcatcher>\n</$set>\n</div>\n</$reveal>\n</div>\n<$let currentTiddlerCSSescaped={{{ [<currentTiddler>escapecss[]] }}} currentTiddler={{{ [subfilter<get-field-value-tiddler-filter>] }}} currentField=\"text\" currentFieldName={{{ [<newFieldNameTiddler>get[text]] }}}>\n<span class=\"tc-edit-field-add-value tc-small-gap-right\">\n<$keyboard key=\"((add-field))\" actions=<<new-field-actions>>>\n<$transclude tiddler={{{ [subfilter<get-field-editor-filter>] }}} />\n</$keyboard>\n</span>\n<span class=\"tc-edit-field-add-button\">\n<$transclude $variable=\"new-field\"/>\n</span>\n</$let>\n</$vars>\n</div>\n</$fieldmangler>\n</$set>"},"$:/core/ui/EditTemplate/shadow":{"title":"$:/core/ui/EditTemplate/shadow","tags":"$:/tags/EditTemplate","text":"\\define lingo-base() $:/language/EditTemplate/Shadow/\n\\define pluginLinkBody()\n\\whitespace trim\n<$link to=\"\"\"$(pluginTitle)$\"\"\">\n<$text text=\"\"\"$(pluginTitle)$\"\"\"/>\n</$link>\n\\end\n\\whitespace trim\n<$list filter=\"[all[current]get[draft.of]is[shadow]!is[tiddler]]\">\n\n<$list filter=\"[all[current]shadowsource[]]\" variable=\"pluginTitle\">\n\n<$set name=\"pluginLink\" value=<<pluginLinkBody>>>\n<div class=\"tc-message-box\">\n\n<<lingo Warning>>\n\n</div>\n</$set>\n</$list>\n\n</$list>\n\n<$list filter=\"[all[current]get[draft.of]is[shadow]is[tiddler]]\">\n\n<$list filter=\"[all[current]shadowsource[]]\" variable=\"pluginTitle\">\n\n<$set name=\"pluginLink\" value=<<pluginLinkBody>>>\n<div class=\"tc-message-box\">\n\n<<lingo OverriddenWarning>>\n\n</div>\n</$set>\n</$list>\n\n</$list>"},"$:/core/ui/EditTemplate/tags":{"title":"$:/core/ui/EditTemplate/tags","tags":"$:/tags/EditTemplate","text":"\\whitespace trim\n\n\\procedure lingo-base() $:/language/EditTemplate/\n\n\\procedure tag-body-inner(colour,fallbackTarget,colourA,colourB,icon,tagField:\"tags\")\n<$wikify name=\"foregroundColor\"\n\ttext=\"\"\"<$macrocall $name=\"contrastcolour\"\n\t\ttarget=<<colour>>\n\t\tfallbackTarget=<<fallbackTarget>>\n\t\tcolourA=<<colourA>>\n\t\tcolourB=<<colourB>>/>\n\t\"\"\"\n>\n\t<$let backgroundColor=<<colour>> >\n\t\t<span class=\"tc-tag-label tc-tag-list-item tc-small-gap-right\"\n\t\t\tdata-tag-title=<<currentTiddler>>\n\t\t\tstyle.color=<<foregroundColor>>\n\t\t\tstyle.fill=<<foregroundColor>>\n\t\t\tstyle.background-color=<<backgroundColor>>\n\t\t>\n\t\t\t<$transclude tiddler=<<icon>>/>\n\t\t\t<$view field=\"title\" format=\"text\"/>\n\t\t\t<$button class=\"tc-btn-invisible tc-remove-tag-button\"\n\t\t\t\tstyle.fill=<<foregroundColor>>\n\t\t\t>\n\t\t\t\t<$action-listops $tiddler=<<saveTiddler>> $field=<<tagField>> $subfilter=\"-[{!!title}]\"/>\n\t\t\t\t{{$:/core/images/close-button}}\n\t\t\t</$button>\n\t\t</span>\n\t</$let>\n</$wikify>\n\\end\n\n\\procedure tag-body(colour,palette,icon,tagField:\"tags\")\n<$macrocall $name=\"tag-body-inner\"\n\tcolour=`$(colour)$`\n\tcolourA={{{ [<palette>getindex[foreground]] }}}\n\tcolourB={{{ [<palette>getindex[background]] }}}\n\tfallbackTarget={{{ [<palette>getindex[tag-background]] }}}\n\ticon=<<icon>>\n\ttagField=<<tagField>>\n/>\n\\end\n\n\\procedure edit-tags-template(tagField:\"tags\")\n<div class=\"tc-edit-tags\">\n\t<$list filter=\"[<currentTiddler>get<tagField>enlist-input[]sort[title]]\" storyview=\"pop\">\n\t\t<$macrocall $name=\"tag-body\"\n\t\t\tcolour={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}}\n\t\t\tpalette={{$:/palette}}\n\t\t\ticon={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerIconFilter]!is[draft]get[text]] }}}\n\t\t\ttagField=<<tagField>>\n\t\t/>\n\t</$list>\n\t<$let tabIndex={{$:/config/EditTabIndex}} cancelPopups=\"yes\">\n\t\t<$macrocall $name=\"tag-picker\" tagField=<<tagField>>/>\n\t</$let>\n</div>\n\\end\n<$let saveTiddler=<<currentTiddler>>>\n\t<$macrocall $name=\"edit-tags-template\" tagField=<<tagField>>/>\n</$let>\n"},"$:/core/ui/EditTemplate/title":{"title":"$:/core/ui/EditTemplate/title","tags":"$:/tags/EditTemplate","text":"\\whitespace trim\n<$edit-text field=\"draft.title\" class=\"tc-titlebar tc-edit-texteditor\" focus={{{ [{$:/config/AutoFocus}match[title]then[true]] ~[[false]] }}} tabindex={{$:/config/EditTabIndex}} cancelPopups=\"yes\"/>\n\n<$vars pattern=\"\"\"[\\|\\[\\]{}]\"\"\" bad-chars=\"\"\"`| [ ] { }`\"\"\">\n\n<$list filter=\"[all[current]regexp:draft.title<pattern>]\" variable=\"listItem\">\n\n<div class=\"tc-message-box\">\n\n{{$:/core/images/warning}}&#32;{{$:/language/EditTemplate/Title/BadCharacterWarning}}\n\n</div>\n\n</$list>\n\n</$vars>\n\n<$reveal state=\"!!draft.title\" type=\"nomatch\" text={{!!draft.of}} tag=\"div\">\n\n<$list filter=\"[{!!draft.title}!is[missing]]\" variable=\"listItem\">\n\n<div class=\"tc-message-box\">\n\n{{$:/core/images/warning}}&#32;{{$:/language/EditTemplate/Title/Exists/Prompt}}:&#32;<$link to={{!!draft.title}} />\n\n</div>\n\n</$list>\n\n<$list filter=\"[{!!draft.of}!is[missing]]\" variable=\"listItem\">\n\n<$vars fromTitle={{!!draft.of}} toTitle={{!!draft.title}}>\n\n<$checkbox tiddler=\"$:/config/RelinkOnRename\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"no\">&#32;{{$:/language/EditTemplate/Title/Relink/Prompt}}</$checkbox>\n\n<$list filter=\"[title<fromTitle>backlinks[]limit[1]]\" variable=\"listItem\">\n\n<$vars stateTiddler=<<qualify \"$:/state/edit/references\">> >\n\n<$reveal type=\"nomatch\" state=<<stateTiddler>> text=\"show\">\n<$button set=<<stateTiddler>> setTo=\"show\" class=\"tc-btn-invisible\">\n{{$:/core/images/right-arrow}}\n&#32;\n<<lingo EditTemplate/Title/References/Prompt>></$button>\n</$reveal>\n<$reveal type=\"match\" state=<<stateTiddler>> text=\"show\">\n<$button set=<<stateTiddler>> setTo=\"hide\" class=\"tc-btn-invisible\">\n{{$:/core/images/down-arrow}}\n&#32;\n<<lingo EditTemplate/Title/References/Prompt>></$button>\n</$reveal>\n\n<$reveal type=\"match\" state=<<stateTiddler>> text=\"show\">\n<$tiddler tiddler=<<fromTitle>> >\n<$transclude tiddler=\"$:/core/ui/TiddlerInfo/References\"/>\n</$tiddler>\n</$reveal>\n\n</$vars>\n\n</$list>\n\n</$vars>\n\n</$list>\n\n</$reveal>\n"},"$:/core/ui/EditTemplate/type":{"title":"$:/core/ui/EditTemplate/type","tags":"$:/tags/EditTemplate","first-search-filter":"[all[shadows+tiddlers]prefix[$:/language/Docs/Types/]sort[description]sort[group-sort]removeprefix[$:/language/Docs/Types/]search<userInput>]","text":"\\procedure lingo-base() $:/language/EditTemplate/\n\\procedure input-cancel-actions() <$list filter=\"[<storeTitle>get[text]] [<currentTiddler>get[type]] :and[limit[1]]\" emptyMessage=\"\"\"<<cancel-delete-tiddler-actions \"cancel\">>\"\"\"><$action-sendmessage $message=\"tm-remove-field\" $param=\"type\"/><$action-deletetiddler $filter=\"[<typeInputTiddler>] [<refreshTitle>] [<typeSelectionTiddler>]\"/></$list>\n\\whitespace trim\n<$set name=\"refreshTitle\" value=<<qualify \"$:/temp/type-search/refresh\">>>\n<div class=\"tc-edit-type-selector-wrapper\">\n<em class=\"tc-edit tc-small-gap-right\"><<lingo Type/Prompt>></em>\n<div class=\"tc-type-selector-dropdown-wrapper\">\n<div class=\"tc-type-selector\"><$fieldmangler>\n<$transclude $variable=\"keyboard-driven-input\" tiddler=<<currentTiddler>> storeTitle=<<typeInputTiddler>> refreshTitle=<<refreshTitle>> selectionStateTitle=<<typeSelectionTiddler>> field=\"type\" tag=\"input\" default=\"\" placeholder={{$:/language/EditTemplate/Type/Placeholder}} focusPopup=<<qualify \"$:/state/popup/type-dropdown\">> class=\"tc-edit-typeeditor tc-edit-texteditor tc-popup-handle\" tabindex={{$:/config/EditTabIndex}} focus={{{ [{$:/config/AutoFocus}match[type]then[true]] :else[[false]] }}} cancelPopups=\"yes\" configTiddlerFilter=\"[[$:/core/ui/EditTemplate/type]]\" inputCancelActions=<<input-cancel-actions>>/><$button popup=<<qualify \"$:/state/popup/type-dropdown\">> class=\"tc-btn-invisible tc-btn-dropdown tc-small-gap\" tooltip={{$:/language/EditTemplate/Type/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Type/Dropdown/Caption}}>{{$:/core/images/down-arrow}}</$button><$button message=\"tm-remove-field\" param=\"type\" class=\"tc-btn-invisible tc-btn-icon\" tooltip={{$:/language/EditTemplate/Type/Delete/Hint}} aria-label={{$:/language/EditTemplate/Type/Delete/Caption}}>{{$:/core/images/delete-button}}<$action-deletetiddler $filter=\"[<typeInputTiddler>] [<storeTitle>] [<refreshTitle>] [<selectionStateTitle>]\"/></$button>\n</$fieldmangler></div>\n\n<div class=\"tc-block-dropdown-wrapper\">\n<$set name=\"tv-show-missing-links\" value=\"yes\">\n<$reveal state=<<qualify \"$:/state/popup/type-dropdown\">> type=\"nomatch\" text=\"\" default=\"\">\n<div class=\"tc-block-dropdown tc-edit-type-dropdown\">\n<$linkcatcher to=\"!!type\">\n<$list filter='[all[shadows+tiddlers]prefix[$:/language/Docs/Types/]each[group]sort[group-sort]]'>\n<div class=\"tc-dropdown-item\">\n<$text text={{!!group}}/>\n</div>\n<$set name=\"userInput\" value={{{ [<typeInputTiddler>get[text]] }}}>\n<$list filter=\"[all[shadows+tiddlers]prefix[$:/language/Docs/Types/]group{!!group}] :and[sort[description]] :and[removeprefix[$:/language/Docs/Types/]] :and[search<userInput>]\"><span class={{{ [<currentTiddler>addsuffix[-primaryList]] :except[<typeSelectionTiddler>get[text]] :and[then[]else[tc-list-item-selected]] }}}><$link to={{{ [<currentTiddler>addprefix[$:/language/Docs/Types/]get[name]] }}}><$view tiddler={{{ [<currentTiddler>addprefix[$:/language/Docs/Types/]] }}} field=\"description\"/><$text text=\" \"/>(<$view tiddler={{{ [<currentTiddler>addprefix[$:/language/Docs/Types/]] }}} field=\"name\"/>)</$link></span>\n</$list>\n</$set>\n</$list>\n</$linkcatcher>\n</div>\n</$reveal>\n</$set>\n</div>\n</div>\n</div>\n</$set>\n"},"$:/core/ui/EditTemplate":{"title":"$:/core/ui/EditTemplate","code-body":"yes","text":"\\define delete-edittemplate-state-tiddlers()\n<$set name=\"safeNewFieldValueTiddlerPrefix\" value=<<newFieldValueTiddlerPrefix>> emptyValue=<<qualify \"$:/temp/NewFieldValue\">> >\n\t<$action-deletetiddler $filter=\"[<newFieldNameTiddler>] [prefix[$:/temp/NewFieldValue]prefix<safeNewFieldValueTiddlerPrefix>] [<newFieldNameInputTiddler>] [<newFieldNameSelectionTiddler>] [<newTagNameTiddler>] [<newTagNameInputTiddler>] [<newTagNameSelectionTiddler>] [<typeInputTiddler>] [<typeSelectionTiddler>]\"/>\n</$set>\n\\end\n\n<!-- Beware this is duplicated from fields.tid. For details see bug #7054 -->\n\\define get-field-value-tiddler-filter() [subfilter<get-field-editor-filter>sha256[16]addprefix[/]addprefix<newFieldValueTiddlerPrefix>]\n\\define get-field-editor-filter() [<newFieldNameTiddler>get[text]else[]] :cascade[all[shadows+tiddlers]tag[$:/tags/FieldEditorFilter]!is[draft]get[text]] :and[!is[blank]else{$:/core/ui/EditTemplate/fieldEditor/default}]\n\n\\define save-tiddler-actions()\n\\whitespace trim\n<$action-sendmessage $message=\"tm-add-tag\" $param={{{ [<newTagNameTiddler>get[text]] }}}/>\n<$action-sendmessage $message=\"tm-add-field\" $name={{{ [<newFieldNameTiddler>get[text]] }}} $value={{{ [<newFieldNameTiddler>get[text]] :map[subfilter<get-field-value-tiddler-filter>get[text]] }}}/>\n<<delete-edittemplate-state-tiddlers>>\n<$action-sendmessage $message=\"tm-save-tiddler\"/>\n\\end\n\n\\define cancel-delete-tiddler-actions(message)\n\\whitespace trim\n<<delete-edittemplate-state-tiddlers>>\n<$action-sendmessage $message=\"tm-$message$-tiddler\"/>\n\\end\n\n\\whitespace trim\n<div\n\tdata-tiddler-title=<<currentTiddler>>\n\tdata-tags={{!!tags}}\n\tclass={{{ [all[shadows+tiddlers]tag[$:/tags/ClassFilters/TiddlerTemplate]!is[draft]] :map:flat[subfilter{!!text}] tc-tiddler-frame tc-tiddler-edit-frame [<currentTiddler>is[tiddler]then[tc-tiddler-exists]] [<currentTiddler>is[missing]!is[shadow]then[tc-tiddler-missing]] [<currentTiddler>is[shadow]then[tc-tiddler-exists tc-tiddler-shadow]] [<currentTiddler>is[system]then[tc-tiddler-system]] [{!!class}] [<currentTiddler>tags[]encodeuricomponent[]addprefix[tc-tagged-]] +[join[ ]] }}}\n\trole=\"region\"\n\taria-label={{$:/language/EditTemplate/Caption}}>\n<$fieldmangler>\n<$vars\n\tstoryTiddler=<<currentTiddler>>\n\tnewTagNameTiddler=<<qualify \"$:/temp/NewTagName\">>\n\tnewFieldNameTiddler=<<qualify \"$:/temp/NewFieldName\">>\n\tnewFieldValueTiddlerPrefix=<<qualify \"$:/temp/NewFieldValue\">>\n\tnewFieldNameInputTiddler=<<qualify \"$:/temp/NewFieldName/input\">>\n\tnewFieldNameSelectionTiddler=<<qualify \"$:/temp/NewFieldName/selected-item\">>\n\tnewTagNameInputTiddler=<<qualify \"$:/temp/NewTagName/input\">>\n\tnewTagNameSelectionTiddler=<<qualify \"$:/temp/NewTagName/selected-item\">>\n\ttypeInputTiddler=<<qualify \"$:/temp/Type/input\">>\n\ttypeSelectionTiddler=<<qualify \"$:/temp/Type/selected-item\">>>\n<$keyboard key=\"((cancel-edit-tiddler))\" actions=<<cancel-delete-tiddler-actions \"cancel\">> tag=\"div\">\n<$keyboard key=\"((save-tiddler))\" actions=<<save-tiddler-actions>> tag=\"div\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/EditTemplate]!has[draft.of]]\" variable=\"listItem\">\n<$transclude tiddler=<<listItem>>/>\n</$list>\n</$keyboard>\n</$keyboard>\n</$vars>\n</$fieldmangler>\n</div>\n"},"$:/core/ui/Buttons/cancel":{"title":"$:/core/ui/Buttons/cancel","tags":"$:/tags/EditToolbar","caption":"{{$:/core/images/cancel-button}} {{$:/language/Buttons/Cancel/Caption}}","description":"{{$:/language/Buttons/Cancel/Hint}}","text":"\\whitespace trim\n<$button actions=<<cancel-delete-tiddler-actions \"cancel\">>\n\ttooltip={{$:/language/Buttons/Cancel/Hint}}\n\taria-label={{$:/language/Buttons/Cancel/Hint}}\n\tclass=<<tv-config-toolbar-class>>\n>\n\t<%if [<tv-config-toolbar-icons>match[yes]] %>\n\t\t{{$:/core/images/cancel-button}}\n\t<%endif%>\n\t<%if [<tv-config-toolbar-text>match[yes]] %>\n\t\t<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Cancel/Caption}}/></span>\n\t<%endif%>\n</$button>\n"},"$:/core/ui/Buttons/delete":{"title":"$:/core/ui/Buttons/delete","tags":"$:/tags/EditToolbar $:/tags/ViewToolbar","caption":"{{$:/core/images/delete-button}} {{$:/language/Buttons/Delete/Caption}}","description":"{{$:/language/Buttons/Delete/Hint}}","text":"\\whitespace trim\n<$button actions=<<cancel-delete-tiddler-actions \"delete\">>\n\ttooltip={{$:/language/Buttons/Delete/Hint}}\n\taria-label={{$:/language/Buttons/Delete/Hint}}\n\tclass=<<tv-config-toolbar-class>>\n>\n\t<%if [<tv-config-toolbar-icons>match[yes]] %>\n\t\t{{$:/core/images/delete-button}}\n\t<%endif%>\n\t<%if [<tv-config-toolbar-text>match[yes]] %>\n\t\t<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Delete/Caption}}/></span>\n\t<%endif%>\n</$button>\n"},"$:/core/ui/Buttons/save":{"title":"$:/core/ui/Buttons/save","tags":"$:/tags/EditToolbar","caption":"{{$:/core/images/done-button}} {{$:/language/Buttons/Save/Caption}}","description":"{{$:/language/Buttons/Save/Hint}}","text":"\\whitespace trim\n\\procedure save-tiddler-button()\n<$fieldmangler>\n\t<$button\n\t\ttooltip={{$:/language/Buttons/Save/Hint}}\n\t\taria-label={{$:/language/Buttons/Save/Hint}}\n\t\tclass=<<tv-config-toolbar-class>>\n\t>\n\t\t<<save-tiddler-actions>>\n\t\t<%if [<tv-config-toolbar-icons>match[yes]] %>\n\t\t\t{{$:/core/images/done-button}}\n\t\t<%endif%>\n\t\t<%if [<tv-config-toolbar-text>match[yes]] %>\n\t\t\t<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Save/Caption}}/></span>\n\t\t<%endif%>\n\t</$button>\n</$fieldmangler>\n\\end\n<<save-tiddler-button>>\n"},"$:/core/ui/EditorToolbar/bold":{"title":"$:/core/ui/EditorToolbar/bold","tags":"$:/tags/EditorToolbar","icon":"$:/core/images/bold","caption":"{{$:/language/Buttons/Bold/Caption}}","description":"{{$:/language/Buttons/Bold/Hint}}","condition":"[<targetTiddler>!has[type]] [<targetTiddler>get[type]prefix[text/vnd.tiddlywiki]]","shortcuts":"((bold))","text":"<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"''\"\n\tsuffix=\"''\"\n\ttrimSelection=\"yes\"\n/>\n"},"$:/core/ui/EditorToolbar/clear-dropdown":{"title":"$:/core/ui/EditorToolbar/clear-dropdown","text":"''{{$:/language/Buttons/Clear/Hint}}''\n\n<div class=\"tc-colour-chooser\">\n\n<$macrocall $name=\"colour-picker\" actions=\"\"\"\n\n<$action-sendmessage\n\t$message=\"tm-edit-bitmap-operation\"\n\t$param=\"clear\"\n\tcolour=<<colour-picker-value>>\n/>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n\"\"\"/>\n\n</div>\n"},"$:/core/ui/EditorToolbar/clear":{"title":"$:/core/ui/EditorToolbar/clear","tags":"$:/tags/EditorToolbar","icon":"$:/core/images/erase","caption":"{{$:/language/Buttons/Clear/Caption}}","description":"{{$:/language/Buttons/Clear/Hint}}","condition":"[<targetTiddler>is[image]] -[<targetTiddler>type[image/svg+xml]]","dropdown":"$:/core/ui/EditorToolbar/clear-dropdown","text":""},"$:/core/ui/EditorToolbar/editor-height-dropdown":{"title":"$:/core/ui/EditorToolbar/editor-height-dropdown","text":"\\define lingo-base() $:/language/Buttons/EditorHeight/\n''<<lingo Hint>>''\n\n<$radio tiddler=\"$:/config/TextEditor/EditorHeight/Mode\" value=\"auto\"> {{$:/core/images/auto-height}} <<lingo Caption/Auto>></$radio>\n\n<$radio tiddler=\"$:/config/TextEditor/EditorHeight/Mode\" value=\"fixed\"> {{$:/core/images/fixed-height}} <<lingo Caption/Fixed>> <$edit-text tag=\"input\" tiddler=\"$:/config/TextEditor/EditorHeight/Height\" default=\"100px\"/></$radio>\n"},"$:/core/ui/EditorToolbar/editor-height":{"title":"$:/core/ui/EditorToolbar/editor-height","tags":"$:/tags/EditorToolbar","icon":"$:/core/images/fixed-height","custom-icon":"yes","caption":"{{$:/language/Buttons/EditorHeight/Caption}}","description":"{{$:/language/Buttons/EditorHeight/Hint}}","condition":"[<targetTiddler>type[]] [<targetTiddler>get[type]prefix[text/]] [<targetTiddler>get[type]match[application/javascript]] [<targetTiddler>get[type]match[application/json]] [<targetTiddler>get[type]match[application/x-tiddler-dictionary]] [<targetTiddler>get[type]match[image/svg+xml]] +[first[]]","dropdown":"$:/core/ui/EditorToolbar/editor-height-dropdown","text":"\\whitespace trim\n<$reveal tag=\"span\" state=\"$:/config/TextEditor/EditorHeight/Mode\" type=\"match\" text=\"fixed\">\n{{$:/core/images/fixed-height}}\n</$reveal>\n<$reveal tag=\"span\" state=\"$:/config/TextEditor/EditorHeight/Mode\" type=\"match\" text=\"auto\">\n{{$:/core/images/auto-height}}\n</$reveal>\n"},"$:/core/ui/EditorToolbar/excise-dropdown":{"title":"$:/core/ui/EditorToolbar/excise-dropdown","text":"\\define lingo-base() $:/language/Buttons/Excise/\n\n\\define body(config-title)\n\\whitespace trim\n''<<lingo Hint>>''\n\n<<lingo Caption/NewTitle>>&#32;<$edit-text tag=\"input\" tiddler=\"$config-title$/new-title\" default=\"\" focus=\"true\"/>\n\n<$set name=\"new-title\" value={{$config-title$/new-title}}>\n<$list filter=\"\"\"[<new-title>is[tiddler]]\"\"\">\n<div class=\"tc-error\">\n<<lingo Caption/TiddlerExists>>\n</div>\n</$list>\n</$set>\n\n<$checkbox tiddler=\"\"\"$config-title$/tagnew\"\"\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"false\">&#32;<<lingo Caption/Tag>></$checkbox>\n\n<<lingo Caption/Replace>>&#32;<$select tiddler=\"\"\"$config-title$/type\"\"\" default=\"transclude\">\n<option value=\"link\"><<lingo Caption/Replace/Link>></option>\n<option value=\"transclude\"><<lingo Caption/Replace/Transclusion>></option>\n<option value=\"macro\"><<lingo Caption/Replace/Macro>></option>\n</$select>\n\n<$reveal state=\"\"\"$config-title$/type\"\"\" type=\"match\" text=\"macro\">\n<<lingo Caption/MacroName>>&#32;<$edit-text tag=\"input\" tiddler=\"\"\"$config-title$/macro-title\"\"\" default=\"translink\"/>\n</$reveal>\n\n<$button>\n<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"excise\"\n\ttitle={{$config-title$/new-title}}\n\ttype={{$config-title$/type}}\n\tmacro={{$config-title$/macro-title}}\n\ttagnew={{$config-title$/tagnew}}\n/>\n<$action-deletetiddler\n\t$tiddler=\"$config-title$/new-title\"\n/>\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n<<lingo Caption/Excise>>\n</$button>\n\\end\n\n<$macrocall $name=\"body\" config-title=<<qualify \"$:/state/Excise/\">>/>\n"},"$:/core/ui/EditorToolbar/excise":{"title":"$:/core/ui/EditorToolbar/excise","tags":"$:/tags/EditorToolbar","icon":"$:/core/images/excise","caption":"{{$:/language/Buttons/Excise/Caption}}","description":"{{$:/language/Buttons/Excise/Hint}}","condition":"[<targetTiddler>type[]] [<targetTiddler>type[text/vnd.tiddlywiki]] [<targetTiddler>type[text/markdown]] [<targetTiddler>type[text/x-markdown]] +[first[]]","shortcuts":"((excise))","dropdown":"$:/core/ui/EditorToolbar/excise-dropdown","text":""},"$:/core/ui/EditorToolbar/file-import":{"title":"$:/core/ui/EditorToolbar/file-import","tags":"$:/tags/EditorTools","condition":"[<targetTiddler>filter{$:/config/Editor/EnableImportFilter}]","text":"\\procedure lingo-base() $:/language/Import/\n\n\\procedure closePopupActions()\n<$action-deletetiddler $filter=\"[title<importState>] [title<importTitle>]\"/>\n\\end closePopupActions\n\n\\procedure tw5-ImageTemplate() [img[$(currentTiddler)$]]\n\\procedure tw5-FileTemplate() [[$(currentTiddler)$]]\n\n<!-- The following characters must be escaped in markdown: <>()\\ -->\n\\function escape.title() [search-replace:g:regexp[\\(|\\)|<|>|\\\\],[\\$&]]\n\\procedure markdown-ImageTemplate() ![](<#${ [<currentTiddler>escape.title[]] }$>)\n\\procedure markdown-FileTemplate() [](<#${ [<currentTiddler>escape.title[]] }$>)\n\n\\function is.markdown.tiddler() [all[]type[text/x-markdown]] [all[]type[text/markdown]]\n\\function is.image() [get[type]prefix[image]]\n\\function get.markdown.link() [is.image[]then<markdown-ImageTemplate>else<markdown-FileTemplate>]\n\\function get.tw5.link() [is.image[]then<tw5-ImageTemplate>else<tw5-FileTemplate>] \n\\function get.link.template() [<storyTiddler>is.markdown.tiddler[]then<get.markdown.link>else<get.tw5.link>]\n\n\\procedure postImportActions()\n\\whitespace trim\n<$list filter=\"[<importTitle>links[]] :reduce[get.link.template[]substitute[]addprefix<accumulator>]\" variable=\"imageTitle\">\n<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"insert-text\"\n\ttext=<<imageTitle>>\n/>\n</$list>\n<<closePopupActions>>\n\\end postImportActions\n\n\\procedure buttons()\n\\whitespace trim\n<$button class=\"tc-btn-invisible\" actions=<<closePopupActions>> ><<lingo Listing/Cancel/Caption>></$button>\n&#32;\n<$button class=\"tc-btn-invisible\" message=\"tm-perform-import\" param=<<importTitle>> actions=<<postImportActions>> ><<lingo Listing/Import/Caption>></$button>\n\\end buttons\n\n\\whitespace trim\n<$reveal type=\"popup\" state=<<importState>> tag=\"div\" class=\"tc-editor-importpopup\">\n<div class=\"tc-editor-import\">\n<$list filter=\"[<importTitle>field:plugin-type[import]]\">\n<h2><<lingo Editor/Import/Heading>></h2>\n<$tiddler tiddler=<<importTitle>>>\n{{||$:/core/ui/ImportListing}}\n<<buttons>>\n</$tiddler>\n</$list>\n</div>\n</$reveal>"},"$:/core/ui/EditorToolbar/heading-1":{"title":"$:/core/ui/EditorToolbar/heading-1","tags":"$:/tags/EditorToolbar","icon":"$:/core/images/heading-1","caption":"{{$:/language/Buttons/Heading1/Caption}}","description":"{{$:/language/Buttons/Heading1/Hint}}","condition":"[<targetTiddler>!has[type]] [<targetTiddler>get[type]prefix[text/vnd.tiddlywiki]]","button-classes":"tc-text-editor-toolbar-item-start-group","shortcuts":"((heading-1))","text":"<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"!\"\n\tcount=\"1\"\n/>\n"},"$:/core/ui/EditorToolbar/heading-2":{"title":"$:/core/ui/EditorToolbar/heading-2","tags":"$:/tags/EditorToolbar","icon":"$:/core/images/heading-2","caption":"{{$:/language/Buttons/Heading2/Caption}}","description":"{{$:/language/Buttons/Heading2/Hint}}","condition":"[<targetTiddler>!has[type]] [<targetTiddler>get[type]prefix[text/vnd.tiddlywiki]]","shortcuts":"((heading-2))","text":"<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"!\"\n\tcount=\"2\"\n/>\n"},"$:/core/ui/EditorToolbar/heading-3":{"title":"$:/core/ui/EditorToolbar/heading-3","tags":"$:/tags/EditorToolbar","icon":"$:/core/images/heading-3","caption":"{{$:/language/Buttons/Heading3/Caption}}","description":"{{$:/language/Buttons/Heading3/Hint}}","condition":"[<targetTiddler>!has[type]] [<targetTiddler>get[type]prefix[text/vnd.tiddlywiki]]","shortcuts":"((heading-3))","text":"<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"!\"\n\tcount=\"3\"\n/>\n"},"$:/core/ui/EditorToolbar/heading-4":{"title":"$:/core/ui/EditorToolbar/heading-4","tags":"$:/tags/EditorToolbar","icon":"$:/core/images/heading-4","caption":"{{$:/language/Buttons/Heading4/Caption}}","description":"{{$:/language/Buttons/Heading4/Hint}}","condition":"[<targetTiddler>!has[type]] [<targetTiddler>get[type]prefix[text/vnd.tiddlywiki]]","shortcuts":"((heading-4))","text":"<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"!\"\n\tcount=\"4\"\n/>\n"},"$:/core/ui/EditorToolbar/heading-5":{"title":"$:/core/ui/EditorToolbar/heading-5","tags":"$:/tags/EditorToolbar","icon":"$:/core/images/heading-5","caption":"{{$:/language/Buttons/Heading5/Caption}}","description":"{{$:/language/Buttons/Heading5/Hint}}","condition":"[<targetTiddler>!has[type]] [<targetTiddler>get[type]prefix[text/vnd.tiddlywiki]]","shortcuts":"((heading-5))","text":"<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"!\"\n\tcount=\"5\"\n/>\n"},"$:/core/ui/EditorToolbar/heading-6":{"title":"$:/core/ui/EditorToolbar/heading-6","tags":"$:/tags/EditorToolbar","icon":"$:/core/images/heading-6","caption":"{{$:/language/Buttons/Heading6/Caption}}","description":"{{$:/language/Buttons/Heading6/Hint}}","condition":"[<targetTiddler>!has[type]] [<targetTiddler>get[type]prefix[text/vnd.tiddlywiki]]","shortcuts":"((heading-6))","text":"<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"!\"\n\tcount=\"6\"\n/>\n"},"$:/core/ui/EditorToolbar/italic":{"title":"$:/core/ui/EditorToolbar/italic","tags":"$:/tags/EditorToolbar","icon":"$:/core/images/italic","caption":"{{$:/language/Buttons/Italic/Caption}}","description":"{{$:/language/Buttons/Italic/Hint}}","condition":"[<targetTiddler>!has[type]] [<targetTiddler>get[type]prefix[text/vnd.tiddlywiki]]","shortcuts":"((italic))","text":"<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"//\"\n\tsuffix=\"//\"\n\ttrimSelection=\"yes\"\n/>\n"},"$:/core/ui/EditorToolbar/line-width-dropdown":{"title":"$:/core/ui/EditorToolbar/line-width-dropdown","text":"\\define lingo-base() $:/language/Buttons/LineWidth/\n\n\\define toolbar-line-width-inner()\n<$button tag=\"a\" tooltip=\"\"\"$(line-width)$\"\"\">\n\n<$action-setfield\n\t$tiddler=\"$:/config/BitmapEditor/LineWidth\"\n\t$value=\"$(line-width)$\"\n/>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n<div style=\"display: inline-block; margin: 4px calc(80px - $(line-width)$); background-color: #000; width: calc(100px + $(line-width)$ * 2); height: $(line-width)$; border-radius: 120px; vertical-align: middle;\"/>\n\n<span style=\"margin-left: 8px;\">\n\n<$text text=\"\"\"$(line-width)$\"\"\"/>\n\n<$reveal state=\"$:/config/BitmapEditor/LineWidth\" type=\"match\" text=\"\"\"$(line-width)$\"\"\" tag=\"span\">\n\n<$entity entity=\"&nbsp;\"/>\n\n<$entity entity=\"&#x2713;\"/>\n\n</$reveal>\n\n</span>\n\n</$button>\n\\end\n\n''<<lingo Hint>>''\n\n<$list filter={{$:/config/BitmapEditor/LineWidths}} variable=\"line-width\">\n\n<<toolbar-line-width-inner>>\n\n</$list>\n"},"$:/core/ui/EditorToolbar/line-width":{"title":"$:/core/ui/EditorToolbar/line-width","tags":"$:/tags/EditorToolbar","icon":"$:/core/images/line-width","caption":"{{$:/language/Buttons/LineWidth/Caption}}","description":"{{$:/language/Buttons/LineWidth/Hint}}","condition":"[<targetTiddler>is[image]] -[<targetTiddler>type[image/svg+xml]]","dropdown":"$:/core/ui/EditorToolbar/line-width-dropdown","text":"<$text text={{$:/config/BitmapEditor/LineWidth}}/>\n"},"$:/core/ui/EditorToolbar/link-dropdown":{"title":"$:/core/ui/EditorToolbar/link-dropdown","text":"\\procedure lingo-base() $:/language/Buttons/Link/\n\n\\procedure add-link-actions()\n\\whitespace trim\n<$action-sendmessage $message=\"tm-edit-text-operation\" $param=\"make-link\" text={{{ [<linkTiddler>get[text]] }}} />\n<$action-deletetiddler $filter=\"[<dropdown-state>] [<searchTiddler>] [<linkTiddler>] [<storeTitle>] [<searchListState>]\"/>\n\\end\n\n\\procedure prefix.bracket() [\n\\procedure suffix.bracket() ]\n\n\\function tf.get-focus-selector() [[data-tiddler-title=]addprefix[$(prefix.bracket)$]substitute[]addsuffix<cssEscapedTitle>addsuffix[$(suffix.bracket)$]substitute[]] .tc-create-wikitext-link input :and[join[ ]]\n\n\\procedure cancel-search-actions-inner()\n<$set name=\"userInput\" value={{{ [<storeTitle>get[text]] }}}><$list filter=\"[<searchTiddler>get[text]!match<userInput>]\" emptyMessage=\"<$action-deletetiddler $filter='[<searchTiddler>] [<linkTiddler>] [<storeTitle>] [<searchListState>]'/>\"><$action-setfield $tiddler=<<searchTiddler>> text=<<userInput>>/><$action-setfield $tiddler=<<refreshTitle>> text=\"yes\"/></$list></$set>\n\\end\n\n\\procedure cancel-search-actions() <$list filter=\"[<storeTitle>!has[text]] :and[<searchTiddler>!has[text]]\" emptyMessage=\"<<cancel-search-actions-inner>>\"><$action-sendmessage $message=\"tm-edit-text-operation\" $param=\"focus-editor\"/></$list>\n\n\\procedure external-link()\n\\whitespace trim\n<$button class=\"tc-btn-invisible tc-btn-mini\" style=\"width: auto; display: inline-block; background-colour: inherit;\" actions=<<add-link-actions>>>\n{{$:/core/images/chevron-right}}\n</$button>\n\\end\n\n\\procedure set-next-input-tab() <$transclude $variable=\"change-input-tab-after\" stateTitle=\"$:/state/tab/search-results/sidebar\" tag=\"$:/tags/SearchResults\" defaultState={{$:/config/SearchResults/Default}} actions=\"<$action-setfield $tiddler='$:/state/search/currentTab' text=<<nextTab>>/>\"/>\n\n\\procedure set-previous-input-tab() <$transclude $variable=\"change-input-tab-before\" stateTitle=\"$:/state/tab/search-results/sidebar\" tag=\"$:/tags/SearchResults\" defaultState={{$:/config/SearchResults/Default}} actions=\"<$action-setfield $tiddler='$:/state/search/currentTab' text=<<nextTab>>/>\"/>\n\n\\procedure body(config-title)\n\\whitespace trim\n''<<lingo Hint>>''\n\n<$vars searchTiddler={{{ [<config-title>addsuffix[/search]] }}} linkTiddler={{{ [<config-title>addsuffix[/link]] }}} linktext=\"\" searchListState=<<qualify \"$:/temp/link-search/selected-item\">> refreshTitle=<<qualify \"$:/temp/link-search/refresh\">> storeTitle=<<qualify \"$:/temp/link-search/input\">>>\n\n<$vars linkTiddler=<<searchTiddler>>>\n<$keyboard key=\"((input-tab-right))\" actions=<<set-next-input-tab>>>\n<$keyboard key=\"((input-tab-left))\" actions=<<set-previous-input-tab>> class=\"tc-create-wikitext-link\">\n<$transclude $variable=\"keyboard-driven-input\" tiddler=<<searchTiddler>> storeTitle=<<storeTitle>>\n\t\tselectionStateTitle=<<searchListState>> refreshTitle=<<refreshTitle>> type=\"search\" filterMinLength=\"1\"\n\t\ttag=\"input\" focus=\"true\" class=\"tc-popup-handle\" inputCancelActions=<<cancel-search-actions>>\n\t\tinputAcceptActions=<<add-link-actions>> placeholder={{$:/language/Search/Search}} default=\"\"\n\t\tconfigTiddlerFilter=\"[[$:/state/search/currentTab]!is[missing]get[text]] :else[{$:/config/SearchResults/Default}]\" />\n</$keyboard>\n</$keyboard>\n&#32;\n<$reveal tag=\"span\" state=<<storeTitle>> type=\"nomatch\" text=\"\">\n<<external-link>>\n&#32;\n<$button class=\"tc-btn-invisible tc-btn-mini\" style=\"width: auto; display: inline-block; background-colour: inherit;\">\n<<cancel-search-actions>><$set name=\"cssEscapedTitle\" value={{{ [<storyTiddler>escapecss[]] }}}><$action-sendmessage $message=\"tm-focus-selector\" $param=<<tf.get-focus-selector>>/></$set>\n{{$:/core/images/close-button}}\n</$button>\n</$reveal>\n</$vars>\n\n<$reveal tag=\"div\" state=<<storeTitle>> type=\"nomatch\" text=\"\">\n\n<$linkcatcher actions=<<add-link-actions>> to=<<linkTiddler>>>\n\n<$vars userInput={{{ [<storeTitle>get[text]] }}} configTiddler={{{ [[$:/state/search/currentTab]!is[missing]get[text]] :else[{$:/config/SearchResults/Default}] }}}>\n\n{{$:/core/ui/SearchResults}}\n\n</$vars>\n\n</$linkcatcher>\n\n</$reveal>\n\n</$vars>\n\n\\end\n\n<$transclude $variable=\"body\" config-title=<<qualify \"$:/state/Link/\">>/>\n"},"$:/core/ui/EditorToolbar/link":{"title":"$:/core/ui/EditorToolbar/link","tags":"$:/tags/EditorToolbar","icon":"$:/core/images/link","caption":"{{$:/language/Buttons/Link/Caption}}","description":"{{$:/language/Buttons/Link/Hint}}","condition":"[<targetTiddler>!has[type]] [<targetTiddler>get[type]prefix[text/vnd.tiddlywiki]]","button-classes":"tc-text-editor-toolbar-item-start-group","shortcuts":"((link))","dropdown":"$:/core/ui/EditorToolbar/link-dropdown","text":""},"$:/core/ui/EditorToolbar/linkify":{"title":"$:/core/ui/EditorToolbar/linkify","caption":"{{$:/language/Buttons/Linkify/Caption}}","condition":"[<targetTiddler>!has[type]] [<targetTiddler>get[type]prefix[text/vnd.tiddlywiki]]","description":"{{$:/language/Buttons/Linkify/Hint}}","icon":"$:/core/images/linkify","list-before":"$:/core/ui/EditorToolbar/mono-block","shortcuts":"((linkify))","tags":"$:/tags/EditorToolbar","text":"<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"[[\"\n\tsuffix=\"]]\"\n\ttrimSelection=\"yes\"\n/>\n"},"$:/core/ui/EditorToolbar/list-bullet":{"title":"$:/core/ui/EditorToolbar/list-bullet","tags":"$:/tags/EditorToolbar","icon":"$:/core/images/list-bullet","caption":"{{$:/language/Buttons/ListBullet/Caption}}","description":"{{$:/language/Buttons/ListBullet/Hint}}","condition":"[<targetTiddler>!has[type]] [<targetTiddler>get[type]prefix[text/vnd.tiddlywiki]]","shortcuts":"((list-bullet))","text":"<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"*\"\n\tcount=\"1\"\n/>\n"},"$:/core/ui/EditorToolbar/list-number":{"title":"$:/core/ui/EditorToolbar/list-number","tags":"$:/tags/EditorToolbar","icon":"$:/core/images/list-number","caption":"{{$:/language/Buttons/ListNumber/Caption}}","description":"{{$:/language/Buttons/ListNumber/Hint}}","condition":"[<targetTiddler>!has[type]] [<targetTiddler>get[type]prefix[text/vnd.tiddlywiki]]","shortcuts":"((list-number))","text":"<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"#\"\n\tcount=\"1\"\n/>\n"},"$:/core/ui/EditorToolbar/mono-block":{"title":"$:/core/ui/EditorToolbar/mono-block","tags":"$:/tags/EditorToolbar","icon":"$:/core/images/mono-block","caption":"{{$:/language/Buttons/MonoBlock/Caption}}","description":"{{$:/language/Buttons/MonoBlock/Hint}}","condition":"[<targetTiddler>!has[type]] [<targetTiddler>get[type]prefix[text/vnd.tiddlywiki]]","button-classes":"tc-text-editor-toolbar-item-start-group","shortcuts":"((mono-block))","text":"<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-lines\"\n\tprefix=\"\n```\"\n\tsuffix=\"```\"\n/>\n"},"$:/core/ui/EditorToolbar/mono-line":{"title":"$:/core/ui/EditorToolbar/mono-line","tags":"$:/tags/EditorToolbar","icon":"$:/core/images/mono-line","caption":"{{$:/language/Buttons/MonoLine/Caption}}","description":"{{$:/language/Buttons/MonoLine/Hint}}","condition":"[<targetTiddler>!has[type]] [<targetTiddler>get[type]prefix[text/vnd.tiddlywiki]]","shortcuts":"((mono-line))","text":"<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"`\"\n\tsuffix=\"`\"\n\ttrimSelection=\"yes\"\n/>\n"},"$:/core/ui/EditorToolbar/more-dropdown":{"title":"$:/core/ui/EditorToolbar/more-dropdown","text":"\\define config-title()\n$:/config/EditorToolbarButtons/Visibility/$(toolbarItem)$\n\\end\n\n\\define conditional-button()\n\\whitespace trim\n<$list filter={{$(toolbarItem)$!!condition}} variable=\"condition\">\n<$transclude tiddler=\"$:/core/ui/EditTemplate/body/toolbar/button\" mode=\"inline\"/>\n&#32;\n<$transclude tiddler=<<toolbarItem>> field=\"description\"/>\n</$list>\n\\end\n\\whitespace trim\n\n<div class=\"tc-text-editor-toolbar-more\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/EditorToolbar]!has[draft.of]] -[[$:/core/ui/EditorToolbar/more]]\">\n<$reveal type=\"match\" state=<<config-visibility-title>> text=\"hide\" tag=\"div\">\n<<conditional-button>>\n</$reveal>\n</$list>\n</div>\n"},"$:/core/ui/EditorToolbar/more":{"title":"$:/core/ui/EditorToolbar/more","tags":"$:/tags/EditorToolbar","icon":"$:/core/images/down-arrow","caption":"{{$:/language/Buttons/More/Caption}}","description":"{{$:/language/Buttons/More/Hint}}","condition":"[<targetTiddler>]","dropdown":"$:/core/ui/EditorToolbar/more-dropdown","text":""},"$:/core/ui/EditorToolbar/opacity-dropdown":{"title":"$:/core/ui/EditorToolbar/opacity-dropdown","text":"\\define lingo-base() $:/language/Buttons/Opacity/\n\n\\define toolbar-opacity-inner()\n<$button tag=\"a\" tooltip=\"\"\"$(opacity)$\"\"\">\n\n<$action-setfield\n\t$tiddler=\"$:/config/BitmapEditor/Opacity\"\n\t$value=\"$(opacity)$\"\n/>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n<div style=\"display: inline-block; vertical-align: middle; background-color: $(current-paint-colour)$; opacity: $(opacity)$; width: 1em; height: 1em; border-radius: 50%;\"/>\n\n<span style=\"margin-left: 8px;\">\n\n<$text text=\"\"\"$(opacity)$\"\"\"/>\n\n<$reveal state=\"$:/config/BitmapEditor/Opacity\" type=\"match\" text=\"\"\"$(opacity)$\"\"\" tag=\"span\">\n\n<$entity entity=\"&nbsp;\"/>\n\n<$entity entity=\"&#x2713;\"/>\n\n</$reveal>\n\n</span>\n\n</$button>\n\\end\n\n\\define toolbar-opacity()\n''<<lingo Hint>>''\n\n<$list filter={{$:/config/BitmapEditor/Opacities}} variable=\"opacity\">\n\n<<toolbar-opacity-inner>>\n\n</$list>\n\\end\n\n<$set name=\"current-paint-colour\" value={{$:/config/BitmapEditor/Colour}}>\n\n<$set name=\"current-opacity\" value={{$:/config/BitmapEditor/Opacity}}>\n\n<<toolbar-opacity>>\n\n</$set>\n\n</$set>\n"},"$:/core/ui/EditorToolbar/opacity":{"title":"$:/core/ui/EditorToolbar/opacity","tags":"$:/tags/EditorToolbar","icon":"$:/core/images/opacity","caption":"{{$:/language/Buttons/Opacity/Caption}}","description":"{{$:/language/Buttons/Opacity/Hint}}","condition":"[<targetTiddler>is[image]] -[<targetTiddler>type[image/svg+xml]]","dropdown":"$:/core/ui/EditorToolbar/opacity-dropdown","text":"<$text text={{$:/config/BitmapEditor/Opacity}}/>\n"},"$:/core/ui/EditorToolbar/paint-dropdown":{"title":"$:/core/ui/EditorToolbar/paint-dropdown","text":"''{{$:/language/Buttons/Paint/Hint}}''\n\n<$macrocall $name=\"colour-picker\" actions=\"\"\"\n\n<$action-setfield\n\t$tiddler=\"$:/config/BitmapEditor/Colour\"\n\t$value=<<colour-picker-value>>\n/>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n\"\"\"/>\n"},"$:/core/ui/EditorToolbar/paint":{"title":"$:/core/ui/EditorToolbar/paint","tags":"$:/tags/EditorToolbar","icon":"$:/core/images/paint","caption":"{{$:/language/Buttons/Paint/Caption}}","description":"{{$:/language/Buttons/Paint/Hint}}","condition":"[<targetTiddler>is[image]] -[<targetTiddler>type[image/svg+xml]]","dropdown":"$:/core/ui/EditorToolbar/paint-dropdown","text":"\\define toolbar-paint()\n<div style=\"display: inline-block; vertical-align: middle; background-color: $(colour-picker-value)$; width: 1em; height: 1em; border-radius: 50%;\"/>\n\\end\n\\whitespace trim\n<$set name=\"colour-picker-value\" value={{$:/config/BitmapEditor/Colour}}>\n<<toolbar-paint>>\n</$set>\n"},"$:/core/ui/EditorToolbar/picture-dropdown":{"title":"$:/core/ui/EditorToolbar/picture-dropdown","text":"\\define replacement-text()\n[img[$(imageTitle)$]]\n\\end\n\n''{{$:/language/Buttons/Picture/Hint}}''\n\n<$macrocall $name=\"image-picker\" actions=\"\"\"\n\n<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"replace-selection\"\n\ttext=<<replacement-text>>\n/>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n\"\"\"/>\n"},"$:/core/ui/EditorToolbar/picture":{"title":"$:/core/ui/EditorToolbar/picture","tags":"$:/tags/EditorToolbar","icon":"$:/core/images/picture","caption":"{{$:/language/Buttons/Picture/Caption}}","description":"{{$:/language/Buttons/Picture/Hint}}","condition":"[<targetTiddler>!has[type]] [<targetTiddler>get[type]prefix[text/vnd.tiddlywiki]]","shortcuts":"((picture))","dropdown":"$:/core/ui/EditorToolbar/picture-dropdown","text":""},"$:/core/ui/EditorToolbar/preview-type-dropdown":{"title":"$:/core/ui/EditorToolbar/preview-type-dropdown","text":"\\define preview-type-button()\n<$button tag=\"a\">\n\n<$action-setfield $tiddler=\"$:/state/editpreviewtype\" $value=\"$(previewType)$\"/>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n<$transclude tiddler=<<previewType>> field=\"caption\" mode=\"inline\">\n\n<$view tiddler=<<previewType>> field=\"title\" mode=\"inline\"/>\n\n</$transclude> \n\n<$reveal tag=\"span\" state=\"$:/state/editpreviewtype\" type=\"match\" text=<<previewType>> default=\"$:/core/ui/EditTemplate/body/preview/output\">\n\n<$entity entity=\"&nbsp;\"/>\n\n<$entity entity=\"&#x2713;\"/>\n\n</$reveal>\n\n</$button>\n\\end\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/EditPreview]!has[draft.of]]\" variable=\"previewType\">\n\n<<preview-type-button>>\n\n</$list>\n"},"$:/core/ui/EditorToolbar/preview-type":{"title":"$:/core/ui/EditorToolbar/preview-type","tags":"$:/tags/EditorToolbar","icon":"$:/core/images/chevron-down","caption":"{{$:/language/Buttons/PreviewType/Caption}}","description":"{{$:/language/Buttons/PreviewType/Hint}}","condition":"[all[shadows+tiddlers]tag[$:/tags/EditPreview]!has[draft.of]butfirst[]limit[1]]","button-classes":"tc-text-editor-toolbar-item-adjunct","dropdown":"$:/core/ui/EditorToolbar/preview-type-dropdown"},"$:/core/ui/EditorToolbar/preview":{"title":"$:/core/ui/EditorToolbar/preview","tags":"$:/tags/EditorToolbar","icon":"$:/core/images/preview-open","custom-icon":"yes","caption":"{{$:/language/Buttons/Preview/Caption}}","description":"{{$:/language/Buttons/Preview/Hint}}","condition":"[<targetTiddler>]","button-classes":"tc-text-editor-toolbar-item-start-group","shortcuts":"((preview))","text":"\\whitespace trim\n<span>\n\t<$transclude $tiddler={{{ [<edit-preview-state>match[yes]then[$:/core/images/preview-open]else[$:/core/images/preview-closed]] }}} />\n</span>\n<$action-setfield $tiddler=<<editPreviewStateTiddler>> $value={{{ [<editPreviewStateTiddler>get[text]toggle[yes],[no]] }}} />\n<$action-sendmessage $message=\"tm-edit-text-operation\" $param=\"focus-editor\"/>\n"},"$:/core/ui/EditorToolbar/quote":{"title":"$:/core/ui/EditorToolbar/quote","tags":"$:/tags/EditorToolbar","icon":"$:/core/images/quote","caption":"{{$:/language/Buttons/Quote/Caption}}","description":"{{$:/language/Buttons/Quote/Hint}}","condition":"[<targetTiddler>!has[type]] [<targetTiddler>get[type]prefix[text/vnd.tiddlywiki]]","shortcuts":"((quote))","text":"<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-lines\"\n\tprefix=\"\n<<<\"\n\tsuffix=\"<<<\"\n/>\n"},"$:/core/ui/EditorToolbar/rotate-left":{"title":"$:/core/ui/EditorToolbar/rotate-left","tags":"$:/tags/EditorToolbar","icon":"$:/core/images/rotate-left","caption":"{{$:/language/Buttons/RotateLeft/Caption}}","description":"{{$:/language/Buttons/RotateLeft/Hint}}","condition":"[<targetTiddler>is[image]] -[<targetTiddler>type[image/svg+xml]]","text":"<$action-sendmessage\n\t$message=\"tm-edit-bitmap-operation\"\n\t$param=\"rotate-left\"\n/>\n"},"$:/core/ui/EditorToolbar/size-dropdown":{"title":"$:/core/ui/EditorToolbar/size-dropdown","text":"\\define lingo-base() $:/language/Buttons/Size/\n\n\\define toolbar-button-size-preset(config-title)\n<$set name=\"width\" filter=\"$(sizePair)$ +[first[]]\">\n\n<$set name=\"height\" filter=\"$(sizePair)$ +[last[]]\">\n\n<$button tag=\"a\">\n\n<$action-setfield\n\t$tiddler=\"\"\"$config-title$/new-width\"\"\"\n\t$value=<<width>>\n/>\n\n<$action-setfield\n\t$tiddler=\"\"\"$config-title$/new-height\"\"\"\n\t$value=<<height>>\n/>\n\n<$action-deletetiddler\n\t$tiddler=\"\"\"$config-title$/presets-popup\"\"\"\n/>\n\n<$text text=<<width>>/> &times; <$text text=<<height>>/>\n\n</$button>\n\n</$set>\n\n</$set>\n\\end\n\n\\define toolbar-button-size(config-title)\n\\whitespace trim\n''{{$:/language/Buttons/Size/Hint}}''\n\n<<lingo Caption/Width>>&#32;<$edit-text tag=\"input\" tiddler=\"\"\"$config-title$/new-width\"\"\" default=<<tv-bitmap-editor-width>> focus=\"true\" size=\"8\"/>\n&#32;\n<<lingo Caption/Height>>&#32;<$edit-text tag=\"input\" tiddler=\"\"\"$config-title$/new-height\"\"\" default=<<tv-bitmap-editor-height>> size=\"8\"/>\n&#32;\n<$button popup=\"\"\"$config-title$/presets-popup\"\"\" class=\"tc-btn-invisible tc-popup-keep\" style=\"width: auto; display: inline-block; background-colour: inherit;\" selectedClass=\"tc-selected\">\n{{$:/core/images/down-arrow}}\n</$button>\n\n<$reveal tag=\"span\" state=\"\"\"$config-title$/presets-popup\"\"\" type=\"popup\" position=\"belowleft\" animate=\"yes\">\n\n<div class=\"tc-drop-down tc-popup-keep\">\n\n<$list filter={{$:/config/BitmapEditor/ImageSizes}} variable=\"sizePair\">\n\n<$macrocall $name=\"toolbar-button-size-preset\" config-title=\"$config-title$\"/>\n\n</$list>\n\n</div>\n\n</$reveal>\n\n<$button>\n<$action-sendmessage\n\t$message=\"tm-edit-bitmap-operation\"\n\t$param=\"resize\"\n\twidth={{$config-title$/new-width}}\n\theight={{$config-title$/new-height}}\n/>\n<$action-deletetiddler\n\t$tiddler=\"\"\"$config-title$/new-width\"\"\"\n/>\n<$action-deletetiddler\n\t$tiddler=\"\"\"$config-title$/new-height\"\"\"\n/>\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n<<lingo Caption/Resize>>\n</$button>\n\\end\n\n<$macrocall $name=\"toolbar-button-size\" config-title=<<qualify \"$:/state/Size/\">>/>\n"},"$:/core/ui/EditorToolbar/size":{"title":"$:/core/ui/EditorToolbar/size","tags":"$:/tags/EditorToolbar","icon":"$:/core/images/size","caption":"{{$:/language/Buttons/Size/Caption}}","description":"{{$:/language/Buttons/Size/Hint}}","condition":"[<targetTiddler>is[image]] -[<targetTiddler>type[image/svg+xml]]","dropdown":"$:/core/ui/EditorToolbar/size-dropdown","text":""},"$:/core/ui/EditorToolbar/StampDropdown/ItemTemplate":{"title":"$:/core/ui/EditorToolbar/StampDropdown/ItemTemplate","text":"<$linkcatcher actions=\"\"\"\n\n<$list filter=\"[<modifier>!match[ctrl]]\" variable=\"ignore\">\n\n<$list filter=\"[<currentTiddler>addsuffix[/prefix]!is[tiddler]!is[shadow]removesuffix[/prefix]addsuffix[/suffix]!is[tiddler]!is[shadow]]\" variable=\"ignore\">\n\n<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"replace-selection\"\n\ttext={{{ [<currentTiddler>get[text]] }}}\n/>\n\n</$list>\n\n\n<$list filter=\"[<currentTiddler>addsuffix[/prefix]] [<currentTiddler>addsuffix[/suffix]] +[is[shadow]] :else[is[tiddler]] +[limit[1]]\" variable=\"ignore\">\n\n<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix={{{ [<currentTiddler>addsuffix[/prefix]get[text]] }}}\n\tsuffix={{{ [<currentTiddler>addsuffix[/suffix]get[text]] }}}\n/>\n\n</$list>\n\n</$list>\n\n<$list filter=\"[<modifier>match[ctrl]]\" variable=\"ignore\">\n\n<$action-sendmessage $message=\"tm-edit-tiddler\"/>\n\n</$list>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n\"\"\">\n\n<$link tooltip={{{ [<currentTiddler>get[description]] }}}>\n\n<$transclude tiddler=<<currentTiddler>> field=\"caption\" mode=\"inline\">\n\n<$view tiddler=<<currentTiddler>> field=\"title\" />\n\n</$transclude>\n\n</$link>\n\n</$linkcatcher>\n"},"$:/core/ui/EditorToolbar/stamp-dropdown":{"title":"$:/core/ui/EditorToolbar/stamp-dropdown","text":"<$macrocall $name=\"list-tagged-draggable\" tag=\"$:/tags/TextEditor/Snippet\" subFilter=\"!is[draft]\" itemTemplate=\"$:/core/ui/EditorToolbar/StampDropdown/ItemTemplate\"/>\n\n----\n\n<$button tag=\"a\">\n\n<$action-sendmessage\n\t$message=\"tm-new-tiddler\"\n\ttags=\"$:/tags/TextEditor/Snippet\"\n\tcaption={{$:/language/Buttons/Stamp/New/Title}}\n\ttext={{$:/language/Buttons/Stamp/New/Text}}\n/>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n<em>\n\n<$text text={{$:/language/Buttons/Stamp/Caption/New}}/>\n\n</em>\n\n</$button>\n"},"$:/core/ui/EditorToolbar/stamp":{"title":"$:/core/ui/EditorToolbar/stamp","tags":"$:/tags/EditorToolbar","icon":"$:/core/images/stamp","caption":"{{$:/language/Buttons/Stamp/Caption}}","description":"{{$:/language/Buttons/Stamp/Hint}}","condition":"[<targetTiddler>type[]] [<targetTiddler>get[type]prefix[text/]] [<targetTiddler>get[type]match[application/javascript]] [<targetTiddler>get[type]match[application/json]] [<targetTiddler>get[type]match[application/x-tiddler-dictionary]] [<targetTiddler>get[type]match[image/svg+xml]] +[first[]]","shortcuts":"((stamp))","dropdown":"$:/core/ui/EditorToolbar/stamp-dropdown","button-classes":"tc-editortoolbar-stamp-button","text":""},"$:/core/ui/EditorToolbar/strikethrough":{"title":"$:/core/ui/EditorToolbar/strikethrough","tags":"$:/tags/EditorToolbar","icon":"$:/core/images/strikethrough","caption":"{{$:/language/Buttons/Strikethrough/Caption}}","description":"{{$:/language/Buttons/Strikethrough/Hint}}","condition":"[<targetTiddler>!has[type]] [<targetTiddler>get[type]prefix[text/vnd.tiddlywiki]]","shortcuts":"((strikethrough))","text":"<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"~~\"\n\tsuffix=\"~~\"\n\ttrimSelection=\"yes\"\n/>\n"},"$:/core/ui/EditorToolbar/subscript":{"title":"$:/core/ui/EditorToolbar/subscript","tags":"$:/tags/EditorToolbar","icon":"$:/core/images/subscript","caption":"{{$:/language/Buttons/Subscript/Caption}}","description":"{{$:/language/Buttons/Subscript/Hint}}","condition":"[<targetTiddler>!has[type]] [<targetTiddler>get[type]prefix[text/vnd.tiddlywiki]]","shortcuts":"((subscript))","text":"<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\",,\"\n\tsuffix=\",,\"\n\ttrimSelection=\"yes\"\n/>\n"},"$:/core/ui/EditorToolbar/superscript":{"title":"$:/core/ui/EditorToolbar/superscript","tags":"$:/tags/EditorToolbar","icon":"$:/core/images/superscript","caption":"{{$:/language/Buttons/Superscript/Caption}}","description":"{{$:/language/Buttons/Superscript/Hint}}","condition":"[<targetTiddler>!has[type]] [<targetTiddler>get[type]prefix[text/vnd.tiddlywiki]]","shortcuts":"((superscript))","text":"<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"^^\"\n\tsuffix=\"^^\"\n\ttrimSelection=\"yes\"\n/>\n"},"$:/core/ui/EditorToolbar/transcludify":{"title":"$:/core/ui/EditorToolbar/transcludify","caption":"{{$:/language/Buttons/Transcludify/Caption}}","condition":"[<targetTiddler>!has[type]] [<targetTiddler>get[type]prefix[text/vnd.tiddlywiki]]","description":"{{$:/language/Buttons/Transcludify/Hint}}","icon":"$:/core/images/transcludify","list-before":"$:/core/ui/EditorToolbar/mono-block","shortcuts":"((transcludify))","tags":"$:/tags/EditorToolbar","text":"<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"{{\"\n\tsuffix=\"}}\"\n\ttrimSelection=\"yes\"\n/>\n"},"$:/core/ui/EditorToolbar/underline":{"title":"$:/core/ui/EditorToolbar/underline","tags":"$:/tags/EditorToolbar","icon":"$:/core/images/underline","caption":"{{$:/language/Buttons/Underline/Caption}}","description":"{{$:/language/Buttons/Underline/Hint}}","condition":"[<targetTiddler>!has[type]] [<targetTiddler>get[type]prefix[text/vnd.tiddlywiki]]","shortcuts":"((underline))","text":"<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"__\"\n\tsuffix=\"__\"\n\ttrimSelection=\"yes\"\n/>\n"},"$:/core/ui/ExportTiddlyWikiCore":{"title":"$:/core/ui/ExportTiddlyWikiCore","text":"\\define jsFileName() tiddlywikicore-$(version)$.js\n\\define noExportMsg()\nIt appears that you have a wiki with an external ~TiddlyWiki core. The export action cannot be performed.\n<p>You will need to view the page source in your browser. Then go to the very bottom the the source, find the last `<script>` \nelement, and right-click its `src` URI. Save the link as ''$(jsFileName)$''</p>\n\\end\n\n''For advanced users''\n\nExport the ~TiddlyWiki core ~JavaScript code for running with external ~JavaScript:\n\n<$button tooltip=\"Export the ~TiddlyWiki core code for running with external ~JavaScript\" aria-label=\"export TiddlyWiki core\" class=\"tc-btn-big-green\">\n<$list filter=\"[[$:/boot/boot.js]is[missing]]\" variable=\"ignore\" emptyMessage=\"\"\"<$action-sendmessage $message=\"tm-download-file\" $param=\"$:/core/templates/tiddlywiki5.js\" filename=<<jsFileName>>/>\"\"\" >\n<$action-setfield $tiddler=<<qualify \"$:/temp/alert\">> text=<<noExportMsg>> subtitle=\"Export ~TiddllyWiki Core\"/>\n<$action-sendmessage $message=\"tm-modal\" $param=<<qualify \"$:/temp/alert\">>/>\n</$list>\n{{$:/core/images/download-button}} Download ~TiddlyWiki core\n</$button>\n\n[[Further information|https://tiddlywiki.com/#Using%20the%20external%20JavaScript%20template]]\n"},"$:/core/Filters/AllTags":{"title":"$:/core/Filters/AllTags","tags":"$:/tags/Filter","filter":"[tags[]!is[system]sort[title]]","description":"{{$:/language/Filters/AllTags}}","text":""},"$:/core/Filters/AllTiddlers":{"title":"$:/core/Filters/AllTiddlers","tags":"$:/tags/Filter","filter":"[!is[system]sort[title]]","description":"{{$:/language/Filters/AllTiddlers}}","text":""},"$:/core/Filters/Drafts":{"title":"$:/core/Filters/Drafts","tags":"$:/tags/Filter","filter":"[has[draft.of]sort[title]]","description":"{{$:/language/Filters/Drafts}}","text":""},"$:/core/Filters/Missing":{"title":"$:/core/Filters/Missing","tags":"$:/tags/Filter","filter":"[all[missing]sort[title]]","description":"{{$:/language/Filters/Missing}}","text":""},"$:/core/Filters/Orphans":{"title":"$:/core/Filters/Orphans","tags":"$:/tags/Filter","filter":"[all[orphans]sort[title]]","description":"{{$:/language/Filters/Orphans}}","text":""},"$:/core/Filters/OverriddenShadowTiddlers":{"title":"$:/core/Filters/OverriddenShadowTiddlers","tags":"$:/tags/Filter","filter":"[is[shadow]]","description":"{{$:/language/Filters/OverriddenShadowTiddlers}}","text":""},"$:/core/Filters/RecentSystemTiddlers":{"title":"$:/core/Filters/RecentSystemTiddlers","tags":"$:/tags/Filter","filter":"[has[modified]!sort[modified]limit[50]]","description":"{{$:/language/Filters/RecentSystemTiddlers}}","text":""},"$:/core/Filters/RecentTiddlers":{"title":"$:/core/Filters/RecentTiddlers","tags":"$:/tags/Filter","filter":"[!is[system]has[modified]!sort[modified]limit[50]]","description":"{{$:/language/Filters/RecentTiddlers}}","text":""},"$:/core/Filters/SessionTiddlers":{"title":"$:/core/Filters/SessionTiddlers","tags":"$:/tags/Filter","filter":"[haschanged[]]","description":"{{$:/language/Filters/SessionTiddlers}}","text":""},"$:/core/Filters/ShadowTiddlers":{"title":"$:/core/Filters/ShadowTiddlers","tags":"$:/tags/Filter","filter":"[all[shadows]sort[title]]","description":"{{$:/language/Filters/ShadowTiddlers}}","text":""},"$:/core/Filters/StoryList":{"title":"$:/core/Filters/StoryList","tags":"$:/tags/Filter","filter":"[list[$:/StoryList]] -$:/AdvancedSearch","description":"{{$:/language/Filters/StoryList}}","text":""},"$:/core/Filters/SystemTags":{"title":"$:/core/Filters/SystemTags","tags":"$:/tags/Filter","filter":"[all[shadows+tiddlers]tags[]is[system]sort[title]]","description":"{{$:/language/Filters/SystemTags}}","text":""},"$:/core/Filters/SystemTiddlers":{"title":"$:/core/Filters/SystemTiddlers","tags":"$:/tags/Filter","filter":"[is[system]sort[title]]","description":"{{$:/language/Filters/SystemTiddlers}}","text":""},"$:/core/Filters/TypedTiddlers":{"title":"$:/core/Filters/TypedTiddlers","tags":"$:/tags/Filter","filter":"[!is[system]has[type]each[type]sort[type]] -[type[text/vnd.tiddlywiki]]","description":"{{$:/language/Filters/TypedTiddlers}}","text":""},"$:/core/ui/ImportListing":{"title":"$:/core/ui/ImportListing","text":"\\define lingo-base() $:/language/Import/\n\n\\define messageField() message-$(payloadTiddler)$\n\n\\define payloadTitleFilter() [<currentTiddler>get<renameField>minlength[1]else<payloadTiddler>]\n\n\\define overWriteWarning()\n\\whitespace trim\n<$list filter=\"[<currentTiddler>!has<suppressedField>]\">\n<$text text={{{[subfilter<payloadTitleFilter>!is[tiddler]then[]] ~[<lingo-base>addsuffix[Listing/Rename/OverwriteWarning]get[text]]}}}/>\n</$list>\n\\end\n\n\\define selectionInfo()\n\\whitespace trim\n<$set name=\"escUnselected\" value={{{[{$:/language/Import/Upgrader/Tiddler/Unselected}escaperegexp[]addprefix[(?g)]]}}}>\n\t<$list filter=\"[all[current]get<messageField>regexp<escUnselected>]\" variable=\"ignore\">\n\t\t<$text text={{{[all[current]get<selectionField>match[checked]then{$:/language/Import/Upgrader/Tiddler/Selected}else[]]}}}/>\n\t</$list>\n</$set>\n\\end\n\n\\define libraryInfo()\n\\whitespace trim\n<$set name=\"escUnselected\" value={{{[{$:/language/Import/Upgrader/Tiddler/Unselected}escaperegexp[]addprefix[(?g)]]}}}>\n\t<$list filter=\"[all[current]get<messageField>!regexp<escUnselected>]\" variable=\"ignore\">\n\t\t<$text text={{{[all[current]get<messageField>]}}}/>\n\t</$list>\n</$set>\n\\end\n\n\\define selectionField() selection-$(payloadTiddler)$\n\n\\define renameField() rename-$(payloadTiddler)$\n\n\\define suppressedField() suppressed-$(payloadTiddler)$\n\n\\define newImportTitleTiddler() $:/temp/NewImportTitle-$(payloadTiddler)$\n\n\\define previewPopupState() $(currentTiddler)$!!popup-$(payloadTiddler)$\n\n\\define renameFieldState() $(currentTiddler)$!!state-rename-$(payloadTiddler)$\n\n\\define select-all-actions()\n\\whitespace trim\n<$list filter=\"[all[current]plugintiddlers[]sort[title]]\" variable=\"payloadTiddler\">\n<$action-setfield $field={{{ [<payloadTiddler>addprefix[selection-]] }}} $value={{$:/state/import/select-all}}/>\n</$list>\n\\end\n\n\\whitespace trim\n<table class=\"tc-import-table\">\n<tbody>\n<tr>\n<th align=\"left\">\n<$checkbox tiddler=\"$:/state/import/select-all\" field=\"text\" checked=\"checked\" unchecked=\"unchecked\" default=\"checked\" actions=<<select-all-actions>>>\n&#32;\n<<lingo Listing/Select/Caption>>\n</$checkbox>\n</th>\n<th>\n<<lingo Listing/Title/Caption>>\n</th>\n<th>\n<<lingo Listing/Status/Caption>>\n</th>\n</tr>\n<$list filter=\"[all[current]plugintiddlers[]sort[title]]\" variable=\"payloadTiddler\">\n<tr class={{{[<currentTiddler>has<suppressedField>then[tc-row-disabled]] ~[subfilter<payloadTitleFilter>is[tiddler]then[tc-row-warning]] }}}>\n<td>\n<$checkbox field=<<selectionField>> checked=\"checked\" unchecked=\"unchecked\" default=\"checked\" disabled={{{[<currentTiddler>has<suppressedField>then[yes]else[no]]}}}/>\n</td>\n<td>\n<$reveal type=\"nomatch\" state=<<renameFieldState>> text=\"yes\" tag=\"div\">\n<$reveal type=\"nomatch\" state=<<previewPopupState>> text=\"yes\" tag=\"div\" class=\"tc-flex\">\n<$button class=\"tc-btn-invisible tc-btn-dropdown tc-flex-grow-1 tc-word-break\" set=<<previewPopupState>> setTo=\"yes\" disabled={{{[<currentTiddler>has<suppressedField>then[yes]else[no]]}}}>\n<span class=\"tc-small-gap-right\">{{$:/core/images/right-arrow}}</span><$text text={{{[subfilter<payloadTitleFilter>]}}}/>\n</$button>\n<$list filter=\"[<currentTiddler>!has<suppressedField>]\"><$button class=\"tc-btn-invisible\" set=<<renameFieldState>> setTo=\"yes\" tooltip={{{[<lingo-base>addsuffix[Listing/Rename/Tooltip]get[text]]}}}>{{$:/core/images/edit-button}}</$button></$list>\n</$reveal>\n<$reveal type=\"match\" state=<<previewPopupState>> text=\"yes\" tag=\"div\">\n<$button class=\"tc-btn-invisible tc-btn-dropdown\" set=<<previewPopupState>> setTo=\"no\">\n<span class=\"tc-small-gap-right\">{{$:/core/images/down-arrow}}</span><$text text={{{[subfilter<payloadTitleFilter>]}}}/>\n</$button>\n</$reveal>\n</$reveal>\n<$reveal type=\"match\" state=<<renameFieldState>> text=\"yes\" tag=\"div\">\n<$text text={{{[<lingo-base>addsuffix[Listing/Rename/Prompt]get[text]]}}}/>\n</$reveal>\n</td>\n<td>\n<<selectionInfo>>\n&#32;\n<<libraryInfo>>\n&#32;\n<<overWriteWarning>>\n</td>\n</tr>\n<$reveal type=\"match\" state=<<renameFieldState>> text=\"yes\" tag=\"tr\">\n\t<td colspan=\"3\">\n\t\t<div class=\"tc-flex\">\n\t\t\t<$edit-text tiddler=<<newImportTitleTiddler>>  default={{{[subfilter<payloadTitleFilter>]}}} tag=\"input\" class=\"tc-import-rename tc-flex-grow-1\"/>\n\t\t\t<span class=\"tc-small-gap-left\">\n\t\t\t\t<$button  class=\"tc-btn-invisible\" set=<<renameFieldState>> setTo=\"no\" tooltip={{{[<lingo-base>addsuffix[Listing/Rename/CancelRename]get[text]]}}}>\n\t\t\t\t\t{{$:/core/images/close-button}}\n\t\t\t\t\t<$action-deletetiddler $tiddler=<<newImportTitleTiddler>>/>\n\t\t\t\t</$button>\n\t\t\t\t<span class=\"tc-small-gap-right\"/>\n\t\t\t</span>\n\t\t\t<$button  class=\"tc-btn-invisible\" set=<<renameFieldState>> setTo=\"no\" tooltip={{{[<lingo-base>addsuffix[Listing/Rename/ConfirmRename]get[text]]}}}>\n\t\t\t\t{{$:/core/images/done-button}}\n\t\t\t\t<$action-setfield $field=<<renameField>> $value={{{[<newImportTitleTiddler>get[text]minlength[1]else<payloadTiddler>]}}} />\n\t\t\t\t<$action-deletetiddler $tiddler=<<newImportTitleTiddler>>/>\n\t\t\t</$button>\n\t\t</div>\n\t</td>\n</$reveal>\n<$reveal type=\"match\" text=\"yes\" state=<<previewPopupState>> tag=\"tr\">\n<td colspan=\"3\">\n<$list filter=\"[{$:/state/importpreviewtype}has[text]]\" variable=\"listItem\" emptyMessage={{$:/core/ui/ImportPreviews/Text}}>\n\t<div>\n\t\t<$transclude tiddler={{$:/state/importpreviewtype}}/>\n\t</div>\n</$list>\n</td>\n</$reveal>\n</$list>\n</tbody>\n</table>\n"},"$:/core/ui/ImportPreviews/Diff":{"title":"$:/core/ui/ImportPreviews/Diff","tags":"$:/tags/ImportPreview","caption":"{{$:/language/Import/Listing/Preview/Diff}}","text":"<$macrocall $name=\"compareTiddlerText\" sourceTiddlerTitle=<<payloadTiddler>> destTiddlerTitle=<<currentTiddler>> destSubTiddlerTitle=<<payloadTiddler>>/>\n"},"$:/core/ui/ImportPreviews/DiffFields":{"title":"$:/core/ui/ImportPreviews/DiffFields","tags":"$:/tags/ImportPreview","caption":"{{$:/language/Import/Listing/Preview/DiffFields}}","text":"<$macrocall $name=\"compareTiddlers\" sourceTiddlerTitle=<<payloadTiddler>> destTiddlerTitle=<<currentTiddler>> destSubTiddlerTitle=<<payloadTiddler>> exclude=\"text\"/>\n"},"$:/core/ui/ImportPreviews/Fields":{"title":"$:/core/ui/ImportPreviews/Fields","tags":"$:/tags/ImportPreview","caption":"{{$:/language/Import/Listing/Preview/Fields}}","text":"\\whitespace trim\n<table class=\"tc-view-field-table\">\n<tbody>\n<$list filter=\"[<payloadTiddler>subtiddlerfields<currentTiddler>sort[]] -text\" variable=\"fieldName\">\n<tr class=\"tc-view-field\">\n<td class=\"tc-view-field-name\">\n<$text text=<<fieldName>>/>\n</td>\n<td class=\"tc-view-field-value\">\n<$view field=<<fieldName>> tiddler=<<currentTiddler>> subtiddler=<<payloadTiddler>>/>\n</td>\n</tr>\n</$list>\n</tbody>\n</table>\n"},"$:/core/ui/ImportPreviews/Text":{"title":"$:/core/ui/ImportPreviews/Text","tags":"$:/tags/ImportPreview","caption":"{{$:/language/Import/Listing/Preview/Text}}","code-body":"yes","text":"<$transclude tiddler=<<currentTiddler>> subtiddler=<<payloadTiddler>> mode=\"block\"/>\n"},"$:/core/ui/ImportPreviews/TextRaw":{"title":"$:/core/ui/ImportPreviews/TextRaw","tags":"$:/tags/ImportPreview","caption":"{{$:/language/Import/Listing/Preview/TextRaw}}","text":"<pre><code><$view tiddler=<<currentTiddler>> subtiddler=<<payloadTiddler>> /></code></pre>"},"$:/core/ui/KeyboardShortcuts/advanced-search":{"title":"$:/core/ui/KeyboardShortcuts/advanced-search","tags":"$:/tags/KeyboardShortcut","key":"((advanced-search))","text":"\\whitespace trim\n<$navigator story=\"$:/StoryList\" history=\"$:/HistoryList\">\n<$action-navigate $to=\"$:/AdvancedSearch\" $scroll=\"yes\"/>\n<$action-sendmessage $message=\"tm-focus-selector\" $param=\"\"\"[data-tiddler-title=\"$:/AdvancedSearch\"] .tc-search input\"\"\" preventScroll=\"true\"/>\n</$navigator>\n"},"$:/core/ui/KeyboardShortcuts/change-sidebar-layout":{"title":"$:/core/ui/KeyboardShortcuts/change-sidebar-layout","tags":"$:/tags/KeyboardShortcut","key":"((change-sidebar-layout))","text":"\\whitespace trim\n<$list\n\tfilter=\"[{$:/themes/tiddlywiki/vanilla/options/sidebarlayout}match[fixed-fluid]]\"\n\temptyMessage=\"<$action-setfield $tiddler='$:/themes/tiddlywiki/vanilla/options/sidebarlayout' text='fixed-fluid'/>\">\n<$action-setfield $tiddler=\"$:/themes/tiddlywiki/vanilla/options/sidebarlayout\" text=\"fluid-fixed\"/>\n</$list>\n"},"$:/core/ui/KeyboardShortcuts/new-image":{"title":"$:/core/ui/KeyboardShortcuts/new-image","tags":"$:/tags/KeyboardShortcut","key":"((new-image))","text":"\\whitespace trim\n<$navigator story=\"$:/StoryList\" history=\"$:/HistoryList\" openLinkFromInsideRiver={{$:/config/Navigation/openLinkFromInsideRiver}} openLinkFromOutsideRiver={{$:/config/Navigation/openLinkFromOutsideRiver}} relinkOnRename={{$:/config/RelinkOnRename}}>\n{{$:/core/ui/Actions/new-image}}\n</$navigator>\n"},"$:/core/ui/KeyboardShortcuts/new-journal":{"title":"$:/core/ui/KeyboardShortcuts/new-journal","tags":"$:/tags/KeyboardShortcut","key":"((new-journal))","text":"\\whitespace trim\n<$navigator story=\"$:/StoryList\" history=\"$:/HistoryList\" openLinkFromInsideRiver={{$:/config/Navigation/openLinkFromInsideRiver}} openLinkFromOutsideRiver={{$:/config/Navigation/openLinkFromOutsideRiver}} relinkOnRename={{$:/config/RelinkOnRename}}>\n{{$:/core/ui/Actions/new-journal}}\n</$navigator>\n"},"$:/core/ui/KeyboardShortcuts/new-tiddler":{"title":"$:/core/ui/KeyboardShortcuts/new-tiddler","tags":"$:/tags/KeyboardShortcut","key":"((new-tiddler))","text":"\\whitespace trim\n<$navigator story=\"$:/StoryList\" history=\"$:/HistoryList\" openLinkFromInsideRiver={{$:/config/Navigation/openLinkFromInsideRiver}} openLinkFromOutsideRiver={{$:/config/Navigation/openLinkFromOutsideRiver}} relinkOnRename={{$:/config/RelinkOnRename}}>\n{{$:/core/ui/Actions/new-tiddler}}\n</$navigator>\n"},"$:/core/ui/KeyboardShortcuts/open-control-panel":{"title":"$:/core/ui/KeyboardShortcuts/open-control-panel","tags":"$:/tags/KeyboardShortcut","key":"((open-control-panel))","text":"\\whitespace trim\n<$navigator story=\"$:/StoryList\" history=\"$:/HistoryList\">\n<$action-navigate $to=\"$:/ControlPanel\" $scroll=\"yes\"/>\n</$navigator>\n"},"$:/core/ui/KeyboardShortcuts/refresh":{"title":"$:/core/ui/KeyboardShortcuts/refresh","tags":"$:/tags/KeyboardShortcut","key":"((refresh))","text":"<$action-sendmessage $message=\"tm-browser-refresh\"/>\n"},"$:/core/ui/KeyboardShortcuts/save-wiki":{"title":"$:/core/ui/KeyboardShortcuts/save-wiki","tags":"$:/tags/KeyboardShortcut","key":"((save-wiki))","text":"\\whitespace trim\n<$wikify name=\"site-title\" text={{$:/config/SaveWikiButton/Filename}}>\n<$action-sendmessage $message=\"tm-save-wiki\" $param={{$:/config/SaveWikiButton/Template}} filename=<<site-title>>/>\n</$wikify>\n"},"$:/core/ui/KeyboardShortcuts/sidebar-search":{"title":"$:/core/ui/KeyboardShortcuts/sidebar-search","tags":"$:/tags/KeyboardShortcut","key":"((sidebar-search))","text":"<$action-sendmessage $message=\"tm-focus-selector\" $param=\".tc-search input\"/>\n"},"$:/core/ui/KeyboardShortcuts/switcher":{"title":"$:/core/ui/KeyboardShortcuts/switcher","tags":"$:/tags/KeyboardShortcut","key":"((layout-switcher))","text":"<$action-sendmessage $message=\"tm-show-switcher\" switch=\"layout\"/>"},"$:/core/ui/KeyboardShortcuts/toggle-sidebar":{"title":"$:/core/ui/KeyboardShortcuts/toggle-sidebar","tags":"$:/tags/KeyboardShortcut","key":"((toggle-sidebar))","text":"\\whitespace trim\n<$list\n\tfilter=\"[[$:/state/sidebar]is[missing]] [{$:/state/sidebar}removeprefix[yes]]\"\n\temptyMessage=\"<$action-setfield $tiddler='$:/state/sidebar' text='yes'/>\">\n<$action-setfield $tiddler=\"$:/state/sidebar\" text=\"no\"/>\n</$list>\n"},"$:/snippets/LayoutSwitcher":{"title":"$:/snippets/LayoutSwitcher","tags":"$:/tags/ControlPanel/Appearance","caption":"{{$:/language/ControlPanel/LayoutSwitcher/Caption}}","text":"\\whitespace trim\n<$linkcatcher to=\"$:/layout\">\n<div class=\"tc-chooser\">\n<$list filter=\"[all[tiddlers+shadows]tag[$:/tags/Layout]] [[$:/core/ui/PageTemplate]] +[!is[draft]sort[name]]\">\n<$list\n\tfilter=\"[{$:/layout}!has[text]]\"\n\tvariable=\"ignore\"\n\temptyMessage=\"\"\"\\whitespace trim\n\t\t<$set name=\"cls\" filter=\"[all[current]field:title{$:/layout}]\" value=\"tc-chooser-item tc-chosen\" emptyValue=\"tc-chooser-item\">\n\t\t<div class=<<cls>>>\n\t\t<$link to={{!!title}}>\n\t\t''<$transclude tiddler={{{ [<currentTiddler>get[icon]] }}}/><$transclude field=\"name\"/>''&#32;-&#32;<$transclude field=\"description\"/>\n\t\t</$link></div></$set>\n\"\"\">\n<$set name=\"cls\" filter=\"[all[current]field:title[$:/core/ui/PageTemplate]]\" value=\"tc-chooser-item tc-chosen\" emptyValue=\"tc-chooser-item\">\n<div class=<<cls>>>\n<$link to={{!!title}}>\n''<$transclude tiddler={{{ [<currentTiddler>get[icon]] }}}/><$transclude field=\"name\"/>''&#32;-&#32;<$transclude field=\"description\"/>\n</$link>\n</div>\n</$set>\n</$list>\n</$list>\n</div>\n</$linkcatcher>\n"},"$:/core/ui/ListItemTemplate":{"title":"$:/core/ui/ListItemTemplate","text":"<div class=\"tc-menu-list-item\"><$link /></div>"},"$:/snippets/ListTaggedCascade":{"title":"$:/snippets/ListTaggedCascade","text":"\\whitespace trim\n{{||$:/language/ControlPanel/Cascades/TagPrompt}}\n\n<ol>\n<$list filter=\"[all[shadows+tiddlers]tag<currentTiddler>]\">\n<li>\n<div>\n<$link><$text text=<<currentTiddler>>/></$link>\n</div>\n<$codeblock code={{!!text}}/>\n</li>\n</$list>\n</ol>\n"},"$:/Manager/ItemMain/Fields":{"title":"$:/Manager/ItemMain/Fields","tags":"$:/tags/Manager/ItemMain","caption":"{{$:/language/Manager/Item/Fields}}","text":"\\whitespace trim\n<table>\n<tbody>\n<$list filter=\"[all[current]fields[]sort[title]] -text\" template=\"$:/core/ui/TiddlerFieldTemplate\" variable=\"listItem\"/>\n</tbody>\n</table>\n"},"$:/Manager/ItemMain/RawText":{"title":"$:/Manager/ItemMain/RawText","tags":"$:/tags/Manager/ItemMain","caption":"{{$:/language/Manager/Item/RawText}}","text":"<pre><code><$view/></code></pre>\n"},"$:/Manager/ItemMain/WikifiedText":{"title":"$:/Manager/ItemMain/WikifiedText","tags":"$:/tags/Manager/ItemMain","caption":"{{$:/language/Manager/Item/WikifiedText}}","text":"<$transclude mode=\"block\"/>\n"},"$:/Manager/ItemSidebar/Colour":{"title":"$:/Manager/ItemSidebar/Colour","tags":"$:/tags/Manager/ItemSidebar","caption":"{{$:/language/Manager/Item/Colour}}","text":"\\define swatch-styles()\nheight: 1em;\nbackground-color: $(colour)$\n\\end\n\n\\whitespace trim\n<$vars colour={{!!color}}>\n<p style=<<swatch-styles>>/>\n</$vars>\n<p>\n<$edit-text field=\"color\" tag=\"input\" type=\"color\"/>\n&#32;/&#32;\n<$edit-text field=\"color\" tag=\"input\" type=\"text\" size=\"9\"/>\n</p>\n"},"$:/Manager/ItemSidebar/Icon":{"title":"$:/Manager/ItemSidebar/Icon","tags":"$:/tags/Manager/ItemSidebar","caption":"{{$:/language/Manager/Item/Icon}}","text":"\\whitespace trim\n<p>\n<div class=\"tc-manager-icon-editor\">\n<$button popup=<<qualify \"$:/state/popup/image-picker\">> class=\"tc-btn-invisible\">\n<$transclude tiddler={{!!icon}}>\n{{$:/language/Manager/Item/Icon/None}}\n</$transclude>\n</$button>\n<div class=\"tc-block-dropdown-wrapper\" style=\"position: static;\">\n<$reveal state=<<qualify \"$:/state/popup/image-picker\">> type=\"nomatch\" text=\"\" default=\"\" tag=\"div\" class=\"tc-popup\">\n<div class=\"tc-block-dropdown tc-popup-keep\" style=\"width: 80%; left: 10%; right: 10%; padding: 0.5em;\">\n<$macrocall\n\t$name=\"image-picker-include-tagged-images\"\n\tactions=\"<$action-setfield $field='icon' $value=<<imageTitle>>/><$action-deletetiddler $tiddler=<<qualify '$:/state/popup/image-picker'>>/>\"/>\n</div>\n</$reveal>\n</div>\n</div>\n</p>\n"},"$:/Manager/ItemSidebar/Tags":{"title":"$:/Manager/ItemSidebar/Tags","tags":"$:/tags/Manager/ItemSidebar","caption":"{{$:/language/Manager/Item/Tags}}","text":"\\whitespace trim\n\\define tag-checkbox-actions()\n<$action-listops\n\t$tiddler=\"$:/config/Manager/RecentTags\"\n\t$subfilter=\"[<tag>] [list[$:/config/Manager/RecentTags]] +[limit[12]]\"\n/>\n\\end\n\n\\define tag-picker-actions()\n<<tag-checkbox-actions>>\n\\end\n\n<p>\n<$list filter=\"[all[current]tags[]] [list[$:/config/Manager/RecentTags]] +[sort[title]] \" variable=\"tag\" storyview=\"pop\">\n<div>\n<$checkbox tiddler=<<currentTiddler>> tag=<<tag>> actions=<<tag-checkbox-actions>>>\n<$macrocall $name=\"tag-pill\" tag=<<tag>>/>\n</$checkbox>\n</div>\n</$list>\n</p>\n<p>\n<$fieldmangler>\n<$macrocall $name=\"tag-picker\" actions=<<tag-picker-actions>>/>\n</$fieldmangler>\n</p>\n"},"$:/Manager/ItemSidebar/Tools":{"title":"$:/Manager/ItemSidebar/Tools","tags":"$:/tags/Manager/ItemSidebar","caption":"{{$:/language/Manager/Item/Tools}}","text":"\\whitespace trim\n<p>\n<$button to=<<currentTiddler>>>\n{{$:/core/images/link}}&#32;open\n</$button>\n</p>\n<p>\n<$button message=\"tm-edit-tiddler\" param=<<currentTiddler>>>\n{{$:/core/images/edit-button}}&#32;edit\n</$button>\n</p>\n"},"$:/Manager":{"title":"$:/Manager","icon":"$:/core/images/list","color":"#bbb","text":"\\define lingo-base() $:/language/Manager/\n\n\\define list-item-content-item()\n\\whitespace trim\n<div class=\"tc-manager-list-item-content-item\">\n\t<$vars state-title=\"\"\"$:/state/popup/manager/item/$(listItem)$\"\"\">\n\t\t<$reveal state=<<state-title>> type=\"match\" text=\"show\" default=\"show\" tag=\"div\">\n\t\t\t<$button set=<<state-title>> setTo=\"hide\" class=\"tc-btn-invisible tc-manager-list-item-content-item-heading\">\n\t\t\t\t{{$:/core/images/down-arrow}}&#32;<$transclude tiddler=<<listItem>> field=\"caption\"/>\n\t\t\t</$button>\n\t\t</$reveal>\n\t\t<$reveal state=<<state-title>> type=\"nomatch\" text=\"show\" default=\"show\" tag=\"div\">\n\t\t\t<$button set=<<state-title>> setTo=\"show\" class=\"tc-btn-invisible tc-manager-list-item-content-item-heading\">\n\t\t\t\t{{$:/core/images/right-arrow}}&#32;<$transclude tiddler=<<listItem>> field=\"caption\"/>\n\t\t\t</$button>\n\t\t</$reveal>\n\t\t<$reveal state=<<state-title>> type=\"match\" text=\"show\" default=\"show\" tag=\"div\" class=\"tc-manager-list-item-content-item-body\">\n\t\t\t<$transclude tiddler=<<listItem>>/>\n\t\t</$reveal>\n\t</$vars>\n</div>\n\\end\n\n\\whitespace trim\n<div class=\"tc-manager-wrapper\">\n\t<div class=\"tc-manager-controls\">\n\t\t<div class=\"tc-manager-control\">\n\t\t\t<<lingo Controls/Show/Prompt>>&#32;<$select tiddler=\"$:/config/Manager/Show\" default=\"tiddlers\">\n\t\t\t\t<option value=\"tiddlers\"><<lingo Controls/Show/Option/Tiddlers>></option>\n\t\t\t\t<option value=\"tags\"><<lingo Controls/Show/Option/Tags>></option>\n\t\t\t</$select>\n\t\t</div>\n\t\t<div class=\"tc-manager-control\">\n\t\t\t<<lingo Controls/Search/Prompt>>&#32;<$edit-text tiddler=\"$:/config/Manager/Filter\" tag=\"input\" default=\"\" placeholder={{$:/language/Manager/Controls/Search/Placeholder}}/>\n\t\t</div>\n\t\t<div class=\"tc-manager-control\">\n\t\t\t<<lingo Controls/FilterByTag/Prompt>>&#32;<$select tiddler=\"$:/config/Manager/Tag\" default=\"\">\n\t\t\t\t<option value=\"\"><<lingo Controls/FilterByTag/None>></option>\n\t\t\t\t<$list filter=\"[!is{$:/config/Manager/System}tags[]!is[system]sort[title]]\" variable=\"tag\">\n\t\t\t\t\t<option value=<<tag>>><$text text=<<tag>>/></option>\n\t\t\t\t</$list>\n\t\t\t</$select>\n\t\t</div>\n\t\t<div class=\"tc-manager-control\">\n\t\t\t<<lingo Controls/Sort/Prompt>>&#32;<$select tiddler=\"$:/config/Manager/Sort\" default=\"title\">\n\t\t\t\t<optgroup label=\"Common\">\n\t\t\t\t\t<$list filter=\"title modified modifier created creator created\" variable=\"field\">\n\t\t\t\t\t\t<option value=<<field>>><$text text=<<field>>/></option>\n\t\t\t\t\t</$list>\n\t\t\t\t</optgroup>\n\t\t\t\t<optgroup label=\"All\">\n\t\t\t\t\t<$list filter=\"[all{$:/config/Manager/Show}!is{$:/config/Manager/System}fields[]sort[title]] -title -modified -modifier -created -creator -created\" variable=\"field\">\n\t\t\t\t\t\t<option value=<<field>>><$text text=<<field>>/></option>\n\t\t\t\t\t</$list>\n\t\t\t\t</optgroup>\n\t\t\t</$select>\n\t\t\t&#32;\n\t\t\t<$checkbox tiddler=\"$:/config/Manager/Order\" field=\"text\" checked=\"reverse\" unchecked=\"forward\" default=\"forward\">\n\t\t\t\t&#32;\n\t\t\t\t<<lingo Controls/Order/Prompt>>\n\t\t\t</$checkbox>\n\t\t</div>\n\t\t<div class=\"tc-manager-control\">\n\t\t\t<$checkbox tiddler=\"$:/config/Manager/System\" field=\"text\" checked=\"\" unchecked=\"system\" default=\"system\">\n\t\t\t\t&#32;\n\t\t\t\t{{$:/language/SystemTiddlers/Include/Prompt}}\n\t\t\t</$checkbox>\n\t\t</div>\n\t</div>\n\t<div class=\"tc-manager-list\">\n\t\t<$list filter=\"[all{$:/config/Manager/Show}!is{$:/config/Manager/System}search{$:/config/Manager/Filter}tag:strict{$:/config/Manager/Tag}sort{$:/config/Manager/Sort}order{$:/config/Manager/Order}]\">\n\t\t\t<$vars transclusion=<<currentTiddler>>>\n\t\t\t\t<div style=\"tc-manager-list-item\">\n\t\t\t\t\t<$button popup=<<qualify \"$:/state/manager/popup\">> class=\"tc-btn-invisible tc-manager-list-item-heading\" selectedClass=\"tc-manager-list-item-heading-selected\">\n\t\t\t\t\t\t<$text text=<<currentTiddler>>/>\n\t\t\t\t\t</$button>\n\t\t\t\t\t<$reveal state=<<qualify \"$:/state/manager/popup\">> type=\"nomatch\" text=\"\" default=\"\" tag=\"div\" class=\"tc-manager-list-item-content tc-popup-handle\">\n\t\t\t\t\t\t<div class=\"tc-manager-list-item-content-tiddler\">\n\t\t\t\t\t\t\t<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Manager/ItemMain]!has[draft.of]]\" variable=\"listItem\">\n\t\t\t\t\t\t\t\t<<list-item-content-item>>\n\t\t\t\t\t\t\t</$list>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"tc-manager-list-item-content-sidebar\">\n\t\t\t\t\t\t\t<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Manager/ItemSidebar]!has[draft.of]]\" variable=\"listItem\">\n\t\t\t\t\t\t\t\t<<list-item-content-item>>\n\t\t\t\t\t\t\t</$list>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</$reveal>\n\t\t\t\t</div>\n\t\t\t</$vars>\n\t\t</$list>\n\t</div>\n</div>\n"},"$:/core/ui/MissingTemplate":{"title":"$:/core/ui/MissingTemplate","text":"\\whitespace trim\n<div class=\"tc-tiddler-missing\">\n<$button popup=<<qualify \"$:/state/popup/missing\">> class=\"tc-btn-invisible tc-missing-tiddler-label\">\n<$view field=\"title\" format=\"text\" />\n</$button>\n<$reveal state=<<qualify \"$:/state/popup/missing\">> type=\"popup\" position=\"below\" animate=\"yes\">\n<div class=\"tc-drop-down\">\n<$transclude tiddler=\"$:/core/ui/ListItemTemplate\"/>\n<hr>\n<$list filter=\"[all[current]backlinks[]sort[title]]\" template=\"$:/core/ui/ListItemTemplate\"/>\n</div>\n</$reveal>\n</div>\n"},"$:/core/ui/MoreSideBar/All":{"title":"$:/core/ui/MoreSideBar/All","tags":"$:/tags/MoreSideBar","caption":"{{$:/language/SideBar/All/Caption}}","text":"<$list filter={{$:/core/Filters/AllTiddlers!!filter}} template=\"$:/core/ui/ListItemTemplate\"/>\n"},"$:/core/ui/MoreSideBar/Drafts":{"title":"$:/core/ui/MoreSideBar/Drafts","tags":"$:/tags/MoreSideBar","caption":"{{$:/language/SideBar/Drafts/Caption}}","text":"<$list filter={{$:/core/Filters/Drafts!!filter}} template=\"$:/core/ui/ListItemTemplate\"/>\n"},"$:/core/ui/MoreSideBar/Explorer":{"title":"$:/core/ui/MoreSideBar/Explorer","tags":"$:/tags/MoreSideBar","caption":"{{$:/language/SideBar/Explorer/Caption}}","text":"<<tree \"$:/\">>\n"},"$:/core/ui/MoreSideBar/Missing":{"title":"$:/core/ui/MoreSideBar/Missing","tags":"$:/tags/MoreSideBar","caption":"{{$:/language/SideBar/Missing/Caption}}","text":"<$list filter={{$:/core/Filters/Missing!!filter}} template=\"$:/core/ui/MissingTemplate\"/>\n"},"$:/core/ui/MoreSideBar/Orphans":{"title":"$:/core/ui/MoreSideBar/Orphans","tags":"$:/tags/MoreSideBar","caption":"{{$:/language/SideBar/Orphans/Caption}}","text":"<$list filter={{$:/core/Filters/Orphans!!filter}} template=\"$:/core/ui/ListItemTemplate\"/>\n"},"$:/core/ui/MoreSideBar/Plugins":{"title":"$:/core/ui/MoreSideBar/Plugins","tags":"$:/tags/MoreSideBar","caption":"{{$:/language/ControlPanel/Plugins/Caption}}","text":"\n{{$:/language/ControlPanel/Plugins/Installed/Hint}}\n\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/MoreSideBar/Plugins]!has[draft.of]]\" default=\"$:/core/ui/MoreSideBar/Plugins/Plugins\" explicitState=\"$:/state/tab-1163638994\"/>\n"},"$:/core/ui/MoreSideBar/Recent":{"title":"$:/core/ui/MoreSideBar/Recent","tags":"$:/tags/MoreSideBar","caption":"{{$:/language/SideBar/Recent/Caption}}","text":"<$macrocall $name=\"timeline\" format={{$:/language/RecentChanges/DateFormat}}/>\n"},"$:/core/ui/MoreSideBar/Shadows":{"title":"$:/core/ui/MoreSideBar/Shadows","tags":"$:/tags/MoreSideBar","caption":"{{$:/language/SideBar/Shadows/Caption}}","text":"<$list filter={{$:/core/Filters/ShadowTiddlers!!filter}} template=\"$:/core/ui/ListItemTemplate\"/>\n"},"$:/core/ui/MoreSideBar/System":{"title":"$:/core/ui/MoreSideBar/System","tags":"$:/tags/MoreSideBar","caption":"{{$:/language/SideBar/System/Caption}}","text":"<$list filter={{$:/core/Filters/SystemTiddlers!!filter}} template=\"$:/core/ui/ListItemTemplate\"/>\n"},"$:/core/ui/MoreSideBar/Tags":{"title":"$:/core/ui/MoreSideBar/Tags","tags":"$:/tags/MoreSideBar","caption":"{{$:/language/SideBar/Tags/Caption}}","text":"\\whitespace trim\n<$let tv-config-toolbar-icons=\"yes\" tv-config-toolbar-text=\"yes\" tv-config-toolbar-class=\"\">\n\t<div class=\"tc-tiny-v-gap-bottom\">\n\t\t{{$:/core/ui/Buttons/tag-manager}}\n\t</div>\n</$let>\n<$list filter={{$:/core/Filters/AllTags!!filter}}>\n\t<div class=\"tc-tiny-v-gap-bottom\">\n\t\t<$transclude tiddler=\"$:/core/ui/TagTemplate\"/>\n\t</div>\n</$list>\n<hr class=\"tc-untagged-separator\">\n{{$:/core/ui/UntaggedTemplate}}\n"},"$:/core/ui/MoreSideBar/Types":{"title":"$:/core/ui/MoreSideBar/Types","tags":"$:/tags/MoreSideBar","caption":"{{$:/language/SideBar/Types/Caption}}","text":"\\whitespace trim\n<$list filter={{$:/core/Filters/TypedTiddlers!!filter}}>\n<div class=\"tc-menu-list-item\">\n<$view field=\"type\"/>\n<$list filter=\"[type{!!type}!is[system]sort[title]]\">\n<div class=\"tc-menu-list-subitem\">\n<$link to={{!!title}}><$view field=\"title\"/></$link>\n</div>\n</$list>\n</div>\n</$list>\n"},"$:/core/ui/MoreSideBar/Plugins/Languages":{"title":"$:/core/ui/MoreSideBar/Plugins/Languages","tags":"$:/tags/MoreSideBar/Plugins","caption":"{{$:/language/ControlPanel/Plugins/Languages/Caption}}","text":"<$list filter=\"[!has[draft.of]plugin-type[language]sort[name]]\" template=\"$:/core/ui/PluginListItemTemplate\" emptyMessage={{$:/language/ControlPanel/Plugins/Empty/Hint}}/>\n"},"$:/core/ui/MoreSideBar/Plugins/Plugins":{"title":"$:/core/ui/MoreSideBar/Plugins/Plugins","tags":"$:/tags/MoreSideBar/Plugins","caption":"{{$:/language/ControlPanel/Plugins/Plugins/Caption}}","text":"<$list filter=\"[!has[draft.of]plugin-type[plugin]sort[name]]\" template=\"$:/core/ui/PluginListItemTemplate\" emptyMessage={{$:/language/ControlPanel/Plugins/Empty/Hint}}>>/>\n"},"$:/core/ui/MoreSideBar/Plugins/Theme":{"title":"$:/core/ui/MoreSideBar/Plugins/Theme","tags":"$:/tags/MoreSideBar/Plugins","caption":"{{$:/language/ControlPanel/Plugins/Themes/Caption}}","text":"<$list filter=\"[!has[draft.of]plugin-type[theme]sort[name]]\" template=\"$:/core/ui/PluginListItemTemplate\" emptyMessage={{$:/language/ControlPanel/Plugins/Empty/Hint}}/>\n"},"$:/core/ui/Buttons/advanced-search":{"title":"$:/core/ui/Buttons/advanced-search","tags":"$:/tags/PageControls","caption":"{{$:/core/images/advanced-search-button}} {{$:/language/Buttons/AdvancedSearch/Caption}}","description":"{{$:/language/Buttons/AdvancedSearch/Hint}}","text":"\\whitespace trim\n\\procedure advanced-search-button(class)\n<$button to=\"$:/AdvancedSearch\" tooltip={{$:/language/Buttons/AdvancedSearch/Hint}} aria-label={{$:/language/Buttons/AdvancedSearch/Caption}} class=`$(tv-config-toolbar-class)$ $(class)$`>\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/advanced-search-button}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/AdvancedSearch/Caption}}/></span>\n<%endif%>\n</$button>\n\\end\n\n<$list filter=\"[list[$:/StoryList]] +[field:title[$:/AdvancedSearch]]\" emptyMessage=<<advanced-search-button>>>\n<<advanced-search-button \"tc-selected\">>\n</$list>\n"},"$:/core/ui/Buttons/close-all":{"title":"$:/core/ui/Buttons/close-all","tags":"$:/tags/PageControls","caption":"{{$:/core/images/close-all-button}} {{$:/language/Buttons/CloseAll/Caption}}","description":"{{$:/language/Buttons/CloseAll/Hint}}","text":"\\whitespace trim\n<$button message=\"tm-close-all-tiddlers\" tooltip={{$:/language/Buttons/CloseAll/Hint}} aria-label={{$:/language/Buttons/CloseAll/Caption}} class=<<tv-config-toolbar-class>>>\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/close-all-button}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/CloseAll/Caption}}/>\n</span>\n<%endif%>\n</$button>\n"},"$:/core/ui/Buttons/control-panel":{"title":"$:/core/ui/Buttons/control-panel","tags":"$:/tags/PageControls","caption":"{{$:/core/images/options-button}} {{$:/language/Buttons/ControlPanel/Caption}}","description":"{{$:/language/Buttons/ControlPanel/Hint}}","text":"\\whitespace trim\n\\procedure control-panel-button(class)\n<$button to=\"$:/ControlPanel\" tooltip={{$:/language/Buttons/ControlPanel/Hint}} aria-label={{$:/language/Buttons/ControlPanel/Caption}} class=`$(tv-config-toolbar-class)$ $(class)$`>\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/options-button}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/ControlPanel/Caption}}/></span>\n<%endif%>\n</$button>\n\\end\n\n<$list filter=\"[list<tv-story-list>] +[field:title[$:/ControlPanel]]\" emptyMessage=<<control-panel-button>>>\n<<control-panel-button \"tc-selected\">>\n</$list>\n"},"$:/core/ui/Buttons/encryption":{"title":"$:/core/ui/Buttons/encryption","tags":"$:/tags/PageControls","caption":"{{$:/core/images/locked-padlock}} {{$:/language/Buttons/Encryption/Caption}}","description":"{{$:/language/Buttons/Encryption/Hint}}","text":"\\whitespace trim\n<$reveal type=\"match\" state=\"$:/isEncrypted\" text=\"yes\">\n<$button message=\"tm-clear-password\" tooltip={{$:/language/Buttons/Encryption/ClearPassword/Hint}} aria-label={{$:/language/Buttons/Encryption/ClearPassword/Caption}} class=<<tv-config-toolbar-class>>>\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/locked-padlock}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/Encryption/ClearPassword/Caption}}/>\n</span>\n<%endif%>\n</$button>\n</$reveal>\n<$reveal type=\"nomatch\" state=\"$:/isEncrypted\" text=\"yes\">\n<$button message=\"tm-set-password\" tooltip={{$:/language/Buttons/Encryption/SetPassword/Hint}} aria-label={{$:/language/Buttons/Encryption/SetPassword/Caption}} class=<<tv-config-toolbar-class>>>\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/unlocked-padlock}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/Encryption/SetPassword/Caption}}/>\n</span>\n<%endif%>\n</$button>\n</$reveal>\n"},"$:/core/ui/Buttons/export-page":{"title":"$:/core/ui/Buttons/export-page","tags":"$:/tags/PageControls","caption":"{{$:/core/images/export-button}} {{$:/language/Buttons/ExportPage/Caption}}","description":"{{$:/language/Buttons/ExportPage/Hint}}","text":"<$transclude $variable=\"exportButton\" exportFilter=\"[!is[system]sort[title]]\" lingoBase=\"$:/language/Buttons/ExportPage/\"/>"},"$:/core/ui/Buttons/fold-all":{"title":"$:/core/ui/Buttons/fold-all","tags":"$:/tags/PageControls","caption":"{{$:/core/images/fold-all-button}} {{$:/language/Buttons/FoldAll/Caption}}","description":"{{$:/language/Buttons/FoldAll/Hint}}","text":"\\whitespace trim\n<$button tooltip={{$:/language/Buttons/FoldAll/Hint}} aria-label={{$:/language/Buttons/FoldAll/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-sendmessage $message=\"tm-fold-all-tiddlers\" $param=<<currentTiddler>> foldedStatePrefix=\"$:/state/folded/\"/>\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/fold-all-button}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/FoldAll/Caption}}/>\n</span>\n<%endif%>\n</$button>\n"},"$:/core/ui/Buttons/full-screen":{"title":"$:/core/ui/Buttons/full-screen","tags":"$:/tags/PageControls","caption":"{{$:/core/images/full-screen-button}} {{$:/language/Buttons/FullScreen/Caption}}","description":"{{$:/language/Buttons/FullScreen/Hint}}","text":"\\whitespace trim\n<$button message=\"tm-full-screen\" tooltip={{$:/language/Buttons/FullScreen/Hint}} aria-label={{$:/language/Buttons/FullScreen/Caption}} class=<<tv-config-toolbar-class>>>\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/full-screen-button}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/FullScreen/Caption}}/>\n</span>\n<%endif%>\n</$button>\n"},"$:/core/ui/Buttons/home":{"title":"$:/core/ui/Buttons/home","tags":"$:/tags/PageControls","caption":"{{$:/core/images/home-button}} {{$:/language/Buttons/Home/Caption}}","description":"{{$:/language/Buttons/Home/Hint}}","text":"\\whitespace trim\n<$button message=\"tm-home\" tooltip={{$:/language/Buttons/Home/Hint}} aria-label={{$:/language/Buttons/Home/Caption}} class=<<tv-config-toolbar-class>>>\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/home-button}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/Home/Caption}}/>\n</span>\n<%endif%>\n</$button>\n"},"$:/core/ui/Buttons/import":{"title":"$:/core/ui/Buttons/import","tags":"$:/tags/PageControls","caption":"{{$:/core/images/import-button}} {{$:/language/Buttons/Import/Caption}}","description":"{{$:/language/Buttons/Import/Hint}}","text":"\\whitespace trim\n<div class=\"tc-file-input-wrapper\">\n<$button tooltip={{$:/language/Buttons/Import/Hint}} aria-label={{$:/language/Buttons/Import/Caption}} class=<<tv-config-toolbar-class>>>\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/import-button}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/Import/Caption}}/>\n</span>\n<%endif%>\n</$button>\n<$browse tooltip={{$:/language/Buttons/Import/Hint}}/>\n</div>\n"},"$:/core/ui/Buttons/language":{"title":"$:/core/ui/Buttons/language","tags":"$:/tags/PageControls","caption":"{{$:/core/images/globe}} {{$:/language/Buttons/Language/Caption}}","description":"{{$:/language/Buttons/Language/Hint}}","text":"\\whitespace trim\n<span class=\"tc-popup-keep\">\n<$button popup=<<qualify \"$:/state/popup/language\">> tooltip={{$:/language/Buttons/Language/Hint}} aria-label={{$:/language/Buttons/Language/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n    <span class=\"tc-image-button\">\n        <$set name=\"languagePluginTitle\" value={{$:/language}}>\n            <$image source=`$(languagePluginTitle)$/icon`/>\n        </$set>\n    </span>\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Language/Caption}}/></span>\n<%endif%>\n</$button>\n</span>\n<$reveal state=<<qualify \"$:/state/popup/language\">> type=\"popup\" position=\"below\" animate=\"yes\">\n<div class=\"tc-drop-down\">\n{{$:/snippets/languageswitcher}}\n</div>\n</$reveal>\n"},"$:/core/ui/Buttons/layout":{"title":"$:/core/ui/Buttons/layout","tags":"$:/tags/PageControls","caption":"{{$:/core/images/layout-button}} {{$:/language/Buttons/LayoutSwitcher/Caption}}","description":"{{$:/language/LayoutSwitcher/Description}}","text":"\\whitespace trim\n<$button tooltip={{$:/language/Buttons/LayoutSwitcher/Hint}} aria-label={{$:/language/Buttons/LayoutSwitcher/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-sendmessage $message=\"tm-show-switcher\" switch=\"layout\"/>\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/layout-button}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/LayoutSwitcher/Caption}}/></span>\n<%endif%>\n</$button>\n"},"$:/core/ui/Buttons/manager":{"title":"$:/core/ui/Buttons/manager","tags":"$:/tags/PageControls","caption":"{{$:/core/images/list}} {{$:/language/Buttons/Manager/Caption}}","description":"{{$:/language/Buttons/Manager/Hint}}","text":"\\whitespace trim\n\\procedure manager-button(class)\n<$button to=\"$:/Manager\" tooltip={{$:/language/Buttons/Manager/Hint}} aria-label={{$:/language/Buttons/Manager/Caption}} class=`$(tv-config-toolbar-class)$ $(class)$`>\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/list}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/Manager/Caption}}/>\n</span>\n<%endif%>\n</$button>\n\\end\n\n<$list filter=\"[list[$:/StoryList]] +[field:title[$:/Manager]]\" emptyMessage=<<manager-button>>>\n<<manager-button \"tc-selected\">>\n</$list>\n"},"$:/core/ui/Buttons/more-page-actions":{"title":"$:/core/ui/Buttons/more-page-actions","tags":"$:/tags/PageControls","caption":"{{$:/core/images/down-arrow}} {{$:/language/Buttons/More/Caption}}","description":"{{$:/language/Buttons/More/Hint}}","text":"\\whitespace trim\n\\define config-title() $:/config/PageControlButtons/Visibility/$(listItem)$\n\n<$button popup=<<qualify \"$:/state/popup/more\">>\n\ttooltip={{$:/language/Buttons/More/Hint}}\n\taria-label={{$:/language/Buttons/More/Caption}}\n\tclass=<<tv-config-toolbar-class>>\n\tselectedClass=\"tc-selected\"\n>\n\t<%if [<tv-config-toolbar-icons>match[yes]] %>\n\t\t{{$:/core/images/down-arrow}}\n\t<%endif%>\n\t<%if [<tv-config-toolbar-text>match[yes]] %>\n\t\t<span class=\"tc-btn-text\">\n\t\t\t<$text text={{$:/language/Buttons/More/Caption}}/>\n\t\t</span>\n\t<%endif%>\n</$button>\n<$reveal state=<<qualify \"$:/state/popup/more\">> type=\"popup\" position=\"below\" animate=\"yes\">\n\t<div class=\"tc-drop-down\">\n\t\t<$let tv-config-toolbar-icons=\"yes\" tv-config-toolbar-text=\"yes\" tv-config-toolbar-class=\"tc-btn-invisible\">\n\t\t\t<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/PageControls]!has[draft.of]] -[[$:/core/ui/Buttons/more-page-actions]]\"\n\t\t\t\tvariable=\"listItem\"\n\t\t\t>\n\t\t\t\t<$reveal type=\"match\" state=<<config-title>> text=\"hide\">\n\t\t\t\t\t<$set name=\"tv-config-toolbar-class\"\n\t\t\t\t\t\tfilter=\"[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<$transclude tiddler=<<listItem>> mode=\"inline\"/>\n\t\t\t\t\t</$set>\n\t\t\t\t</$reveal>\n\t\t\t</$list>\n\t\t</$let>\n\t</div>\n</$reveal>\n"},"$:/core/ui/Buttons/network-activity":{"title":"$:/core/ui/Buttons/network-activity","tags":"$:/tags/PageControls","caption":"{{$:/core/images/network-activity}} {{$:/language/Buttons/NetworkActivity/Caption}}","description":"{{$:/language/Buttons/NetworkActivity/Hint}}","text":"\\whitespace trim\n<$button message=\"tm-http-cancel-all-requests\" tooltip={{$:/language/Buttons/NetworkActivity/Hint}} aria-label={{$:/language/Buttons/NetworkActivity/Caption}} class=<<tv-config-toolbar-class>>>\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/network-activity}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/NetworkActivity/Caption}}/>\n</span>\n<%endif%>\n</$button>\n"},"$:/core/ui/Buttons/new-image":{"title":"$:/core/ui/Buttons/new-image","tags":"$:/tags/PageControls","caption":"{{$:/core/images/new-image-button}} {{$:/language/Buttons/NewImage/Caption}}","description":"{{$:/language/Buttons/NewImage/Hint}}","text":"\\whitespace trim\n<$button tooltip={{$:/language/Buttons/NewImage/Hint}} aria-label={{$:/language/Buttons/NewImage/Caption}} class=<<tv-config-toolbar-class>> actions={{$:/core/ui/Actions/new-image}}>\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/new-image-button}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/NewImage/Caption}}/>\n</span>\n<%endif%>\n</$button>\n"},"$:/core/ui/Buttons/new-journal":{"title":"$:/core/ui/Buttons/new-journal","tags":"$:/tags/PageControls","caption":"{{$:/core/images/new-journal-button}} {{$:/language/Buttons/NewJournal/Caption}}","description":"{{$:/language/Buttons/NewJournal/Hint}}","text":"\\whitespace trim\n\\procedure journalButton()\n<$button tooltip={{$:/language/Buttons/NewJournal/Hint}} aria-label={{$:/language/Buttons/NewJournal/Caption}} class=<<tv-config-toolbar-class>> actions={{$:/core/ui/Actions/new-journal}}>\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/new-journal-button}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/NewJournal/Caption}}/>\n</span>\n<%endif%>\n</$button>\n\\end\n<<journalButton>>\n"},"$:/core/ui/Buttons/new-tiddler":{"title":"$:/core/ui/Buttons/new-tiddler","tags":"$:/tags/PageControls","caption":"{{$:/core/images/new-button}} {{$:/language/Buttons/NewTiddler/Caption}}","description":"{{$:/language/Buttons/NewTiddler/Hint}}","text":"\\whitespace trim\n<$button actions={{$:/core/ui/Actions/new-tiddler}} tooltip={{$:/language/Buttons/NewTiddler/Hint}} aria-label={{$:/language/Buttons/NewTiddler/Caption}} class=<<tv-config-toolbar-class>>>\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/new-button}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/NewTiddler/Caption}}/>\n</span>\n<%endif%>\n</$button>\n"},"$:/core/ui/Buttons/palette":{"title":"$:/core/ui/Buttons/palette","tags":"$:/tags/PageControls","caption":"{{$:/core/images/palette}} {{$:/language/Buttons/Palette/Caption}}","description":"{{$:/language/Buttons/Palette/Hint}}","text":"\\whitespace trim\n<span class=\"tc-popup-keep\">\n<$button popup=<<qualify \"$:/state/popup/palette\">> tooltip={{$:/language/Buttons/Palette/Hint}} aria-label={{$:/language/Buttons/Palette/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/palette}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Palette/Caption}}/></span>\n<%endif%>\n</$button>\n</span>\n<$reveal state=<<qualify \"$:/state/popup/palette\">> type=\"popup\" position=\"below\" animate=\"yes\">\n<div class=\"tc-drop-down\" style=\"font-size:0.7em;\">\n{{$:/snippets/paletteswitcher}}\n</div>\n</$reveal>\n"},"$:/core/ui/Buttons/print":{"title":"$:/core/ui/Buttons/print","tags":"$:/tags/PageControls","caption":"{{$:/core/images/print-button}} {{$:/language/Buttons/Print/Caption}}","description":"{{$:/language/Buttons/Print/Hint}}","text":"\\whitespace trim\n<$button message=\"tm-print\" tooltip={{$:/language/Buttons/Print/Hint}} aria-label={{$:/language/Buttons/Print/Caption}} class=<<tv-config-toolbar-class>>>\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/print-button}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/Print/Caption}}/>\n</span>\n<%endif%>\n</$button>\n"},"$:/core/ui/Buttons/refresh":{"title":"$:/core/ui/Buttons/refresh","tags":"$:/tags/PageControls","caption":"{{$:/core/images/refresh-button}} {{$:/language/Buttons/Refresh/Caption}}","description":"{{$:/language/Buttons/Refresh/Hint}}","text":"\\whitespace trim\n<$button message=\"tm-browser-refresh\" tooltip={{$:/language/Buttons/Refresh/Hint}} aria-label={{$:/language/Buttons/Refresh/Caption}} class=<<tv-config-toolbar-class>>>\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/refresh-button}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/Refresh/Caption}}/>\n</span>\n<%endif%>\n</$button>\n"},"$:/core/ui/Buttons/save-wiki":{"title":"$:/core/ui/Buttons/save-wiki","tags":"$:/tags/PageControls","caption":"{{$:/core/images/save-button-dynamic}} {{$:/language/Buttons/SaveWiki/Caption}}","description":"{{$:/language/Buttons/SaveWiki/Hint}}","text":"\\whitespace trim\n<$button tooltip={{$:/language/Buttons/SaveWiki/Hint}} aria-label={{$:/language/Buttons/SaveWiki/Caption}} class=<<tv-config-toolbar-class>>>\n<$wikify name=\"site-title\" text={{$:/config/SaveWikiButton/Filename}}>\n<$action-sendmessage $message=\"tm-save-wiki\" $param={{$:/config/SaveWikiButton/Template}} filename=<<site-title>>/>\n</$wikify>\n<span class=\"tc-dirty-indicator\">\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/save-button-dynamic}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/SaveWiki/Caption}}/>\n</span>\n<%endif%>\n</span>\n</$button>\n"},"$:/core/ui/Buttons/storyview":{"title":"$:/core/ui/Buttons/storyview","tags":"$:/tags/PageControls","caption":"{{$:/core/images/storyview-classic}} {{$:/language/Buttons/StoryView/Caption}}","description":"{{$:/language/Buttons/StoryView/Hint}}","text":"\\whitespace trim\n<span class=\"tc-popup-keep\">\n<$button popup=<<qualify \"$:/state/popup/storyview\">> tooltip={{$:/language/Buttons/StoryView/Hint}} aria-label={{$:/language/Buttons/StoryView/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n<$set name=\"storyview\" value={{$:/view}}>\n<$transclude tiddler=`$:/core/images/storyview-$(storyview)$`/>\n</$set>\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/StoryView/Caption}}/></span>\n<%endif%>\n</$button>\n</span>\n<$reveal state=<<qualify \"$:/state/popup/storyview\">> type=\"popup\" position=\"below\" animate=\"yes\">\n<div class=\"tc-drop-down\">\n{{$:/snippets/viewswitcher}}\n</div>\n</$reveal>\n"},"$:/core/ui/Buttons/tag-manager":{"title":"$:/core/ui/Buttons/tag-manager","tags":"$:/tags/PageControls","caption":"{{$:/core/images/tag-button}} {{$:/language/Buttons/TagManager/Caption}}","description":"{{$:/language/Buttons/TagManager/Hint}}","text":"\\whitespace trim\n\\procedure control-panel-button(class)\n<$button to=\"$:/TagManager\" tooltip={{$:/language/Buttons/TagManager/Hint}} aria-label={{$:/language/Buttons/TagManager/Caption}} class=`$(tv-config-toolbar-class)$ $(class)$`>\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/tag-button}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/TagManager/Caption}}/>\n</span>\n<%endif%>\n</$button>\n\\end\n\n<$list filter=\"[list[$:/StoryList]] +[field:title[$:/TagManager]]\" emptyMessage=<<control-panel-button>>>\n<<control-panel-button \"tc-selected\">>\n</$list>\n"},"$:/core/ui/Buttons/theme":{"title":"$:/core/ui/Buttons/theme","tags":"$:/tags/PageControls","caption":"{{$:/core/images/theme-button}} {{$:/language/Buttons/Theme/Caption}}","description":"{{$:/language/Buttons/Theme/Hint}}","text":"\\whitespace trim\n<span class=\"tc-popup-keep\">\n<$button popup=<<qualify \"$:/state/popup/theme\">> tooltip={{$:/language/Buttons/Theme/Hint}} aria-label={{$:/language/Buttons/Theme/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/theme-button}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Theme/Caption}}/></span>\n<%endif%>\n</$button>\n</span>\n<$reveal state=<<qualify \"$:/state/popup/theme\">> type=\"popup\" position=\"below\" animate=\"yes\">\n<div class=\"tc-drop-down\">\n<$linkcatcher to=\"$:/theme\">\n{{$:/snippets/themeswitcher}}\n</$linkcatcher>\n</div>\n</$reveal>\n"},"$:/core/ui/Buttons/timestamp":{"title":"$:/core/ui/Buttons/timestamp","tags":"$:/tags/PageControls","caption":"{{$:/core/images/timestamp-on}} {{$:/language/Buttons/Timestamp/Caption}}","description":"{{$:/language/Buttons/Timestamp/Hint}}","text":"\\whitespace trim\n<$reveal type=\"nomatch\" state=\"$:/config/TimestampDisable\" text=\"yes\">\n<$button tooltip={{$:/language/Buttons/Timestamp/On/Hint}} aria-label={{$:/language/Buttons/Timestamp/On/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-setfield $tiddler=\"$:/config/TimestampDisable\" $value=\"yes\"/>\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/timestamp-on}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/Timestamp/On/Caption}}/>\n</span>\n<%endif%>\n</$button>\n</$reveal>\n<$reveal type=\"match\" state=\"$:/config/TimestampDisable\" text=\"yes\">\n<$button tooltip={{$:/language/Buttons/Timestamp/Off/Hint}} aria-label={{$:/language/Buttons/Timestamp/Off/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-setfield $tiddler=\"$:/config/TimestampDisable\" $value=\"no\"/>\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/timestamp-off}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/Timestamp/Off/Caption}}/>\n</span>\n<%endif%>\n</$button>\n</$reveal>\n"},"$:/core/ui/Buttons/unfold-all":{"title":"$:/core/ui/Buttons/unfold-all","tags":"$:/tags/PageControls","caption":"{{$:/core/images/unfold-all-button}} {{$:/language/Buttons/UnfoldAll/Caption}}","description":"{{$:/language/Buttons/UnfoldAll/Hint}}","text":"\\whitespace trim\n<$button tooltip={{$:/language/Buttons/UnfoldAll/Hint}} aria-label={{$:/language/Buttons/UnfoldAll/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-sendmessage $message=\"tm-unfold-all-tiddlers\" $param=<<currentTiddler>> foldedStatePrefix=\"$:/state/folded/\"/>\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/unfold-all-button}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/UnfoldAll/Caption}}/>\n</span>\n<%endif%>\n</$button>\n"},"$:/core/ui/PageTemplate/pagecontrols":{"title":"$:/core/ui/PageTemplate/pagecontrols","text":"\\whitespace trim\n\\function config-title() [[$:/config/PageControlButtons/Visibility/$(listItem)$]substitute[]]\n\n<div class=\"tc-page-controls\">\n\t<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/PageControls]!has[draft.of]]\" variable=\"listItem\">\n\t\t<$list filter=\"[<config-title>!text[hide]]\" storyview=\"pop\" variable=\"ignore\">\n\t\t\t<$let tv-config-toolbar-class={{{ [enlist<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]] +[join[ ]] }}}>\n\t\t\t\t<$transclude $tiddler=<<listItem>> $mode=\"inline\"/>\n\t\t\t</$let>\n\t\t</$list>\n\t</$list>\n</div>"},"$:/core/ui/PageStylesheet":{"title":"$:/core/ui/PageStylesheet","code-body":"yes","text":"\\import [subfilter{$:/core/config/GlobalImportFilter}]\n\\whitespace trim\n\n<$set name=\"currentTiddler\" value={{$:/language}}>\n\n<$set name=\"languageTitle\" value={{!!name}}>\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Stylesheet]!has[draft.of]]\">\n<$transclude mode=\"block\"/>\n</$list>\n\n</$set>\n\n</$set>\n"},"$:/core/ui/PageTemplate/alerts":{"title":"$:/core/ui/PageTemplate/alerts","tags":"$:/tags/PageTemplate","text":"<div class=\"tc-alerts\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Alert]!has[draft.of]]\" template=\"$:/core/ui/AlertTemplate\" storyview=\"pop\"/>\n\n</div>\n"},"$:/core/ui/PageTemplate/drafts":{"title":"$:/core/ui/PageTemplate/drafts","tags":"$:/tags/PageTemplate","text":"\\whitespace trim\n<$reveal state=\"$:/status/IsReadOnly\" type=\"nomatch\" text=\"yes\" tag=\"div\" class=\"tc-drafts-list\">\n<$list filter=\"[has[draft.of]!sort[modified]] -[list[$:/StoryList]]\">\n<$link>\n{{$:/core/images/edit-button}} <$text text=<<currentTiddler>>/>\n</$link>\n</$list>\n</$reveal>\n"},"$:/core/ui/PageTemplate/pluginreloadwarning":{"title":"$:/core/ui/PageTemplate/pluginreloadwarning","tags":"$:/tags/PageTemplate","text":"\\define lingo-base() $:/language/\n\n<$list filter=\"[{$:/status/RequireReloadDueToPluginChange}match[yes]]\">\n\n<$reveal type=\"nomatch\" state=\"$:/temp/HidePluginWarning\" text=\"yes\">\n\n<div class=\"tc-plugin-reload-warning\">\n\n<$set name=\"tv-config-toolbar-class\" value=\"\">\n\n<<lingo PluginReloadWarning>> <$button set=\"$:/temp/HidePluginWarning\" setTo=\"yes\" class=\"tc-btn-invisible\">{{$:/core/images/close-button}}</$button>\n\n</$set>\n\n</div>\n\n</$reveal>\n\n</$list>\n"},"$:/core/ui/PageTemplate/sidebar":{"title":"$:/core/ui/PageTemplate/sidebar","tags":"$:/tags/PageTemplate","text":"\\whitespace trim\n\\define config-title()\n$:/config/SideBarSegments/Visibility/$(listItem)$\n\\end\n\n<$scrollable fallthrough=\"no\" class=\"tc-sidebar-scrollable\">\n\n<div class=\"tc-sidebar-header\">\n\n<$reveal state=\"$:/state/sidebar\" type=\"match\" text=\"yes\" default=\"yes\" retain=\"yes\" animate=\"yes\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/SideBarSegment]!has[draft.of]]\" variable=\"listItem\">\n\n<$reveal type=\"nomatch\" state=<<config-title>> text=\"hide\"  tag=\"div\">\n\n<$transclude tiddler=<<listItem>> mode=\"block\"/>\n\n</$reveal>\n\n</$list>\n\n</$reveal>\n\n</div>\n\n</$scrollable>\n"},"$:/core/ui/PageTemplate/story":{"title":"$:/core/ui/PageTemplate/story","tags":"$:/tags/PageTemplate","text":"\\whitespace trim\n<section class=\"tc-story-river\" role=\"main\">\n\n<section class=\"story-backdrop\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/AboveStory]!has[draft.of]]\">\n\n<$transclude/>\n\n</$list>\n\n</section>\n\n<$list filter=\"[list[$:/StoryList]]\" history=\"$:/HistoryList\" template=\"$:/core/ui/StoryTiddlerTemplate\" storyview={{$:/view}} emptyMessage={{$:/config/EmptyStoryMessage}}/>\n\n<section class=\"story-frontdrop\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/BelowStory]!has[draft.of]]\">\n\n<$transclude/>\n\n</$list>\n\n</section>\n\n</section>\n"},"$:/core/ui/PageTemplate/topleftbar":{"title":"$:/core/ui/PageTemplate/topleftbar","tags":"$:/tags/PageTemplate","text":"<span class=\"tc-topbar tc-topbar-left\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/TopLeftBar]!has[draft.of]]\" variable=\"listItem\" storyview=\"pop\">\n\n<$transclude tiddler=<<listItem>> mode=\"inline\"/>\n\n</$list>\n\n</span>\n"},"$:/core/ui/PageTemplate/toprightbar":{"title":"$:/core/ui/PageTemplate/toprightbar","tags":"$:/tags/PageTemplate","text":"<span class=\"tc-topbar tc-topbar-right\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/TopRightBar]!has[draft.of]]\" variable=\"listItem\" storyview=\"pop\">\n\n<$transclude tiddler=<<listItem>> mode=\"inline\"/>\n\n</$list>\n\n</span>\n"},"$:/PaletteManager":{"title":"$:/PaletteManager","text":"\\define lingo-base() $:/language/ControlPanel/Palette/Editor/\n\\define describePaletteColour(colour)\n<$transclude tiddler=\"$:/language/Docs/PaletteColours/$colour$\"><$text text=\"$colour$\"/></$transclude>\n\\end\n\\define edit-colour-placeholder()\n edit $(colourName)$\n\\end\n\\define colour-tooltip(showhide) $showhide$ editor for $(newColourName)$ \n\n\\define resolve-colour(macrocall)\n\\import $:/core/macros/utils\n\\whitespace trim\n<$wikify name=\"name\" text=\"\"\"$macrocall$\"\"\">\n<<name>>\n</$wikify>\n\\end\n\n\\define delete-colour-index-actions() <$action-setfield $index=<<colourName>>/>\n\\define palette-manager-colour-row-segment()\n\\whitespace trim\n<$edit-text index=<<colourName>> tag=\"input\" placeholder=<<edit-colour-placeholder>> default=\"\"/>\n<br>\n<$edit-text index=<<colourName>> type=\"color\" tag=\"input\" class=\"tc-palette-manager-colour-input\"/>\n<$list filter=\"[<currentTiddler>getindex<colourName>removeprefix[<<]removesuffix[>>]] [<currentTiddler>getindex<colourName>removeprefix[<$]removesuffix[/>]]\" variable=\"ignore\">\n<$set name=\"state\" value={{{ [[$:/state/palettemanager/]addsuffix<currentTiddler>addsuffix[/]addsuffix<colourName>] }}}>\n<$wikify name=\"newColourName\" text=\"\"\"<$macrocall $name=\"resolve-colour\" macrocall={{{ [<currentTiddler>getindex<colourName>] }}}/>\"\"\">\n<$reveal state=<<state>> type=\"nomatch\" text=\"show\">\n<$button tooltip=<<colour-tooltip show>> aria-label=<<colour-tooltip show>> class=\"tc-btn-invisible\" set=<<state>> setTo=\"show\">{{$:/core/images/down-arrow}}<$text text=<<newColourName>> class=\"tc-small-gap-left\"/></$button><br>\n</$reveal>\n<$reveal state=<<state>> type=\"match\" text=\"show\">\n<$button tooltip=<<colour-tooltip hide>> aria-label=<<colour-tooltip show>> class=\"tc-btn-invisible\" actions=\"\"\"<$action-deletetiddler $tiddler=<<state>>/>\"\"\">{{$:/core/images/up-arrow}}<$text text=<<newColourName>> class=\"tc-small-gap-left\"/></$button><br>\n</$reveal>\n<$reveal state=<<state>> type=\"match\" text=\"show\">\n<$set name=\"colourName\" value=<<newColourName>>>\n<br>\n<<palette-manager-colour-row-segment>>\n<br><br>\n</$set>\n</$reveal>\n</$wikify>\n</$set>\n</$list>\n\\end\n\n\\define palette-manager-colour-row()\n\\whitespace trim\n<tr>\n<td>\n<span style=\"float:right;\">\n<$button tooltip={{$:/language/ControlPanel/Palette/Editor/Delete/Hint}} aria-label={{$:/language/ControlPanel/Palette/Editor/Delete/Hint}} class=\"tc-btn-invisible\" actions=<<delete-colour-index-actions>>>\n{{$:/core/images/delete-button}}</$button>\n</span>\n''<$macrocall $name=\"describePaletteColour\" colour=<<colourName>>/>''<br/>\n<$macrocall $name=\"colourName\" $output=\"text/plain\"/>\n</td>\n<td>\n<<palette-manager-colour-row-segment>>\n</td>\n</tr>\n\\end\n\n\\define palette-manager-table()\n\\whitespace trim\n<table>\n<tbody>\n<$set name=\"colorList\" filter=\"[{$:/state/palettemanager/showexternal}match[yes]]\"\n   value=\"[all[shadows+tiddlers]tag[$:/tags/Palette]indexes[]]\" emptyValue=\"[<currentTiddler>indexes[]]\">\n<$list filter=<<colorList>> variable=\"colourName\"> <<palette-manager-colour-row>> </$list>\n</$set>\n</tbody>\n</table>\n\\end\n\\whitespace trim\n<$set name=\"currentTiddler\" value={{$:/palette}}>\n\n<<lingo Prompt>>&#32;<$link to={{$:/palette}}><$macrocall $name=\"currentTiddler\" $output=\"text/plain\"/></$link>\n\n<$list filter=\"[all[current]is[shadow]is[tiddler]]\" variable=\"listItem\">\n<<lingo Prompt/Modified>>\n&#32;\n<$button message=\"tm-delete-tiddler\" param={{$:/palette}}><<lingo Reset/Caption>></$button>\n</$list>\n\n<$list filter=\"[all[current]is[shadow]!is[tiddler]]\" variable=\"listItem\">\n<<lingo Clone/Prompt>>\n</$list>\n\n<$button message=\"tm-new-tiddler\" param={{$:/palette}}><<lingo Clone/Caption>></$button>\n\n<$checkbox tiddler=\"$:/state/palettemanager/showexternal\" field=\"text\" checked=\"yes\" unchecked=\"no\"><span class=\"tc-small-gap-left\"><<lingo Names/External/Show>></span></$checkbox>\n\n<<palette-manager-table>>\n"},"$:/core/ui/PluginInfo":{"title":"$:/core/ui/PluginInfo","text":"\\define localised-info-tiddler-title()\n$(currentTiddler)$/$(languageTitle)$/$(currentTab)$\n\\end\n\\define info-tiddler-title()\n$(currentTiddler)$/$(currentTab)$\n\\end\n\\define default-tiddler-title()\n$:/core/ui/PluginInfo/Default/$(currentTab)$\n\\end\n\\whitespace trim\n<$transclude tiddler=<<localised-info-tiddler-title>> mode=\"block\">\n<$transclude tiddler=<<currentTiddler>> subtiddler=<<localised-info-tiddler-title>> mode=\"block\">\n<$transclude tiddler=<<currentTiddler>> subtiddler=<<info-tiddler-title>> mode=\"block\">\n<$transclude tiddler=<<default-tiddler-title>> mode=\"block\">\n{{$:/language/ControlPanel/Plugin/NoInfoFound/Hint}}\n</$transclude>\n</$transclude>\n</$transclude>\n</$transclude>\n"},"$:/core/ui/PluginInfo/Default/contents":{"title":"$:/core/ui/PluginInfo/Default/contents","text":"\\define lingo-base() $:/language/TiddlerInfo/Advanced/PluginInfo/\n\\whitespace trim\n<<lingo Hint>>\n<ul>\n<$list filter=\"[all[current]plugintiddlers[]sort[title]]\" emptyMessage=<<lingo Empty/Hint>>>\n<li>\n<$link />\n</li>\n</$list>\n</ul>\n"},"$:/core/ui/PluginListItemTemplate":{"title":"$:/core/ui/PluginListItemTemplate","text":"\\whitespace trim\n<$link to={{!!title}} class=\"tc-plugin-info\">\n\t<div class=\"tc-plugin-info-chunk tc-plugin-info-icon\">\n\t\t<$transclude tiddler=<<currentTiddler>> subtiddler={{{ [<currentTiddler>addsuffix[/icon]] }}}>\n\t\t\t<$transclude tiddler={{{ [<currentTiddler>get[plugin-type]addprefix[$:/core/images/plugin-generic-]] }}}/>\n\t\t</$transclude>\n\t</div>\n\t<div class=\"tc-plugin-info-chunk tc-plugin-info-description\">\n\t\t<h1>\n\t\t\t''<$text text={{{ [<currentTiddler>get[name]] ~[<currentTiddler>split[/]last[1]] }}}/>'':&nbsp;<$view field=\"description\"><$view field=\"title\"/></$view>\n\t\t</h1>\n\t</div>\n</$link>\n"},"$:/core/ui/RootTemplate":{"title":"$:/core/ui/RootTemplate","code-body":"yes","text":"<$transclude tiddler={{{ [{$:/layout}has[text]] ~[[$:/core/ui/PageTemplate]] }}} mode=\"inline\"/>\n\n"},"$:/core/ui/SearchResults":{"title":"$:/core/ui/SearchResults","text":"<div class=\"tc-search-results\">\n\n<$list\n\tfilter=\"[all[shadows+tiddlers]tag[$:/tags/SearchResults]!has[draft.of]butfirst[]limit[1]]\"\n\temptyMessage=\"<$list filter='[all[shadows+tiddlers]tag[$:/tags/SearchResults]!has[draft.of]]'><$transclude mode='block'/></$list>\">\n\n<$macrocall $name=\"tabs\"\n\ttabsList=\"[all[shadows+tiddlers]tag[$:/tags/SearchResults]!has[draft.of]]\"\n\tdefault={{$:/config/SearchResults/Default}}\n\tactions=\"<$action-setfield $tiddler='$:/state/search/currentTab' text=<<currentTab>>/>\"\n\texplicitState=\"$:/state/tab/search-results/sidebar\"/>\n\n</$list>\n\n</div>\n"},"$:/core/ui/SideBar/More":{"title":"$:/core/ui/SideBar/More","tags":"$:/tags/SideBar","caption":"{{$:/language/SideBar/More/Caption}}","text":"\\whitespace trim\n<div class={{{ [{$:/config/ui/SideBar/More/horizontal}match[yes]then[tc-sidebar-tabs]else[tc-more-sidebar]] }}}>\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/MoreSideBar]!has[draft.of]]\" default={{$:/config/DefaultMoreSidebarTab}} state=\"$:/state/tab/moresidebar\" class={{{ [{$:/config/ui/SideBar/More/horizontal}match[yes]then[tc-sidebar-tabs-more]else[tc-vertical tc-sidebar-tabs-more]] }}} explicitState=\"$:/state/tab/moresidebar-1850697562\"/>\n</div>\n"},"$:/core/ui/SideBar/Open":{"title":"$:/core/ui/SideBar/Open","tags":"$:/tags/SideBar","caption":"{{$:/language/SideBar/Open/Caption}}","text":"\\whitespace trim\n\\define lingo-base() $:/language/CloseAll/\n\n\\define drop-actions()\n<$action-listops $tiddler=<<tv-story-list>> $subfilter=\"+[insertbefore<actionTiddler>,<currentTiddler>]\"/>\n\\end\n\n\\define placeholder()\n<div class=\"tc-droppable-placeholder\"/>\n\\end\n\n\\define droppable-item(button)\n\\whitespace trim\n<$droppable actions=<<drop-actions>> enable=<<tv-allow-drag-and-drop>> tag=\"div\">\n<<placeholder>>\n<div>\n$button$\n</div>\n</$droppable>\n\\end\n\n<div class=\"tc-sidebar-tab-open\">\n<$list filter=\"[list<tv-story-list>]\" history=<<tv-history-list>> storyview=\"pop\">\n<div class=\"tc-sidebar-tab-open-item\">\n<$macrocall $name=\"droppable-item\" button=\"<$button message='tm-close-tiddler' tooltip={{$:/language/Buttons/Close/Hint}} aria-label={{$:/language/Buttons/Close/Caption}} class='tc-btn-invisible tc-btn-mini tc-small-gap-right'>{{$:/core/images/close-button}}</$button><$link/>\"/>\n</div>\n</$list>\n<$tiddler tiddler=\"\">\n<div>\n<$macrocall $name=\"droppable-item\" button=\"<$button message='tm-close-all-tiddlers' class='tc-btn-invisible tc-btn-mini'><<lingo Button>></$button>\"/>\n</div>\n</$tiddler>\n</div>\n"},"$:/core/ui/SideBar/Recent":{"title":"$:/core/ui/SideBar/Recent","tags":"$:/tags/SideBar","caption":"{{$:/language/SideBar/Recent/Caption}}","text":"<$transclude $variable=\"timeline\" format={{$:/language/RecentChanges/DateFormat}} limit={{$:/config/RecentLimit}}/>\n"},"$:/core/ui/SideBar/Tools":{"title":"$:/core/ui/SideBar/Tools","tags":"$:/tags/SideBar","caption":"{{$:/language/SideBar/Tools/Caption}}","text":"\\define lingo-base() $:/language/ControlPanel/\n\\define config-title()\n$:/config/PageControlButtons/Visibility/$(listItem)$\n\\end\n\n<<lingo Basics/Version/Prompt>> <<version>>\n\n<$set name=\"tv-config-toolbar-icons\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-text\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-class\" value=\"\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/PageControls]!has[draft.of]]\" variable=\"listItem\">\n\n<div style=\"position:relative;\" class={{{ [<listItem>encodeuricomponent[]addprefix[tc-btn-]] }}}>\n\n<$checkbox tiddler=<<config-title>> field=\"text\" checked=\"show\" unchecked=\"hide\" default=\"show\"/> <$transclude tiddler=<<listItem>>/> <i class=\"tc-muted\"><$transclude tiddler=<<listItem>> field=\"description\"/></i>\n\n</div>\n\n</$list>\n\n</$set>\n\n</$set>\n\n</$set>\n"},"$:/core/ui/SideBarLists":{"title":"$:/core/ui/SideBarLists","text":"<$transclude tiddler=\"$:/core/ui/SideBarSegments/search\"/>\n\n<$transclude tiddler=\"$:/core/ui/SideBarSegments/tabs\"/>\n\n"},"$:/core/ui/SideBarSegments/page-controls":{"title":"$:/core/ui/SideBarSegments/page-controls","tags":"$:/tags/SideBarSegment","text":"{{||$:/core/ui/PageTemplate/pagecontrols}}\n"},"$:/core/ui/SideBarSegments/search":{"title":"$:/core/ui/SideBarSegments/search","tags":"$:/tags/SideBarSegment","text":"\\whitespace trim\n\n\\procedure count-popup-button()\n\\whitespace trim\n<$button popup=<<qualify \"$:/state/popup/search-dropdown\">> class=\"tc-btn-invisible\">\n{{$:/core/images/down-arrow}}\n<$list filter=\"[<searchTiddler>get[text]minlength{$:/config/Search/MinLength}limit[1]]\" variable=\"listItem\">\n<$vars userInput={{{ [<searchTiddler>get[text]] }}} configTiddler={{{ [[$:/state/search/currentTab]!is[missing]get[text]] :else[{$:/config/SearchResults/Default}] }}} replaceRegexp=\"limit\\[\\d+\\]\">\n<$vars primaryListFilter={{{ [<configTiddler>get[first-search-filter]search-replace:g:regexp<replaceRegexp>,[]] }}} secondaryListFilter={{{ [<configTiddler>get[second-search-filter]search-replace:g:regexp<replaceRegexp>,[]] }}}>\n<$set name=\"resultCount\" value=\"\"\"<$count filter=\"[subfilter<primaryListFilter>] [subfilter<secondaryListFilter>]\"/>\"\"\">\n{{$:/language/Search/Matches}}\n</$set>\n</$vars>\n</$vars>\n</$list>\n</$button>\n\\end\n\n\\procedure search-results-list()\n\\whitespace trim\n<$vars userInput={{{ [<searchTiddler>get[text]] }}} configTiddler={{{ [[$:/state/search/currentTab]!is[missing]get[text]] :else[{$:/config/SearchResults/Default}] }}}>\n<$list filter=\"[<userInput>minlength{$:/config/Search/MinLength}limit[1]]\" emptyMessage=\"\"\"<div class=\"tc-search-results\">{{$:/language/Search/Search/TooShort}}</div>\"\"\" variable=\"listItem\">\n\n<$tiddler tiddler=<<configTiddler>>>\n\n{{$:/core/ui/SearchResults}}\n\n</$tiddler>\n\n</$list>\n</$vars>\n\\end\n\n\\procedure cancel-search-actions() <$list filter=\"[<searchTiddler>get[text]!match{$:/temp/search}]\" emptyMessage=\"\"\"<$action-deletetiddler $filter=\"[[$:/temp/search]] [<searchTiddler>] [<searchListState>]\"/>\"\"\"><$action-setfield $tiddler=\"$:/temp/search\" text={{{ [<searchTiddler>get[text]] }}}/><$action-setfield $tiddler=\"$:/temp/search/refresh\" text=\"yes\"/></$list>\n\n\\procedure input-accept-actions() <$list filter=\"[{$:/config/Search/NavigateOnEnter/enable}match[yes]]\" emptyMessage=\"\"\"<$list filter=\"[<tiddler>get[text]!is[missing]] :else[<tiddler>get[text]is[shadow]]\"><$action-navigate $to={{{ [<tiddler>get[text]] }}}/></$list>\"\"\"><$action-navigate $to={{{ [<tiddler>get[text]] }}}/></$list>\n\n\\procedure input-accept-variant-actions() <$list filter=\"[{$:/config/Search/NavigateOnEnter/enable}match[yes]]\" emptyMessage=\"\"\"<$list filter=\"[<tiddler>get[text]!is[missing]] :else[<tiddler>get[text]is[shadow]]\"><$list filter=\"[<tiddler>get[text]minlength[1]]\"><$action-sendmessage $message=\"tm-edit-tiddler\" $param={{{  [<tiddler>get[text]] }}}/></$list></$list>\"\"\"><$list filter=\"[<tiddler>get[text]minlength[1]]\"><$action-sendmessage $message=\"tm-edit-tiddler\" $param={{{  [<tiddler>get[text]] }}}/></$list></$list>\n\n\\procedure set-next-input-tab() <$transclude $variable=\"change-input-tab\" stateTitle=\"$:/state/tab/search-results/sidebar\" tag=\"$:/tags/SearchResults\" beforeafter=\"after\" defaultState={{$:/config/SearchResults/Default}} actions=\"\"\"<$action-setfield $tiddler=\"$:/state/search/currentTab\" text=<<nextTab>>/>\"\"\"/>\n\n\\procedure set-previous-input-tab() <$transclude $variable=\"change-input-tab\" stateTitle=\"$:/state/tab/search-results/sidebar\" tag=\"$:/tags/SearchResults\" beforeafter=\"before\" defaultState={{$:/config/SearchResults/Default}} actions=\"\"\"<$action-setfield $tiddler=\"$:/state/search/currentTab\" text=<<nextTab>>/>\"\"\"/>\n\n\\procedure advanced-search-actions() <$action-setfield $tiddler=\"$:/temp/advancedsearch\" text={{$:/temp/search/input}}/><$action-setfield $tiddler=\"$:/temp/advancedsearch/input\" text={{$:/temp/search/input}}/><<delete-state-tiddlers>><$action-navigate $to=\"$:/AdvancedSearch\"/><$action-setfield $tiddler=\"$:/temp/advancedsearch/refresh\" text=\"yes\"/><$action-sendmessage $message=\"tm-focus-selector\" $param=\"\"\"[data-tiddler-title=\"$:/AdvancedSearch\"] .tc-search input\"\"\" preventScroll=\"true\"/><$action-deletetiddler $filter=\"$:/temp/search $:/temp/search/input $:/temp/search/refresh [<searchListState>]\"/>\n\n<div class=\"tc-sidebar-lists tc-sidebar-search\">\n\n<$vars editTiddler=\"$:/temp/search\" searchTiddler=\"$:/temp/search/input\" searchListState=<<qualify \"$:/state/search-list/selected-item\">>>\n<div class=\"tc-search\">\n<$keyboard key=\"((input-tab-right))\" actions=<<set-next-input-tab>>>\n<$keyboard key=\"((input-tab-left))\" actions=<<set-previous-input-tab>>>\n<$keyboard key=\"((advanced-search-sidebar))\" actions=<<advanced-search-actions>>>\n<form class=\"tc-form-inline\">\n<$transclude $variable=\"keyboard-driven-input\" tiddler=<<editTiddler>> storeTitle=<<searchTiddler>> \n\t\tselectionStateTitle=<<searchListState>> refreshTitle=\"$:/temp/search/refresh\" type=\"search\" \n\t\ttag=\"input\" focus={{$:/config/Search/AutoFocus}} focusPopup=<<qualify \"$:/state/popup/search-dropdown\">> \n\t\tclass=\"tc-tiny-gap-right tc-popup-handle\" filterMinLength={{$:/config/Search/MinLength}} inputCancelActions=<<cancel-search-actions>> \n\t\tinputAcceptActions=<<input-accept-actions>> inputAcceptVariantActions=<<input-accept-variant-actions>> cancelPopups=\"yes\" \n\t\tconfigTiddlerFilter=\"[[$:/state/search/currentTab]!is[missing]get[text]] :else[{$:/config/SearchResults/Default}]\"/>\n</form>\n</$keyboard>\n</$keyboard>\n</$keyboard>\n<$reveal state=<<searchTiddler>> type=\"nomatch\" text=\"\">\n<$button tooltip={{$:/language/Buttons/AdvancedSearch/Hint}} aria-label={{$:/language/Buttons/AdvancedSearch/Caption}} class=\"tc-btn-invisible\">\n<<advanced-search-actions>>\n{{$:/core/images/advanced-search-button}}\n</$button>\n<$button class=\"tc-btn-invisible\">\n<<cancel-search-actions>><$action-sendmessage $message=\"tm-focus-selector\" $param=\".tc-search input\"/>\n{{$:/core/images/close-button}}\n</$button>\n<<count-popup-button>>\n</$reveal>\n<$reveal state=<<searchTiddler>> type=\"match\" text=\"\">\n<$button to=\"$:/AdvancedSearch\" tooltip={{$:/language/Buttons/AdvancedSearch/Hint}} aria-label={{$:/language/Buttons/AdvancedSearch/Caption}} class=\"tc-btn-invisible\">\n{{$:/core/images/advanced-search-button}}\n</$button>\n</$reveal>\n</div>\n\n<$reveal tag=\"div\" class=\"tc-block-dropdown-wrapper\" state=<<searchTiddler>> type=\"nomatch\" text=\"\">\n\n<$reveal tag=\"div\" class=\"tc-block-dropdown tc-search-drop-down tc-popup-handle\" state=<<qualify \"$:/state/popup/search-dropdown\">> type=\"nomatch\" text=\"\" default=\"\">\n\n<<search-results-list>>\n\n</$reveal>\n\n</$reveal>\n\n</$vars>\n\n</div>\n"},"$:/core/ui/SideBarSegments/site-subtitle":{"title":"$:/core/ui/SideBarSegments/site-subtitle","tags":"$:/tags/SideBarSegment","text":"<div class=\"tc-site-subtitle\">\n\n<$transclude tiddler=\"$:/SiteSubtitle\" mode=\"inline\"/>\n\n</div>\n"},"$:/core/ui/SideBarSegments/site-title":{"title":"$:/core/ui/SideBarSegments/site-title","tags":"$:/tags/SideBarSegment","text":"<h1 class=\"tc-site-title\">\n\n<$transclude tiddler=\"$:/SiteTitle\" mode=\"inline\"/>\n\n</h1>\n"},"$:/core/ui/SideBarSegments/tabs":{"title":"$:/core/ui/SideBarSegments/tabs","tags":"$:/tags/SideBarSegment","text":"<div class=\"tc-sidebar-lists tc-sidebar-tabs\" role=\"region\" aria-label={{$:/language/SideBar/Caption}}>\n\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/SideBar]!has[draft.of]]\" default={{$:/config/DefaultSidebarTab}} state=\"$:/state/tab/sidebar\" class=\"tc-sidebar-tabs-main\" explicitState=\"$:/state/tab/sidebar--595412856\"/>\n\n</div>\n"},"$:/core/ui/PageTemplate":{"title":"$:/core/ui/PageTemplate","name":"{{$:/language/PageTemplate/Name}}","description":"{{$:/language/PageTemplate/Description}}","icon":"$:/core/images/standard-layout","code-body":"yes","text":"\\whitespace trim\n\\import [subfilter{$:/core/config/GlobalImportFilter}]\n\n<$vars\n\ttv-config-toolbar-icons={{$:/config/Toolbar/Icons}}\n\ttv-config-toolbar-text={{$:/config/Toolbar/Text}}\n\ttv-config-toolbar-class={{$:/config/Toolbar/ButtonClass}}\n\ttv-enable-drag-and-drop={{$:/config/DragAndDrop/Enable}}\n\ttv-show-missing-links={{$:/config/MissingLinks}}\n\tstoryviewTitle={{$:/view}}\n\tlanguageTitle={{{ [{$:/language}get[name]] }}}>\n\n<div class={{{ [all[shadows+tiddlers]tag[$:/tags/ClassFilters/PageTemplate]!is[draft]] :map:flat[subfilter{!!text}] tc-page-container [[tc-page-view-]addsuffix<storyviewTitle>] [[tc-language-]addsuffix<languageTitle>] :and[unique[]join[ ]] }}} >\n\n<$navigator story=\"$:/StoryList\" history=\"$:/HistoryList\" openLinkFromInsideRiver={{$:/config/Navigation/openLinkFromInsideRiver}} openLinkFromOutsideRiver={{$:/config/Navigation/openLinkFromOutsideRiver}} relinkOnRename={{$:/config/RelinkOnRename}}>\n\n<$dropzone enable=<<tv-enable-drag-and-drop>> class=\"tc-dropzone tc-page-container-inner\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/PageTemplate]!has[draft.of]]\" variable=\"listItem\">\n\n<$transclude tiddler=<<listItem>>/>\n\n</$list>\n\n</$dropzone>\n\n</$navigator>\n\n</div>\n\n</$vars>\n"},"$:/core/ui/StoryTiddlerTemplate":{"title":"$:/core/ui/StoryTiddlerTemplate","code-body":"yes","text":"<$transclude tiddler={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/StoryTiddlerTemplateFilter]!is[draft]get[text]] :and[has[title]else[$:/core/ui/ViewTemplate]] }}} />\n"},"$:/core/ui/SwitcherModal":{"title":"$:/core/ui/SwitcherModal","subtitle":"<$text text={{{[<switch>lookup[$:/language/Switcher/Subtitle/]]}}}/>","class":"tc-modal-centered","mask-closable":"yes","text":"<$tiddler tiddler={{{[<switch>lookup[$:/config/SwitcherTargets/]]}}}>\n\n\n<$transclude/>\n\n\n</$tiddler>"},"$:/TagManager":{"title":"$:/TagManager","icon":"$:/core/images/tag-button","color":"#bbb","text":"\\define lingo-base() $:/language/TagManager/\n\n\\define iconEditorTab(type)\n\\whitespace trim\n<$link to=\"\"><<lingo Icons/None>></$link>\n<$list filter=\"[all[shadows+tiddlers]is[image]] [all[shadows+tiddlers]tag[$:/tags/Image]] -[type[application/pdf]] +[sort[title]] +[$type$is[system]]\">\n\t<$link to={{!!title}}>\n\t\t<$transclude/> <$view field=\"title\"/>\n\t</$link>\n</$list>\n\\end\n\n\\define iconEditor(title)\n\\whitespace trim\n<div class=\"tc-drop-down-wrapper\">\n\t<$button popupTitle={{{ [[$:/state/popup/icon/]addsuffix<__title__>] }}} class=\"tc-btn-invisible tc-btn-dropdown\">\n\t\t{{$:/core/images/down-arrow}}\n\t</$button>\n\t<$reveal stateTitle={{{ [[$:/state/popup/icon/]addsuffix<__title__>] }}} type=\"popup\" position=\"belowleft\" text=\"\" default=\"\">\n\t\t<div class=\"tc-drop-down\">\n\t\t\t<$linkcatcher actions=\"\"\"<$action-setfield $tiddler=<<__title__>> icon=<<navigateTo>>/>\"\"\">\n\t\t\t\t<<iconEditorTab type:\"!\">>\n\t\t\t\t<hr/>\n\t\t\t\t<<iconEditorTab type:\"\">>\n\t\t\t</$linkcatcher>\n\t\t</div>\n\t</$reveal>\n</div>\n\\end\n\n\\define toggleButton(state)\n\\whitespace trim\n<$reveal stateTitle=<<__state__>> type=\"match\" text=\"closed\" default=\"closed\">\n\t<$button setTitle=<<__state__>> setTo=\"open\" class=\"tc-btn-invisible tc-btn-dropdown\" selectedClass=\"tc-selected\">\n\t\t{{$:/core/images/info-button}}\n\t</$button>\n</$reveal>\n<$reveal stateTitle=<<__state__>> type=\"match\" text=\"open\" default=\"closed\">\n\t<$button setTitle=<<__state__>> setTo=\"closed\" class=\"tc-btn-invisible tc-btn-dropdown\" selectedClass=\"tc-selected\">\n\t\t{{$:/core/images/info-button}}\n\t</$button>\n</$reveal>\n\\end\n\n\\procedure color-picker-actions()\n\\whitespace trim\n<$action-setfield $tiddler=<<currentTiddler>> color=<<colour-picker-value>>/>\n\\end\n\n\\procedure color-picker-button()\n\\whitespace trim\n<div class=\"tc-drop-down-wrapper\">\n<$button class=\"tc-btn-invisible\" popup={{{ [[$:/state/tag-manager/color/]addsuffix<currentTiddler>] }}}>{{$:/core/images/palette}}</$button>\n<$reveal type=\"popup\" tag=\"div\" class=\"tc-drop-down tc-popup-keep\" state={{{ [[$:/state/tag-manager/color/]addsuffix<currentTiddler>] }}}>\n<$transclude $variable=\"colour-picker\" actions=<<color-picker-actions>>/>\n</$reveal>\n</div>\n\\end\n\n\\whitespace trim\n<table class=\"tc-tag-manager-table\">\n<tbody>\n\t<tr>\n\t\t<th><<lingo Colour/Heading>></th>\n\t\t<th class=\"tc-tag-manager-tag\"><<lingo Tag/Heading>></th>\n\t\t<th><<lingo Count/Heading>></th>\n\t\t<th><<lingo Icon/Heading>></th>\n\t\t<th><<lingo Info/Heading>></th>\n\t</tr>\n\t<$list filter=\"[tags[]!is[system]sort[title]]\">\n\t\t<tr>\n\t\t\t<td><$transclude $variable=\"color-picker-button\"/></td>\n\t\t\t<td>{{||$:/core/ui/TagTemplate}}</td>\n\t\t\t<td><$count filter=\"[all[current]tagging[]]\"/></td>\n\t\t\t<td>\n\t\t\t\t<$macrocall $name=\"iconEditor\" title={{!!title}}/>\n\t\t\t</td>\n\t\t\t<td>\n\t\t\t\t<$macrocall $name=\"toggleButton\" state={{{ [[$:/state/tag-manager/]addsuffix<currentTiddler>] }}} />\n\t\t\t</td>\n\t\t</tr>\n\t\t<tr>\n\t\t\t<td></td>\n\t\t\t<td colspan=\"4\">\n\t\t\t\t<$reveal stateTitle={{{ [[$:/state/tag-manager/]addsuffix<currentTiddler>] }}} type=\"match\" text=\"open\" default=\"\">\n\t\t\t\t\t<table>\n\t\t\t\t\t\t<tbody>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td><<lingo Colour/Heading>></td>\n\t\t\t\t\t\t\t\t<td><$edit-text field=\"color\" tag=\"input\" type=\"text\" size=\"9\"/></td>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td><<lingo Icon/Heading>></td>\n\t\t\t\t\t\t\t\t<td><$edit-text field=\"icon\" tag=\"input\" size=\"45\"/></td>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t</tbody>\n\t\t\t\t\t</table>\n\t\t\t\t</$reveal>\n\t\t\t</td>\n\t\t</tr>\n\t</$list>\n\t<tr>\n\t\t<td></td>\n\t\t<td style=\"position:relative;\">\n\t\t\t{{$:/core/ui/UntaggedTemplate}}\n\t\t</td>\n\t\t<td>\n\t\t\t<small class=\"tc-menu-list-count\"><$count filter=\"[untagged[]!is[system]] -[tags[]]\"/></small>\n\t\t</td>\n\t\t<td></td>\n\t\t<td></td>\n\t</tr>\n</tbody>\n</table>"},"$:/core/ui/TagPickerTagTemplate":{"title":"$:/core/ui/TagPickerTagTemplate","text":"\\whitespace trim\n<$button class=<<button-classes>> tag=\"a\" tooltip={{$:/language/EditTemplate/Tags/Add/Button/Hint}}>\n\t<$list filter=\"[<saveTiddler>minlength[1]]\">\n\t\t<$action-listops $tiddler=<<saveTiddler>> $field=<<tagField>> $subfilter=\"[<tag>]\"/>\n\t</$list>\n\t<$set name=\"currentTiddlerCSSEscaped\" value={{{ [<saveTiddler>escapecss[]] }}}>\n\t\t<$action-sendmessage $message=\"tm-focus-selector\" $param=<<get-tagpicker-focus-selector>> preventScroll=\"true\"/>\n\t</$set>\n\t<<delete-tag-state-tiddlers>>\n\t<$list filter=\"[<refreshTitle>minlength[1]]\">\n\t\t<$action-setfield $tiddler=<<refreshTitle>> text=\"yes\"/>\n\t</$list>\n\t<<actions>>\n\t<$set name=\"backgroundColor\"\n\t\tvalue={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}}\n\t>\n\t\t<$wikify name=\"foregroundColor\"\n\t\t\ttext=\"\"\"<$macrocall $name=\"contrastcolour\" target=<<backgroundColor>> fallbackTarget=<<fallbackTarget>> colourA=<<colourA>> colourB=<<colourB>>/>\"\"\"\n\t\t>\n\t\t\t<span class=\"tc-tag-label tc-btn-invisible\"\n\t\t\t\tstyle=<<tag-pill-styles>>\n\t\t\t\tdata-tag-title=<<currentTiddler>>\n\t\t\t>\n\t\t\t\t{{||$:/core/ui/TiddlerIcon}}<$view field=\"title\" format=\"text\"/>\n\t\t\t</span>\n\t\t</$wikify>\n\t</$set>\n</$button>\n"},"$:/core/ui/TagTemplate":{"title":"$:/core/ui/TagTemplate","text":"\\whitespace trim\n<span class=\"tc-tag-list-item\" data-tag-title=<<currentTiddler>>>\n<$set name=\"transclusion\" value=<<currentTiddler>>>\n\t<$macrocall $name=\"tag-pill-body\"\n\t\ttag=<<currentTiddler>>\n\t\ticon={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerIconFilter]!is[draft]get[text]] }}}\n\t\tcolour={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}}\n\t\tpalette={{$:/palette}}\n\t\telement-tag=\"$button\"\n\t\telement-attributes=\"\"\"popup=<<qualify \"$:/state/popup/tag\">> dragFilter=\"[subfilter{$:/core/config/TagPillDragFilter}]\" tag='span'\"\"\"\n\t/>\n\t<$reveal state=<<qualify \"$:/state/popup/tag\">> type=\"popup\" position=\"below\" animate=\"yes\" class=\"tc-drop-down\">\n\t\t<$set name=\"tv-show-missing-links\" value=\"yes\">\n\t\t\t<$transclude tiddler=\"$:/core/ui/ListItemTemplate\"/>\n\t\t</$set>\n\t\t<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/TagDropdown]!has[draft.of]]\" variable=\"listItem\"> \n\t\t\t<$transclude tiddler=<<listItem>>/> \n\t\t</$list>\n\t\t<hr>\n\t\t<$macrocall $name=\"list-tagged-draggable\" tag=<<currentTiddler>>/>\n\t</$reveal>\n</$set>\n</span>\n"},"$:/core/ui/TestCaseTemplate":{"title":"$:/core/ui/TestCaseTemplate","text":"\\parameters (hideIfPass:\"no\")\n\\whitespace trim\n<$let\n\tlinkTarget=\"yes\"\n\tdisplayFormat={{!!display-format}}\n\ttestcaseTiddler=<<currentTiddler>>\n>\n\t<$testcase\n\t\ttestOutput=\"Output\"\n\t\ttestExpectedResult=\"ExpectedResult\"\n\t\ttestActions=\"Actions\"\n\t\ttestHideIfPass=<<hideIfPass>>\n\t>\n\t\t<$data $filter={{!!import}}/>\n\t\t<$data $compound-filter={{!!import-compound}}/>\n\t\t<$data $compound-tiddler=<<currentTiddler>>/>\n\t\t<%if [{!!description}!is[blank]] %><$data title=\"Description\" text={{!!description}}/><%endif%>\n\t</$testcase>\n</$let>\n"},"$:/core/ui/testcases/DefaultTemplate":{"title":"$:/core/ui/testcases/DefaultTemplate","code-body":"yes","text":"\\whitespace trim\n\n\\function tf.state() \"$:/state/testcase\"\n\n\\procedure linkcatcherActions()\n<%if [<navigateTo>has[title]] %>\n\t<$action-setfield $tiddler=<<tf.state>> text=<<navigateTo>>/>\n<%endif%>\n\\end\n\n\\procedure testcase-header()\n<div class=\"tc-test-case-header\">\n\t<h2>\n\t\t<$genesis $type={{{ [<linkTarget>!match[]then[$link]else[span]] }}} to=<<testcaseTiddler>>>\n\t\t\t<%if [<testResult>!match[]] %>\n\t\t\t\t<span class={{{ tc-test-case-result-icon\n\t\t\t\t\t[<testResult>!match[fail]then[tc-test-case-result-icon-pass]]\n\t\t\t\t\t[<testResult>match[fail]then[tc-test-case-result-icon-fail]]\n\t\t\t\t\t+[join[ ]] }}}\n\t\t\t\t>\n\t\t\t\t\t<%if [<testResult>!match[fail]] %>\n\t\t\t\t\t\t{{$:/core/images/done-button}}\n\t\t\t\t\t<%else%>\n\t\t\t\t\t\t{{$:/core/images/close-button}}\n\t\t\t\t\t<%endif%>\n\t\t\t\t</span>\n\t\t\t<%endif%>\n\t\t\t<$view tiddler=\"Description\" mode=\"inline\"/>\n\t\t</$genesis>\n\t\t<span class=\"tc-test-case-toolbar\">\n\t\t\t<<testcase-toolbar>>\n\t\t</span>\n\t</h2>\n</div>\n\\end\n\n\\procedure testcase-toolbar()\n<$button popup=`$(tf.state)$-more`\n\ttooltip={{$:/language/Buttons/More/Hint}}\n\taria-label={{$:/language/Buttons/More/Caption}}\n\tclass=\"tc-btn-invisible\"\n\tselectedClass=\"tc-selected\"\n>\n\t{{$:/core/images/down-arrow}}\n</$button>\n<$let\n\ttv-config-toolbar-icons=\"yes\"\n\ttv-config-toolbar-text=\"yes\"\n\ttv-config-toolbar-class=\"tc-btn-invisible\"\n>\n\t<$reveal state=`$(tf.state)$-more` type=\"popup\" position=\"belowleft\" animate=\"yes\">\n\t\t<div class=\"tc-drop-down\">\n\t\t\t<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/TestCase/Actions]!has[draft.of]]\"\n\t\t\t\tvariable=\"listItem\"\n\t\t\t>\n\t\t\t\t<$transclude $tiddler=<<listItem>> $mode=\"inline\"/>\n\t\t\t</$list>\n\t\t</div>\n\t</$reveal>\n</$let>\n\\end\n\n\\procedure testcase-narrative()\n<div class=\"tc-test-case-narrative\">\n\t<$transclude $tiddler=\"Narrative\" $mode=\"block\"/>\n</div>\n\\end\n\n\\procedure testcase-fail()\n<div class=\"tc-test-case-result-fail\">\n\t<div class=\"tc-test-case-result-fail-header\">\n\t\tTEST FAILED\n\t</div>\n\t<div class=\"tc-test-case-result-fail-body\">\n\t\t<$diff-text source=<<expectedHTML>> dest=<<outputHTML>>/>\n\t</div>\n</div>\n\\end\n\n\\procedure testcase-output-wikified()\n<$linkcatcher actions=<<linkcatcherActions>>>\n\t<$tiddler tiddler=\"Output\">\n\t\t<$transclude $tiddler=\"Output\" $mode=\"block\"/>\n\t</$tiddler>\n</$linkcatcher>\n\\end\n\n\\procedure testcase-output()\n<div class=\"tc-test-case-output\">\n\t<%if [<displayFormat>!match[]else[wikitext]match[plaintext]] %>\n\t\t<pre><$view tiddler=\"Output\" format=\"plainwikified\" mode=\"block\"/></pre>\n\t<%else%>\n\t\t<<testcase-output-wikified>>\n\t<%endif%>\n</div>\n\\end\n\n\\procedure testcase-tabsList()\n[all[tiddlers]sort[]] Output +[putfirst[]]\n-Description\n-Narrative\n-[[$:/temp/testcase/draft-title]]\n-[has[plugin-type]]\n-[prefix<tf.state>]\n-[prefix[$:/state/popup/export]]\n-[prefix[$:/HistoryList]]\n-[prefix[$:/StoryList]]\n\\end\n\n\\procedure testcase-source()\n<div class=\"tc-test-case-source\">\n\t<$macrocall $name=\"tabs\"\n\t\ttabsList=<<testcase-tabsList>>\n\t\texplicitState=<<tf.state>>\n\t\tdefault=\"Output\"\n\t\ttemplate=\"$:/core/ui/testcases/DefaultTemplate/SourceTabs\"\n\t/>\n</div>\n\\end\n\n\\procedure testcase-panes()\n<div class=\"tc-test-case-panes\">\n\t<<testcase-source>>\n\t<div class=\"tc-test-case-divider\"></div>\n\t<<testcase-output>>\n</div>\n\\end\n\n\\procedure testcase-body()\n<div class=\"tc-test-case-wrapper\">\n\t<<testcase-header>>\n\t<$let testcase-source-state = <<tf.state>>>\n\t\t<$navigator story=\"$:/StoryList\" history=\"$:/HistoryList\">\n\t\t\t<%if [[Narrative]is[tiddler]] %>\n\t\t\t\t<<testcase-narrative>>\n\t\t\t<%endif%>\n\t\t\t<%if [<testResult>match[fail]] %>\n\t\t\t\t<<testcase-fail>>\n\t\t\t<%endif%>\n\t\t\t<<testcase-panes>>\n\t\t</$navigator>\n\t</$let>\n</div>\n\\end\n\n<<testcase-body>>"},"$:/core/ui/testcases/DefaultTemplate/SourceTabs":{"title":"$:/core/ui/testcases/DefaultTemplate/SourceTabs","text":"\\whitespace trim\n\n\\procedure testcaseNewTitle() $:/temp/testcase/draft-title\n\n\\procedure saveActions()\n<$action-setfield $tiddler=<<currentTab>> $field=\"draft.title\" $value=<<newTitle>>/>\n<$action-sendmessage $message=\"tm-save-tiddler\" $param=<<title>> />\n<$action-setfield $tiddler=<<testcase-source-state>> text=<<newTitle>>/>\n<$action-deletetiddler $tiddler=<<testcaseNewTitle>>/>\n\\end\n\n\\procedure saveButton(title, newTitle)\n<$button class=\"tc-btn-invisible tc-test-case-save-button tc-small-gap-left\" actions=<<saveActions>> disabled={{{ [<testcaseNewTitle>!has[text]then[yes]] }}}>\n{{$:/core/images/done-button}}\n</$button>\n\\end\n\n\\procedure body()\n<$list filter=\"[<currentTab>fields[]] -text +[limit[1]]\" variable=\"ignore\">\n\t<table class=\"tc-field-table\">\n\t\t<tbody>\n\t\t\t<$list filter=\"[<currentTab>fields[]sort[]] -text -title title +[putfirst[]]\" variable=\"fieldName\">\n\t\t\t\t<tr>\n\t\t\t\t\t<td>\n\t\t\t\t\t\t<$text text=<<fieldName>>/>\n\t\t\t\t\t</td>\n\t\t\t\t\t<td>\n\t\t\t\t\t\t<%if [<fieldName>match[draft.title]]  %>\n\t\t\t\t\t\t\t<$edit-text class=\"tc-edit-texteditor tc-max-width-80\" tiddler=<<testcaseNewTitle>> focus=\"yes\" tag=\"input\"/>\n\t\t\t\t\t\t\t<$macrocall $name=\"saveButton\" newTitle={{{ [<testcaseNewTitle>get[text]] }}} title=<<currentTab>>/>\n\t\t\t\t\t\t<%else%>\n\t\t\t\t\t\t\t<$view tiddler=<<currentTab>> field=<<fieldName>>/>\n\t\t\t\t\t\t<%endif%>\n\t\t\t\t\t</td>\n\t\t\t\t</tr>\n\t\t\t</$list>\n\t\t</tbody>\n\t</table>\n</$list>\n<$edit class=\"tc-edit-texteditor\" tiddler=<<currentTab>>/>\n<div class=\"tc-test-case-footer-toolbar\">\n<$macrocall $name=\"copy-to-clipboard\" src={{{ [<currentTab>get[text]] }}}/>\n</div>\n\\end\n\n<$transclude $variable=\"body\" $mode=\"inline\"/>\n"},"$:/core/ui/testcases/RawJSONTemplate":{"title":"$:/core/ui/testcases/RawJSONTemplate","text":"\\whitespace trim\n<$text text=<<payloadTiddlers>>/>\n"},"$:/core/ui/testcases/actions/Export":{"title":"$:/core/ui/testcases/actions/Export","tags":"$:/tags/TestCase/Actions","text":"<$macrocall $name=\"exportButton\" exportFilter=\"[all[tiddlers]sort[]] -[prefix[$:/state/]] -Description -Narrative -ExpectedResult -[has[plugin-type]]\" lingoBase=\"$:/language/Buttons/ExportTiddlers/\"/>"},"$:/core/ui/testcases/actions/Import":{"title":"$:/core/ui/testcases/actions/Import","tags":"$:/tags/TestCase/Actions","text":"\\whitespace trim\n<$button tooltip={{$:/language/Buttons/TestCaseImport/Hint}} aria-label={{$:/language/Buttons/TestCaseImport/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-sendmessage $message=\"tm-import-tiddlers\" $param=<<payloadTiddlers>>/>\n{{$:/core/images/input-button}}\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/TestCaseImport/Caption}}/>\n</span>\n</$button>\n"},"$:/core/ui/TiddlerFieldTemplate":{"title":"$:/core/ui/TiddlerFieldTemplate","text":"\\whitespace trim\n<tr class=\"tc-view-field\">\n<td class=\"tc-view-field-name\">\n<$text text=<<listItem>>/>\n</td>\n<td class=\"tc-view-field-value\">\n<$view field=<<listItem>>/>\n</td>\n</tr>"},"$:/core/ui/TiddlerFields":{"title":"$:/core/ui/TiddlerFields","text":"\\whitespace trim\n<table class=\"tc-view-field-table\">\n<tbody>\n<$list filter=\"[all[current]fields[]sort[title]] -text\" template=\"$:/core/ui/TiddlerFieldTemplate\" variable=\"listItem\"/>\n</tbody>\n</table>\n"},"$:/core/ui/TiddlerIcon":{"title":"$:/core/ui/TiddlerIcon","text":"\\whitespace trim\n<$let tiddlerIcon={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerIconFilter]!is[draft]get[text]] }}}>\n<$list filter=\"[<tiddlerIcon>!is[blank]]\" variable=\"ignore\">\n<$transclude tiddler=<<tiddlerIcon>>/>\n</$list>\n</$let>\n"},"$:/core/ui/TiddlerInfo/Advanced/PluginInfo":{"title":"$:/core/ui/TiddlerInfo/Advanced/PluginInfo","tags":"$:/tags/TiddlerInfo/Advanced","text":"\\define lingo-base() $:/language/TiddlerInfo/Advanced/PluginInfo/\n\\whitespace trim\n<$list filter=\"[all[current]has[plugin-type]]\">\n\n! <<lingo Heading>>\n\n<<lingo Hint>>\n<ul>\n<$list filter=\"[all[current]plugintiddlers[]sort[title]]\" emptyMessage=<<lingo Empty/Hint>>>\n<li>\n<$link to={{!!title}}>\n<$view field=\"title\"/>\n</$link>\n</li>\n</$list>\n</ul>\n\n</$list>\n"},"$:/core/ui/TiddlerInfo/Advanced/ShadowInfo":{"title":"$:/core/ui/TiddlerInfo/Advanced/ShadowInfo","tags":"$:/tags/TiddlerInfo/Advanced","text":"\\define lingo-base() $:/language/TiddlerInfo/Advanced/ShadowInfo/\n<$set name=\"infoTiddler\" value=<<currentTiddler>>>\n\n''<<lingo Heading>>''\n\n<$list filter=\"[all[current]!is[shadow]]\">\n\n<<lingo NotShadow/Hint>>\n\n</$list>\n\n<$list filter=\"[all[current]is[shadow]]\">\n\n<<lingo Shadow/Hint>>\n\n<$list filter=\"[all[current]shadowsource[]]\">\n\n<$set name=\"pluginTiddler\" value=<<currentTiddler>>>\n\n<<lingo Shadow/Source>>\n</$set>\n\n</$list>\n\n<$list filter=\"[all[current]is[shadow]is[tiddler]]\">\n\n<<lingo OverriddenShadow/Hint>>\n\n</$list>\n\n\n</$list>\n</$set>\n"},"$:/core/ui/TiddlerInfo/Advanced":{"title":"$:/core/ui/TiddlerInfo/Advanced","tags":"$:/tags/TiddlerInfo","caption":"{{$:/language/TiddlerInfo/Advanced/Caption}}","text":"<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/TiddlerInfo/Advanced]!has[draft.of]]\" variable=\"listItem\">\n\n<$transclude tiddler=<<listItem>> mode=\"block\"/>\n\n</$list>\n"},"$:/core/ui/TiddlerInfo/Fields":{"title":"$:/core/ui/TiddlerInfo/Fields","tags":"$:/tags/TiddlerInfo","caption":"{{$:/language/TiddlerInfo/Fields/Caption}}","text":"<$transclude tiddler=\"$:/core/ui/TiddlerFields\"/>\n"},"$:/core/ui/TiddlerInfo/List":{"title":"$:/core/ui/TiddlerInfo/List","tags":"$:/tags/TiddlerInfo","caption":"{{$:/language/TiddlerInfo/List/Caption}}","text":"\\define lingo-base() $:/language/TiddlerInfo/\n<$list filter=\"[list{!!title}]\" emptyMessage=<<lingo List/Empty>> template=\"$:/core/ui/ListItemTemplate\"/>\n"},"$:/core/ui/TiddlerInfo/Listed":{"title":"$:/core/ui/TiddlerInfo/Listed","tags":"$:/tags/TiddlerInfo","caption":"{{$:/language/TiddlerInfo/Listed/Caption}}","text":"\\define lingo-base() $:/language/TiddlerInfo/\n<$list filter=\"[all[current]listed[]!is[system]]\" emptyMessage=<<lingo Listed/Empty>> template=\"$:/core/ui/ListItemTemplate\"/>\n"},"$:/core/ui/TiddlerInfo/References":{"title":"$:/core/ui/TiddlerInfo/References","tags":"$:/tags/TiddlerInfo","caption":"{{$:/language/TiddlerInfo/References/Caption}}","text":"\\define lingo-base() $:/language/TiddlerInfo/\n<$list filter=\"[all[current]backlinks[]sort[title]]\" emptyMessage=<<lingo References/Empty>> template=\"$:/core/ui/ListItemTemplate\">\n</$list>"},"$:/core/ui/TiddlerInfo/Tagging":{"title":"$:/core/ui/TiddlerInfo/Tagging","tags":"$:/tags/TiddlerInfo","caption":"{{$:/language/TiddlerInfo/Tagging/Caption}}","text":"\\define lingo-base() $:/language/TiddlerInfo/\n<$list filter=\"[all[current]tagging[]]\" emptyMessage=<<lingo Tagging/Empty>> template=\"$:/core/ui/ListItemTemplate\"/>\n"},"$:/core/ui/TiddlerInfo/Tools":{"title":"$:/core/ui/TiddlerInfo/Tools","tags":"$:/tags/TiddlerInfo","caption":"{{$:/language/TiddlerInfo/Tools/Caption}}","text":"\\define lingo-base() $:/language/TiddlerInfo/\n\\define config-title()\n$:/config/ViewToolbarButtons/Visibility/$(listItem)$\n\\end\n<$set name=\"tv-config-toolbar-icons\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-text\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-class\" value=\"\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/ViewToolbar]!has[draft.of]]\" variable=\"listItem\">\n\n<$checkbox tiddler=<<config-title>> field=\"text\" checked=\"show\" unchecked=\"hide\" default=\"show\"/> <$transclude tiddler=<<listItem>>/> <i class=\"tc-muted\"><$transclude tiddler=<<listItem>> field=\"description\"/></i>\n\n</$list>\n\n</$set>\n\n</$set>\n\n</$set>\n"},"$:/core/ui/TiddlerInfo":{"title":"$:/core/ui/TiddlerInfo","text":"\\whitespace trim\n<div style=\"position:relative;\">\n<div class=\"tc-tiddler-controls\" style=\"position:absolute;right:0;\">\n<$reveal state=\"$:/config/TiddlerInfo/Mode\" type=\"match\" text=\"sticky\">\n<$button set=<<tiddlerInfoState>> setTo=\"\" tooltip={{$:/language/Buttons/Info/Hint}} aria-label={{$:/language/Buttons/Info/Caption}} class=\"tc-btn-invisible\">\n{{$:/core/images/close-button}}\n</$button>\n</$reveal>\n</div>\n</div>\n\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/TiddlerInfo]!has[draft.of]]\" default={{$:/config/TiddlerInfo/Default}}/>\n"},"$:/core/ui/TopBar/menu":{"title":"$:/core/ui/TopBar/menu","tags":"$:/tags/TopRightBar","text":"\\whitespace trim\n<$list filter=\"[[$:/state/sidebar]get[text]] +[else[yes]!match[no]]\" variable=\"ignore\">\n<$button set=\"$:/state/sidebar\" setTo=\"no\" tooltip={{$:/language/Buttons/HideSideBar/Hint}} aria-label={{$:/language/Buttons/HideSideBar/Caption}} class=\"tc-btn-invisible tc-hide-sidebar-btn\">{{$:/core/images/chevron-right}}</$button>\n</$list>\n<$list filter=\"[[$:/state/sidebar]get[text]] +[else[yes]match[no]]\" variable=\"ignore\">\n<$button set=\"$:/state/sidebar\" setTo=\"yes\" tooltip={{$:/language/Buttons/ShowSideBar/Hint}} aria-label={{$:/language/Buttons/ShowSideBar/Caption}} class=\"tc-btn-invisible tc-show-sidebar-btn\">{{$:/core/images/chevron-left}}</$button>\n</$list>\n"},"$:/core/ui/UntaggedTemplate":{"title":"$:/core/ui/UntaggedTemplate","text":"\\define lingo-base() $:/language/SideBar/\n\\whitespace trim\n<$button popup=<<qualify \"$:/state/popup/tag\">> class=\"tc-btn-invisible tc-untagged-label tc-tag-label\">\n\t<<lingo Tags/Untagged/Caption>>\n</$button>\n<$reveal class=\"tc-drop-down\" tag=\"div\" state=<<qualify \"$:/state/popup/tag\">> type=\"popup\" position=\"below\">\n\t<$list filter=\"[untagged[]!is[system]] -[tags[]] +[sort[title]]\" template=\"$:/core/ui/ListItemTemplate\"/>\n</$reveal>\n"},"$:/core/ui/ViewTemplate/body/blank":{"title":"$:/core/ui/ViewTemplate/body/blank","text":"<!-- Intentionally blank -->\n"},"$:/core/ui/ViewTemplate/body/code":{"title":"$:/core/ui/ViewTemplate/body/code","text":"<%if [<currentTiddler>is[missing]] :and[!is[shadow]] %>\n<$transclude tiddler=\"$:/language/MissingTiddler/Hint\"/>\n<%else%>\n<$transclude $variable=\"copy-to-clipboard-above-right\" src={{{ [<currentTiddler>get[text]] }}} />\n<$codeblock code={{{ [<currentTiddler>get[text]] }}} language={{{ [<currentTiddler>get[type]else[text/vnd.tiddlywiki]] }}}/>\n<%endif%>"},"$:/core/ui/ViewTemplate/body/default":{"title":"$:/core/ui/ViewTemplate/body/default","code-body":"yes","text":"<$transclude>\n\n<$transclude tiddler=\"$:/language/MissingTiddler/Hint\"/>\n\n</$transclude>\n"},"$:/core/ui/ViewTemplate/body/import":{"title":"$:/core/ui/ViewTemplate/body/import","text":"\\define lingo-base() $:/language/Import/\n\n\\define confirmCancel()\n\\whitespace trim\n<$action-confirm $message={{$:/language/Import/Listing/Cancel/Warning}} >\n<$action-deletetiddler $tiddler=<<currentTiddler>>/>\n<$action-deletetiddler $tiddler=\"$:/state/import/select-all\"/>\n<$action-sendmessage $message=\"tm-close-tiddler\" title=<<currentTiddler>>/>\n</$action-confirm>\n\\end\n\n\\define buttons()\n\\whitespace trim\n<$button actions=<<confirmCancel>> ><<lingo Listing/Cancel/Caption>></$button>\n&#32;\n<$button message=\"tm-perform-import\" param=<<currentTiddler>>><<lingo Listing/Import/Caption>></$button>\n&#32;\n<<lingo Listing/Preview>>&#32;<$select tiddler=\"$:/state/importpreviewtype\" default=\"$:/core/ui/ImportPreviews/Text\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/ImportPreview]!has[draft.of]]\">\n<option value=<<currentTiddler>>>{{!!caption}}</option>\n</$list>\n</$select>\n\\end\n\\whitespace trim\n\n<$list filter=\"[all[current]field:plugin-type[import]]\">\n\n<div class=\"tc-import\">\n\n<<lingo Listing/Hint>>\n\n<<buttons>>\n\n{{||$:/core/ui/ImportListing}}\n\n<<buttons>>\n\n</div>\n\n</$list>\n"},"$:/core/ui/ViewTemplate/body/plugin":{"title":"$:/core/ui/ViewTemplate/body/plugin","text":"\\whitespace trim\n<div class=\"tc-tiddler-plugin-info\">\n<$let plugin-type={{!!plugin-type}}\n\tdefault-popup-state=\"yes\"\n\tqualified-state=<<qualify \"$:/state/plugin-info\">>\n>\n{{||$:/core/ui/Components/plugin-info}}\n</$let>\n</div>"},"$:/core/ui/ViewTemplate/body/rendered-plain-text":{"title":"$:/core/ui/ViewTemplate/body/rendered-plain-text","code-body":"yes","text":"\\whitespace trim\n<$wikify name=\"text\" text={{!!text}} type={{!!type}}>\n<$codeblock code=<<text>> language=\"css\"/>\n</$wikify>\n"},"$:/core/ui/ViewTemplate/body":{"title":"$:/core/ui/ViewTemplate/body","tags":"$:/tags/ViewTemplate","text":"\\import [all[shadows+tiddlers]tag[$:/tags/Macro/View/Body]!is[draft]] [all[shadows+tiddlers]tag[$:/tags/Global/View/Body]!is[draft]]\n\n<$reveal tag=\"div\" class=\"tc-tiddler-body tc-clearfix\" type=\"nomatch\" stateTitle=<<folded-state>> text=\"hide\" retain=\"yes\" animate=\"yes\">\n\n<$transclude tiddler={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/ViewTemplateBodyFilter]!is[draft]get[text]] :and[!is[blank]else[$:/core/ui/ViewTemplate/body/default]] }}} />\n\n</$reveal>\n"},"$:/core/ui/ViewTemplate/classic":{"title":"$:/core/ui/ViewTemplate/classic","tags":"$:/tags/ViewTemplate $:/tags/EditTemplate","text":"\\define lingo-base() $:/language/ClassicWarning/\n\\whitespace trim\n<$list filter=\"[all[current]type[text/x-tiddlywiki]]\">\n<div class=\"tc-message-box\">\n\n<<lingo Hint>>\n\n<$button set=\"!!type\" setTo=\"text/vnd.tiddlywiki\"><<lingo Upgrade/Caption>></$button>\n\n</div>\n</$list>\n"},"$:/core/ui/ViewTemplate/lazy-loading":{"title":"$:/core/ui/ViewTemplate/lazy-loading","tags":"$:/tags/ViewTemplate","text":"\\whitespace trim\n<%if [<currentTiddler>has:field[_is_skinny]] %>\n  <!-- Render the text to trigger lazy-loading -->\n  {{||$:/core/ui/ViewTemplate/body/default}}\n  <!-- Indicator of loading state -->\n  <div class=\"tc-tiddler-lazy-loading\" />\n<%endif%>\n"},"$:/core/ui/ViewTemplate/subtitle/default":{"title":"$:/core/ui/ViewTemplate/subtitle/default","text":"\\whitespace trim\n<$reveal type=\"nomatch\" stateTitle=<<folded-state>> text=\"hide\" tag=\"div\" retain=\"yes\" animate=\"yes\">\n<div class=\"tc-subtitle tc-clearfix\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/ViewTemplate/Subtitle]!has[draft.of]]\" variable=\"subtitleTiddler\">\n<$transclude tiddler=<<subtitleTiddler>> mode=\"inline\"/>\n</$list>\n</div>\n</$reveal>\n"},"$:/core/ui/ViewTemplate/subtitle/modified":{"title":"$:/core/ui/ViewTemplate/subtitle/modified","tags":"$:/tags/ViewTemplate/Subtitle","text":"<$view field=\"modified\" format=\"date\" template={{$:/language/Tiddler/DateFormat}}/>"},"$:/core/ui/ViewTemplate/subtitle/modifier":{"title":"$:/core/ui/ViewTemplate/subtitle/modifier","tags":"$:/tags/ViewTemplate/Subtitle","text":"<%if [{!!modifier}!is[blank]] %><$link to={{!!modifier}}/><%endif%>"},"$:/core/ui/ViewTemplate/subtitle":{"title":"$:/core/ui/ViewTemplate/subtitle","tags":"$:/tags/ViewTemplate","text":"\\whitespace trim\n<$transclude tiddler={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/ViewTemplateSubtitleFilter]!is[draft]get[text]] :and[!is[blank]else[$:/core/ui/ViewTemplate/subtitle/default]] }}} />"},"$:/core/ui/ViewTemplate/tags/default":{"title":"$:/core/ui/ViewTemplate/tags/default","text":"\\whitespace trim\n<$reveal type=\"nomatch\" stateTitle=<<folded-state>> text=\"hide\" tag=\"div\" retain=\"yes\" animate=\"yes\">\n  <div class=\"tc-tags-wrapper\">\n    <$list filter=\"[all[current]tags[]sort[title]]\" template=\"$:/core/ui/TagTemplate\" storyview=\"pop\"/>\n    <$list filter=\"[all[shadows+tiddlers]tag[$:/tags/ViewTemplate/Tags]!has[draft.of]]\">\n      <$transclude mode=\"inline\"/>\n    </$list>\n  </div>\n</$reveal>\n"},"$:/core/ui/ViewTemplate/tags":{"title":"$:/core/ui/ViewTemplate/tags","tags":"$:/tags/ViewTemplate","text":"\\whitespace trim\n<$transclude tiddler={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/ViewTemplateTagsFilter]!is[draft]get[text]] :and[!is[blank]else[$:/core/ui/ViewTemplate/tags/default]] }}} />"},"$:/core/ui/ViewTemplate/title/default":{"title":"$:/core/ui/ViewTemplate/title/default","text":"\\whitespace trim\n<h2 class=\"tc-title\">\n<$view field=\"title\"/>\n</h2>\n"},"$:/core/ui/ViewTemplate/title/system":{"title":"$:/core/ui/ViewTemplate/title/system","text":"\\whitespace trim\n<h2 class=\"tc-title\" title={{$:/language/SystemTiddler/Tooltip}}>\n<span class=\"tc-system-title-prefix\">$:/</span><$text text={{{ [<currentTiddler>removeprefix[$:/]] }}}/>\n</h2>"},"$:/core/ui/ViewTemplate/title":{"title":"$:/core/ui/ViewTemplate/title","tags":"$:/tags/ViewTemplate","text":"\\whitespace trim\n\\define title-styles() fill:$(foregroundColor)$;\n\n<div class=\"tc-tiddler-title tc-clearfix\">\n\t<div class=\"tc-titlebar\">\n\t\t<span class=\"tc-tiddler-controls\">\n\t\t\t<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/ViewToolbar]!has[draft.of]] :filter[lookup[$:/config/ViewToolbarButtons/Visibility/]!match[hide]]\"\n\t\t\t\tstoryview=\"pop\"\n\t\t\t\tvariable=\"listItem\"\n\t\t\t>\n\t\t\t\t<$set name=\"tv-config-toolbar-class\" filter=\"[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]\">\n\t\t\t\t\t<$transclude tiddler=<<listItem>>/>\n\t\t\t\t</$set>\n\t\t\t</$list>\n\t\t</span>\n\t\t<$set name=\"tv-wikilinks\" value={{$:/config/Tiddlers/TitleLinks}}>\n\t\t\t<$link>\n\t\t\t\t<$list filter=\"[<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerIconFilter]!is[draft]get[text]] +[!is[blank]]\"\n\t\t\t\t\tvariable=\"ignore\"\n\t\t\t\t>\n\t\t\t\t\t<$let foregroundColor={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}}>\n\t\t\t\t\t\t<span class=\"tc-tiddler-title-icon\" style=<<title-styles>>>\n\t\t\t\t\t\t\t{{||$:/core/ui/TiddlerIcon}}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</$let>\n\t\t\t\t</$list>\n\t\t\t\t<$transclude tiddler={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/ViewTemplateTitleFilter]!is[draft]get[text]] :and[!is[blank]else[$:/core/ui/ViewTemplate/title/default]] }}} />\n\t\t\t</$link>\n\t\t</$set>\n\t</div>\n\t<$reveal tag=\"div\" type=\"nomatch\" text=\"\" default=\"\" state=<<tiddlerInfoState>> class=\"tc-tiddler-info tc-popup-handle\" animate=\"yes\" retain=\"yes\">\n\t\t<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/TiddlerInfoSegment]!has[draft.of]] [[$:/core/ui/TiddlerInfo]]\" variable=\"listItem\">\n\t\t\t<$transclude tiddler=<<listItem>> mode=\"block\"/>\n\t\t</$list>\n\t</$reveal>\n</div>\n"},"$:/core/ui/ViewTemplate/unfold":{"title":"$:/core/ui/ViewTemplate/unfold","tags":"$:/tags/ViewTemplate","text":"\\whitespace trim\n<div class=\"tc-reveal\">\n<$list filter=\"[{$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold-bar}match[show]]\" variable=\"ignore\">\n<$reveal tag=\"div\" type=\"nomatch\" stateTitle=<<folded-state>> text=\"hide\" default=\"show\" retain=\"yes\" animate=\"yes\">\n<$button tooltip={{$:/language/Buttons/Fold/Hint}} aria-label={{$:/language/Buttons/Fold/Caption}} class=\"tc-fold-banner\">\n<$action-sendmessage $message=\"tm-fold-tiddler\" $param=<<currentTiddler>> foldedState=<<folded-state>>/>\n{{$:/core/images/chevron-up}}\n</$button>\n</$reveal>\n</$list>\n<$list filter=\"[{$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold-bar}match[show]] :else[<folded-state>get[text]match[hide]]\" variable=\"ignore\">\n<$reveal tag=\"div\" type=\"nomatch\" stateTitle=<<folded-state>> text=\"show\" default=\"show\" retain=\"yes\" animate=\"yes\">\n<$button tooltip={{$:/language/Buttons/Unfold/Hint}} aria-label={{$:/language/Buttons/Unfold/Caption}} class=\"tc-unfold-banner\">\n<$action-sendmessage $message=\"tm-fold-tiddler\" $param=<<currentTiddler>> foldedState=<<folded-state>>/>\n{{$:/core/images/chevron-down}}\n</$button>\n</$reveal>\n</$list>\n</div>"},"$:/core/ui/ViewTemplate":{"title":"$:/core/ui/ViewTemplate","code-body":"yes","text":"\\whitespace trim\n\\define folded-state()\n$:/state/folded/$(currentTiddler)$\n\\end\n\\define cancel-delete-tiddler-actions(message) <$action-sendmessage $message=\"tm-$message$-tiddler\"/>\n\\import [all[shadows+tiddlers]tag[$:/tags/Macro/View]!is[draft]] [all[shadows+tiddlers]tag[$:/tags/Global/View]!is[draft]]\n<$vars storyTiddler=<<currentTiddler>> tiddlerInfoState=<<qualify \"$:/state/popup/tiddler-info\">>>\n<div data-tiddler-title=<<currentTiddler>> data-tags={{!!tags}} class={{{ [all[shadows+tiddlers]tag[$:/tags/ClassFilters/TiddlerTemplate]!is[draft]] :map:flat[subfilter{!!text}] tc-tiddler-frame tc-tiddler-view-frame [<currentTiddler>is[tiddler]then[tc-tiddler-exists]] [<currentTiddler>is[missing]!is[shadow]then[tc-tiddler-missing]] [<currentTiddler>is[shadow]then[tc-tiddler-exists tc-tiddler-shadow]] [<currentTiddler>is[shadow]is[tiddler]then[tc-tiddler-overridden-shadow]] [<currentTiddler>is[system]then[tc-tiddler-system]] [{!!class}] [<currentTiddler>tags[]encodeuricomponent[]addprefix[tc-tagged-]] +[join[ ]] }}} role=\"article\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/ViewTemplate]!is[draft]]\" variable=\"listItem\">\n<$transclude tiddler=<<listItem>>/>\n</$list>\n</div>\n</$vars>\n"},"$:/core/ui/Buttons/clone":{"title":"$:/core/ui/Buttons/clone","tags":"$:/tags/ViewToolbar","caption":"{{$:/core/images/clone-button}} {{$:/language/Buttons/Clone/Caption}}","description":"{{$:/language/Buttons/Clone/Hint}}","text":"\\whitespace trim\n<$button message=\"tm-new-tiddler\"\n\tparam=<<currentTiddler>>\n\ttooltip={{$:/language/Buttons/Clone/Hint}}\n\taria-label={{$:/language/Buttons/Clone/Hint}}\n\tclass=<<tv-config-toolbar-class>>\n>\n\t<%if [<tv-config-toolbar-icons>match[yes]] %>\n\t\t{{$:/core/images/clone-button}}\n\t<%endif%>\n\t<%if [<tv-config-toolbar-text>match[yes]] %>\n\t\t<span class=\"tc-btn-text\">\n\t\t\t<$text text={{$:/language/Buttons/Clone/Caption}}/>\n\t\t</span>\n\t<%endif%>\n</$button>"},"$:/core/ui/Buttons/close-others":{"title":"$:/core/ui/Buttons/close-others","tags":"$:/tags/ViewToolbar","caption":"{{$:/core/images/close-others-button}} {{$:/language/Buttons/CloseOthers/Caption}}","description":"{{$:/language/Buttons/CloseOthers/Hint}}","text":"\\whitespace trim\n<$button message=\"tm-close-other-tiddlers\" param=<<currentTiddler>> tooltip={{$:/language/Buttons/CloseOthers/Hint}} aria-label={{$:/language/Buttons/CloseOthers/Caption}} class=<<tv-config-toolbar-class>>>\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/close-others-button}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/CloseOthers/Caption}}/>\n</span>\n<%endif%>\n</$button>"},"$:/core/ui/Buttons/close":{"title":"$:/core/ui/Buttons/close","tags":"$:/tags/ViewToolbar","caption":"{{$:/core/images/close-button}} {{$:/language/Buttons/Close/Caption}}","description":"{{$:/language/Buttons/Close/Hint}}","text":"\\whitespace trim\n<$button message=\"tm-close-tiddler\"\n\ttooltip={{$:/language/Buttons/Close/Hint}}\n\taria-label={{$:/language/Buttons/Close/Caption}}\n\tclass=<<tv-config-toolbar-class>>\n>\n\t<%if [<tv-config-toolbar-icons>match[yes]] %>\n\t\t{{$:/core/images/close-button}}\n\t<%endif%>\n\t<%if [<tv-config-toolbar-text>match[yes]] %>\n\t\t<span class=\"tc-btn-text\">\n\t\t\t<$text text={{$:/language/Buttons/Close/Caption}}/>\n\t\t</span>\n\t<%endif%>\n</$button>"},"$:/core/ui/Buttons/edit":{"title":"$:/core/ui/Buttons/edit","tags":"$:/tags/ViewToolbar","caption":"{{$:/core/images/edit-button}} {{$:/language/Buttons/Edit/Caption}}","description":"{{$:/language/Buttons/Edit/Hint}}","text":"\\whitespace trim\n<$button message=\"tm-edit-tiddler\"\n\ttooltip={{$:/language/Buttons/Edit/Hint}}\n\taria-label={{$:/language/Buttons/Edit/Hint}}\n\tclass=<<tv-config-toolbar-class>>\n>\n\t<%if [<tv-config-toolbar-icons>match[yes]] %>\n\t\t{{$:/core/images/edit-button}}\n\t<%endif%>\n\t<%if [<tv-config-toolbar-text>match[yes]] %>\n\t\t<span class=\"tc-btn-text\">\n\t\t<$text text={{$:/language/Buttons/Edit/Caption}}/>\n\t</span>\n\t<%endif%>\n</$button>"},"$:/core/ui/Buttons/export-tiddler":{"title":"$:/core/ui/Buttons/export-tiddler","tags":"$:/tags/ViewToolbar","caption":"{{$:/core/images/export-button}} {{$:/language/Buttons/ExportTiddler/Caption}}","description":"{{$:/language/Buttons/ExportTiddler/Hint}}","text":"<$transclude $variable=\"exportButton\" exportFilter=`[[$(currentTiddler)$]]` lingoBase=\"$:/language/Buttons/ExportTiddler/\" baseFilename=<<currentTiddler>>/>"},"$:/core/ui/Buttons/fold-bar":{"title":"$:/core/ui/Buttons/fold-bar","tags":"$:/tags/ViewToolbar","caption":"{{$:/core/images/chevron-up}} {{$:/language/Buttons/Fold/FoldBar/Caption}}","description":"{{$:/language/Buttons/Fold/FoldBar/Hint}}","text":"<!-- This dummy toolbar button is here to allow visibility of the fold-bar to be controlled as if it were a toolbar button -->"},"$:/core/ui/Buttons/fold-others":{"title":"$:/core/ui/Buttons/fold-others","tags":"$:/tags/ViewToolbar","caption":"{{$:/core/images/fold-others-button}} {{$:/language/Buttons/FoldOthers/Caption}}","description":"{{$:/language/Buttons/FoldOthers/Hint}}","text":"\\whitespace trim\n<$button tooltip={{$:/language/Buttons/FoldOthers/Hint}} aria-label={{$:/language/Buttons/FoldOthers/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-sendmessage $message=\"tm-fold-other-tiddlers\" $param=<<currentTiddler>> foldedStatePrefix=\"$:/state/folded/\"/>\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/fold-others-button}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/FoldOthers/Caption}}/>\n</span>\n<%endif%>\n</$button>"},"$:/core/ui/Buttons/fold":{"title":"$:/core/ui/Buttons/fold","tags":"$:/tags/ViewToolbar","caption":"{{$:/core/images/fold-button}} {{$:/language/Buttons/Fold/Caption}}","description":"{{$:/language/Buttons/Fold/Hint}}","text":"\\whitespace trim\n<$reveal type=\"nomatch\" stateTitle=<<folded-state>> text=\"hide\" default=\"show\">\n<$button tooltip={{$:/language/Buttons/Fold/Hint}} aria-label={{$:/language/Buttons/Fold/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-sendmessage $message=\"tm-fold-tiddler\" $param=<<currentTiddler>> foldedState=<<folded-state>>/>\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/fold-button}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/Fold/Caption}}/>\n</span>\n<%endif%>\n</$button>\n</$reveal>\n<$reveal type=\"match\" stateTitle=<<folded-state>> text=\"hide\" default=\"show\">\n<$button tooltip={{$:/language/Buttons/Unfold/Hint}} aria-label={{$:/language/Buttons/Unfold/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-sendmessage $message=\"tm-fold-tiddler\" $param=<<currentTiddler>> foldedState=<<folded-state>>/>\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/unfold-button}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/Unfold/Caption}}/>\n</span>\n<%endif%>\n</$button>\n</$reveal>\n"},"$:/core/ui/Buttons/info":{"title":"$:/core/ui/Buttons/info","tags":"$:/tags/ViewToolbar","caption":"{{$:/core/images/info-button}} {{$:/language/Buttons/Info/Caption}}","description":"{{$:/language/Buttons/Info/Hint}}","text":"\\whitespace trim\n\\procedure button-content()\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/info-button}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/Info/Caption}}/>\n</span>\n<%endif%>\n\\end\n<$reveal state=\"$:/config/TiddlerInfo/Mode\" type=\"match\" text=\"popup\">\n<$button popup=<<tiddlerInfoState>> tooltip={{$:/language/Buttons/Info/Hint}} aria-label={{$:/language/Buttons/Info/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$transclude $variable=\"button-content\" $mode=\"inline\"/>\n</$button>\n</$reveal>\n<$reveal state=\"$:/config/TiddlerInfo/Mode\" type=\"match\" text=\"sticky\">\n<$reveal state=<<tiddlerInfoState>> type=\"match\" text=\"\" default=\"\">\n<$button set=<<tiddlerInfoState>> setTo=\"yes\" tooltip={{$:/language/Buttons/Info/Hint}} aria-label={{$:/language/Buttons/Info/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$transclude $variable=\"button-content\" $mode=\"inline\"/>\n</$button>\n</$reveal>\n<$reveal state=<<tiddlerInfoState>> type=\"nomatch\" text=\"\" default=\"\">\n<$button set=<<tiddlerInfoState>> setTo=\"\" tooltip={{$:/language/Buttons/Info/Hint}} aria-label={{$:/language/Buttons/Info/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$transclude $variable=\"button-content\" $mode=\"inline\"/>\n</$button>\n</$reveal>\n</$reveal>"},"$:/core/ui/Buttons/more-tiddler-actions":{"title":"$:/core/ui/Buttons/more-tiddler-actions","tags":"$:/tags/ViewToolbar","caption":"{{$:/core/images/down-arrow}} {{$:/language/Buttons/More/Caption}}","description":"{{$:/language/Buttons/More/Hint}}","text":"\\whitespace trim\n\n<$button popup=<<qualify \"$:/state/popup/more\">>\n\ttooltip={{$:/language/Buttons/More/Hint}}\n\taria-label={{$:/language/Buttons/More/Caption}}\n\tclass=<<tv-config-toolbar-class>>\n\tselectedClass=\"tc-selected\"\n>\n\t<%if [<tv-config-toolbar-icons>match[yes]] %>\n\t\t{{$:/core/images/down-arrow}}\n\t<%endif%>\n\t<%if [<tv-config-toolbar-text>match[yes]] %>\n\t\t<span class=\"tc-btn-text\">\n\t\t\t<$text text={{$:/language/Buttons/More/Caption}}/>\n\t\t</span>\n\t<%endif%>\n</$button>\n<$reveal state=<<qualify \"$:/state/popup/more\">> type=\"popup\" position=\"belowleft\" animate=\"yes\">\n\t<div class=\"tc-drop-down\">\n\t\t<$let tv-config-toolbar-icons=\"yes\" tv-config-toolbar-text=\"yes\" tv-config-toolbar-class=\"tc-btn-invisible\">\n\t\t\t<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/ViewToolbar]!has[draft.of]] -[[$:/core/ui/Buttons/more-tiddler-actions]]\"\n\t\t\t\tvariable=\"listItem\"\n\t\t\t>\n\t\t\t\t<$reveal type=\"match\" state=`$:/config/ViewToolbarButtons/Visibility/$(listItem)$` text=\"hide\">\n\t\t\t\t\t<$set name=\"tv-config-toolbar-class\"\n\t\t\t\t\t\tfilter=\"[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<$transclude tiddler=<<listItem>> mode=\"inline\"/>\n\t\t\t\t\t</$set>\n\t\t\t\t</$reveal>\n\t\t\t</$list>\n\t\t</$let>\n\t</div>\n</$reveal>"},"$:/core/ui/Buttons/new-here":{"title":"$:/core/ui/Buttons/new-here","tags":"$:/tags/ViewToolbar","caption":"{{$:/core/images/new-here-button}} {{$:/language/Buttons/NewHere/Caption}}","description":"{{$:/language/Buttons/NewHere/Hint}}","text":"\\whitespace trim\n\\procedure newHereActions()\n<$set name=\"tags\" filter=\"[<currentTiddler>] [enlist{$:/config/NewTiddler/Tags}]\">\n<$action-sendmessage $message=\"tm-new-tiddler\" tags=<<tags>>/>\n</$set>\n\\end\n\\procedure newHereButton()\n<$button actions=<<newHereActions>> tooltip={{$:/language/Buttons/NewHere/Hint}} aria-label={{$:/language/Buttons/NewHere/Caption}} class=<<tv-config-toolbar-class>>>\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/new-here-button}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/NewHere/Caption}}/>\n</span>\n<%endif%>\n</$button>\n\\end\n<<newHereButton>>\n"},"$:/core/ui/Buttons/new-journal-here":{"title":"$:/core/ui/Buttons/new-journal-here","tags":"$:/tags/ViewToolbar","caption":"{{$:/core/images/new-journal-button}} {{$:/language/Buttons/NewJournalHere/Caption}}","description":"{{$:/language/Buttons/NewJournalHere/Hint}}","text":"\\whitespace trim\n\\procedure journalButton()\n<$button tooltip={{$:/language/Buttons/NewJournalHere/Hint}} aria-label={{$:/language/Buttons/NewJournalHere/Caption}} class=<<tv-config-toolbar-class>>>\n<$wikify name=\"journalTitle\" text=\"\"\"<$transclude $variable=\"now\" format=<<journalTitleTemplate>>/>\"\"\">\n<$action-sendmessage $message=\"tm-new-tiddler\" title=<<journalTitle>> tags=`[[$(currentTiddlerTag)$]] $(journalTags)$`/>\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/new-journal-button}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/NewJournalHere/Caption}}/>\n</span>\n<%endif%>\n</$wikify>\n</$button>\n\\end\n<$let journalTitleTemplate={{$:/config/NewJournal/Title}} journalTags={{$:/config/NewJournal/Tags}} currentTiddlerTag=<<currentTiddler>>>\n<<journalButton>>\n</$let>\n"},"$:/core/ui/Buttons/open-window":{"title":"$:/core/ui/Buttons/open-window","tags":"$:/tags/ViewToolbar","caption":"{{$:/core/images/open-window}} {{$:/language/Buttons/OpenWindow/Caption}}","description":"{{$:/language/Buttons/OpenWindow/Hint}}","text":"\\whitespace trim\n<$button message=\"tm-open-window\" tooltip={{$:/language/Buttons/OpenWindow/Hint}} aria-label={{$:/language/Buttons/OpenWindow/Caption}} class=<<tv-config-toolbar-class>>>\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/open-window}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/OpenWindow/Caption}}/>\n</span>\n<%endif%>\n</$button>"},"$:/core/ui/Buttons/permalink":{"title":"$:/core/ui/Buttons/permalink","tags":"$:/tags/ViewToolbar","caption":"{{$:/core/images/permalink-button}} {{$:/language/Buttons/Permalink/Caption}}","description":"{{$:/language/Buttons/Permalink/Hint}}","text":"\\whitespace trim\n<$button message=\"tm-permalink\" tooltip={{$:/language/Buttons/Permalink/Hint}} aria-label={{$:/language/Buttons/Permalink/Caption}} class=<<tv-config-toolbar-class>>>\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/permalink-button}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/Permalink/Caption}}/>\n</span>\n<%endif%>\n</$button>"},"$:/core/ui/Buttons/permaview":{"title":"$:/core/ui/Buttons/permaview","tags":"$:/tags/ViewToolbar $:/tags/PageControls","caption":"{{$:/core/images/permaview-button}} {{$:/language/Buttons/Permaview/Caption}}","description":"{{$:/language/Buttons/Permaview/Hint}}","text":"\\whitespace trim\n<$button message=\"tm-permaview\" tooltip={{$:/language/Buttons/Permaview/Hint}} aria-label={{$:/language/Buttons/Permaview/Caption}} class=<<tv-config-toolbar-class>>>\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/core/images/permaview-button}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/Permaview/Caption}}/>\n</span>\n<%endif%>\n</$button>"},"$:/DefaultTiddlers":{"title":"$:/DefaultTiddlers","text":"GettingStarted\n"},"$:/temp/advancedsearch":{"title":"$:/temp/advancedsearch","text":""},"$:/snippets/allfields":{"title":"$:/snippets/allfields","text":"\\whitespace trim\n\n\\procedure lingo-base() $:/language/Docs/Fields/\n\n\\function tf.getLingoText() [<lingo-base>] [<title>] +[join[]get[text]]\n\n\\procedure renderfield(title)\n<tr class=\"tc-view-field\">\n\t<td class=\"tc-view-field-name\">\n\t\t''<$text text=<<title>>/>'':\n\t</td>\n\t<td class=\"tc-view-field-value\">\n\t\t//<<tf.getLingoText>>//\n\t</td>\n\t<td class=\"tc-view-field-list\">\n\t\t<$macrocall $name=\"show-filter-count\" filter=`[has[$(title)$]sort[]]`>>\n\t</td>\n</tr>\n\\end\n\n<table class=\"tc-view-field-table\">\n\t<tbody>\n\t\t<!-- <<renderfieldHeader>> -->\n\t\t<$list filter=\"[fields[]sort[title]]\" variable=\"listItem\">\n\t\t\t<$macrocall $name=\"renderfield\" title=<<listItem>>/>\n\t\t</$list>\n\t</tbody>\n</table>\n"},"$:/config/AnimationDuration":{"title":"$:/config/AnimationDuration","text":"400"},"$:/config/AutoFocus":{"title":"$:/config/AutoFocus","text":"title"},"$:/config/AutoSave":{"title":"$:/config/AutoSave","text":"yes"},"$:/config/BitmapEditor/Colour":{"title":"$:/config/BitmapEditor/Colour","text":"#444"},"$:/config/BitmapEditor/ImageSizes":{"title":"$:/config/BitmapEditor/ImageSizes","text":"[[62px 100px]] [[100px 62px]] [[124px 200px]] [[200px 124px]] [[248px 400px]] [[371px 600px]] [[400px 248px]] [[556px 900px]] [[600px 371px]] [[742px 1200px]] [[900px 556px]] [[1200px 742px]]"},"$:/config/BitmapEditor/LineWidth":{"title":"$:/config/BitmapEditor/LineWidth","text":"3px"},"$:/config/BitmapEditor/LineWidths":{"title":"$:/config/BitmapEditor/LineWidths","text":"0.25px 0.5px 1px 2px 3px 4px 6px 8px 10px 16px 20px 28px 40px 56px 80px"},"$:/config/BitmapEditor/Opacities":{"title":"$:/config/BitmapEditor/Opacities","text":"0.01 0.025 0.05 0.075 0.1 0.15 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0"},"$:/config/BitmapEditor/Opacity":{"title":"$:/config/BitmapEditor/Opacity","text":"1.0"},"$:/config/DefaultMoreSidebarTab":{"title":"$:/config/DefaultMoreSidebarTab","text":"$:/core/ui/MoreSideBar/Tags"},"$:/config/DefaultSidebarTab":{"title":"$:/config/DefaultSidebarTab","text":"$:/core/ui/SideBar/Open"},"$:/config/ControlPanel/Basics/DefaultTiddlers/RetainStory":{"title":"$:/config/ControlPanel/Basics/DefaultTiddlers/RetainStory","text":"[list[$:/StoryList]]"},"$:/config/DownloadSaver/AutoSave":{"title":"$:/config/DownloadSaver/AutoSave","text":"no"},"$:/config/Drafts/TypingTimeout":{"title":"$:/config/Drafts/TypingTimeout","text":"400"},"$:/config/EditMode/fieldname-filter":{"title":"$:/config/EditMode/fieldname-filter","first-search-filter":"[!is[shadow]!is[system]fields[]search:title<userInput>sort[]] -created -creator -draft.of -draft.title -modified -modifier -tags -text -title -type","second-search-filter":"[fields[]search:title<userInput>sort[]] -[!is[shadow]!is[system]fields[]]"},"$:/config/EditTabIndex":{"title":"$:/config/EditTabIndex","text":"1"},"$:/config/EditTemplateBodyFilters/canonical-uri":{"title":"$:/config/EditTemplateBodyFilters/canonical-uri","tags":"$:/tags/EditTemplateBodyFilter","text":"[has[_canonical_uri]then[$:/core/ui/EditTemplate/body/canonical-uri]]"},"$:/config/EditTemplateBodyFilters/default":{"title":"$:/config/EditTemplateBodyFilters/default","tags":"$:/tags/EditTemplateBodyFilter","text":"[[$:/core/ui/EditTemplate/body/default]]"},"$:/config/EditTemplateFields/Visibility/title":{"title":"$:/config/EditTemplateFields/Visibility/title","text":"hide"},"$:/config/EditTemplateFields/Visibility/tags":{"title":"$:/config/EditTemplateFields/Visibility/tags","text":"hide"},"$:/config/EditTemplateFields/Visibility/text":{"title":"$:/config/EditTemplateFields/Visibility/text","text":"hide"},"$:/config/EditTemplateFields/Visibility/creator":{"title":"$:/config/EditTemplateFields/Visibility/creator","text":"hide"},"$:/config/EditTemplateFields/Visibility/created":{"title":"$:/config/EditTemplateFields/Visibility/created","text":"hide"},"$:/config/EditTemplateFields/Visibility/modified":{"title":"$:/config/EditTemplateFields/Visibility/modified","text":"hide"},"$:/config/EditTemplateFields/Visibility/modifier":{"title":"$:/config/EditTemplateFields/Visibility/modifier","text":"hide"},"$:/config/EditTemplateFields/Visibility/type":{"title":"$:/config/EditTemplateFields/Visibility/type","text":"hide"},"$:/config/EditTemplateFields/Visibility/draft.title":{"title":"$:/config/EditTemplateFields/Visibility/draft.title","text":"hide"},"$:/config/EditTemplateFields/Visibility/draft.of":{"title":"$:/config/EditTemplateFields/Visibility/draft.of","text":"hide"},"$:/config/EditTemplateFields/Visibility/revision":{"title":"$:/config/EditTemplateFields/Visibility/revision","text":"hide"},"$:/config/EditTemplateFields/Visibility/bag":{"title":"$:/config/EditTemplateFields/Visibility/bag","text":"hide"},"$:/config/Editor/EnableImportFilter":{"title":"$:/config/Editor/EnableImportFilter","type":"text/vnd.tiddlywiki","text":"[all[current]type[text/vnd.tiddlywiki]] [all[current]!has[type]] [all[current]type[text/markdown]] [all[current]type[text/x-markdown]]"},"$:/config/Editor/ImportContentTypesFilter":{"title":"$:/config/Editor/ImportContentTypesFilter","type":"text/vnd.tiddlywiki","text":"[prefix[image/]]"},"$:/config/EditorToolbarButtons/Visibility/$:/core/ui/EditorToolbar/heading-4":{"title":"$:/config/EditorToolbarButtons/Visibility/$:/core/ui/EditorToolbar/heading-4","text":"hide"},"$:/config/EditorToolbarButtons/Visibility/$:/core/ui/EditorToolbar/heading-5":{"title":"$:/config/EditorToolbarButtons/Visibility/$:/core/ui/EditorToolbar/heading-5","text":"hide"},"$:/config/EditorToolbarButtons/Visibility/$:/core/ui/EditorToolbar/heading-6":{"title":"$:/config/EditorToolbarButtons/Visibility/$:/core/ui/EditorToolbar/heading-6","text":"hide"},"$:/config/EditorTypeMappings/image/gif":{"title":"$:/config/EditorTypeMappings/image/gif","text":"bitmap"},"$:/config/EditorTypeMappings/image/webp":{"title":"$:/config/EditorTypeMappings/image/webp","text":"bitmap"},"$:/config/EditorTypeMappings/image/heic":{"title":"$:/config/EditorTypeMappings/image/heic","text":"bitmap"},"$:/config/EditorTypeMappings/image/heif":{"title":"$:/config/EditorTypeMappings/image/heif","text":"bitmap"},"$:/config/EditorTypeMappings/image/jpeg":{"title":"$:/config/EditorTypeMappings/image/jpeg","text":"bitmap"},"$:/config/EditorTypeMappings/image/jpg":{"title":"$:/config/EditorTypeMappings/image/jpg","text":"bitmap"},"$:/config/EditorTypeMappings/image/png":{"title":"$:/config/EditorTypeMappings/image/png","text":"bitmap"},"$:/config/EditorTypeMappings/image/x-icon":{"title":"$:/config/EditorTypeMappings/image/x-icon","text":"bitmap"},"$:/config/EditorTypeMappings/text/vnd.tiddlywiki":{"title":"$:/config/EditorTypeMappings/text/vnd.tiddlywiki","text":"text"},"$:/config/FieldEditorFilters/default":{"title":"$:/config/FieldEditorFilters/default","tags":"$:/tags/FieldEditorFilter","text":"[[$:/core/ui/EditTemplate/fieldEditor/default]]"},"$:/core/config/GlobalImportFilter":{"title":"$:/core/config/GlobalImportFilter","text":"[[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!is[draft]] [all[shadows+tiddlers]tag[$:/tags/Global]!is[draft]]"},"$:/config/Manager/Show":{"title":"$:/config/Manager/Show","text":"tiddlers"},"$:/config/Manager/Filter":{"title":"$:/config/Manager/Filter","text":""},"$:/config/Manager/Order":{"title":"$:/config/Manager/Order","text":"forward"},"$:/config/Manager/Sort":{"title":"$:/config/Manager/Sort","text":"title"},"$:/config/Manager/System":{"title":"$:/config/Manager/System","text":"system"},"$:/config/Manager/Tag":{"title":"$:/config/Manager/Tag","text":""},"$:/state/popup/manager/item/$:/Manager/ItemMain/RawText":{"title":"$:/state/popup/manager/item/$:/Manager/ItemMain/RawText","text":"hide"},"$:/config/MissingLinks":{"title":"$:/config/MissingLinks","text":"yes"},"$:/config/Navigation/UpdateAddressBar":{"title":"$:/config/Navigation/UpdateAddressBar","text":"no"},"$:/config/Navigation/UpdateHistory":{"title":"$:/config/Navigation/UpdateHistory","text":"no"},"$:/config/NewImageType":{"title":"$:/config/NewImageType","text":"jpeg"},"$:/config/OfficialPluginLibrary":{"title":"$:/config/OfficialPluginLibrary","tags":"$:/tags/PluginLibrary","url":"https://tiddlywiki.com/library/v5.3.6/index.html","caption":"{{$:/language/OfficialPluginLibrary}}","text":"{{$:/language/OfficialPluginLibrary/Hint}}\n"},"$:/config/Navigation/openLinkFromInsideRiver":{"title":"$:/config/Navigation/openLinkFromInsideRiver","text":"below"},"$:/config/Navigation/openLinkFromOutsideRiver":{"title":"$:/config/Navigation/openLinkFromOutsideRiver","text":"top"},"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/advanced-search":{"title":"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/advanced-search","text":"hide"},"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/close-all":{"title":"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/close-all","text":"hide"},"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/encryption":{"title":"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/encryption","text":"hide"},"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/export-page":{"title":"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/export-page","text":"hide"},"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/fold-all":{"title":"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/fold-all","text":"hide"},"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/full-screen":{"title":"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/full-screen","text":"hide"},"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/home":{"title":"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/home","text":"hide"},"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/refresh":{"title":"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/refresh","text":"hide"},"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/import":{"title":"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/import","text":"hide"},"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/language":{"title":"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/language","text":"hide"},"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/tag-manager":{"title":"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/tag-manager","text":"hide"},"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/manager":{"title":"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/manager","text":"hide"},"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/more-page-actions":{"title":"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/more-page-actions","text":"hide"},"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/network-activity":{"title":"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/network-activity","text":"hide"},"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/new-journal":{"title":"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/new-journal","text":"hide"},"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/new-image":{"title":"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/new-image","text":"hide"},"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/palette":{"title":"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/palette","text":"hide"},"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/permaview":{"title":"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/permaview","text":"hide"},"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/print":{"title":"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/print","text":"hide"},"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/storyview":{"title":"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/storyview","text":"hide"},"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/timestamp":{"title":"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/timestamp","text":"hide"},"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/theme":{"title":"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/theme","text":"hide"},"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/layout":{"title":"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/layout","text":"hide"},"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/unfold-all":{"title":"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/unfold-all","text":"hide"},"$:/config/Performance/Instrumentation":{"title":"$:/config/Performance/Instrumentation","text":"no"},"$:/config/RecentLimit":{"title":"$:/config/RecentLimit","text":"100"},"$:/config/RegisterPluginType/plugin":{"title":"$:/config/RegisterPluginType/plugin","text":"yes"},"$:/config/RegisterPluginType/theme":{"title":"$:/config/RegisterPluginType/theme","text":"no"},"$:/config/RegisterPluginType/language":{"title":"$:/config/RegisterPluginType/language","text":"no"},"$:/config/RegisterPluginType/info":{"title":"$:/config/RegisterPluginType/info","text":"yes"},"$:/config/RegisterPluginType/import":{"title":"$:/config/RegisterPluginType/import","text":"no"},"$:/config/SaveWikiButton/Template":{"title":"$:/config/SaveWikiButton/Template","text":"$:/core/save/all"},"$:/config/SaverFilter":{"title":"$:/config/SaverFilter","text":"[all[]] -[prefix[$:/HistoryList]] -[prefix[$:/StoryList]] -[status[pending]plugin-type[import]] -[[$:/isEncrypted]] -[[$:/UploadName]] -[prefix[$:/state/]] -[prefix[$:/temp/]]\n"},"$:/config/Search/AutoFocus":{"title":"$:/config/Search/AutoFocus","text":"true"},"$:/config/Search/MinLength":{"title":"$:/config/Search/MinLength","text":"3"},"$:/config/SearchResults/Default":{"title":"$:/config/SearchResults/Default","text":"$:/core/ui/DefaultSearchResultList"},"$:/config/Server/ExternalFilters/[all[tiddlers]!is[system]sort[title]]":{"title":"$:/config/Server/ExternalFilters/[all[tiddlers]!is[system]sort[title]]","text":"yes"},"$:/config/ShortcutInfo/add-field":{"title":"$:/config/ShortcutInfo/add-field","text":"{{$:/language/EditTemplate/Fields/Add/Button/Hint}}"},"$:/config/ShortcutInfo/advanced-search":{"title":"$:/config/ShortcutInfo/advanced-search","text":"{{$:/language/Buttons/AdvancedSearch/Hint}}"},"$:/config/ShortcutInfo/advanced-search-sidebar":{"title":"$:/config/ShortcutInfo/advanced-search-sidebar","text":"{{$:/language/Shortcuts/Input/AdvancedSearch/Hint}}"},"$:/config/ShortcutInfo/bold":{"title":"$:/config/ShortcutInfo/bold","text":"{{$:/language/Buttons/Bold/Hint}}"},"$:/config/ShortcutInfo/cancel-edit-tiddler":{"title":"$:/config/ShortcutInfo/cancel-edit-tiddler","text":"{{$:/language/Buttons/Cancel/Hint}}"},"$:/config/ShortcutInfo/change-sidebar-layout":{"title":"$:/config/ShortcutInfo/change-sidebar-layout","text":"{{$:/language/Shortcuts/SidebarLayout/Hint}}"},"$:/config/ShortcutInfo/delete-field":{"title":"$:/config/ShortcutInfo/delete-field","text":"{{$:/language/EditTemplate/Field/Remove/Hint}}"},"$:/config/ShortcutInfo/excise":{"title":"$:/config/ShortcutInfo/excise","text":"{{$:/language/Buttons/Excise/Hint}}"},"$:/config/ShortcutInfo/heading-1":{"title":"$:/config/ShortcutInfo/heading-1","text":"{{$:/language/Buttons/Heading1/Hint}}"},"$:/config/ShortcutInfo/heading-2":{"title":"$:/config/ShortcutInfo/heading-2","text":"{{$:/language/Buttons/Heading2/Hint}}"},"$:/config/ShortcutInfo/heading-3":{"title":"$:/config/ShortcutInfo/heading-3","text":"{{$:/language/Buttons/Heading3/Hint}}"},"$:/config/ShortcutInfo/heading-4":{"title":"$:/config/ShortcutInfo/heading-4","text":"{{$:/language/Buttons/Heading4/Hint}}"},"$:/config/ShortcutInfo/heading-5":{"title":"$:/config/ShortcutInfo/heading-5","text":"{{$:/language/Buttons/Heading5/Hint}}"},"$:/config/ShortcutInfo/heading-6":{"title":"$:/config/ShortcutInfo/heading-6","text":"{{$:/language/Buttons/Heading6/Hint}}"},"$:/config/ShortcutInfo/input-accept":{"title":"$:/config/ShortcutInfo/input-accept","text":"{{$:/language/Shortcuts/Input/Accept/Hint}}"},"$:/config/ShortcutInfo/input-accept-variant":{"title":"$:/config/ShortcutInfo/input-accept-variant","text":"{{$:/language/Shortcuts/Input/AcceptVariant/Hint}}"},"$:/config/ShortcutInfo/input-cancel":{"title":"$:/config/ShortcutInfo/input-cancel","text":"{{$:/language/Shortcuts/Input/Cancel/Hint}}"},"$:/config/ShortcutInfo/input-down":{"title":"$:/config/ShortcutInfo/input-down","text":"{{$:/language/Shortcuts/Input/Down/Hint}}"},"$:/config/ShortcutInfo/input-tab-left":{"title":"$:/config/ShortcutInfo/input-tab-left","text":"{{$:/language/Shortcuts/Input/Tab-Left/Hint}}"},"$:/config/ShortcutInfo/input-tab-right":{"title":"$:/config/ShortcutInfo/input-tab-right","text":"{{$:/language/Shortcuts/Input/Tab-Right/Hint}}"},"$:/config/ShortcutInfo/input-up":{"title":"$:/config/ShortcutInfo/input-up","text":"{{$:/language/Shortcuts/Input/Up/Hint}}"},"$:/config/ShortcutInfo/italic":{"title":"$:/config/ShortcutInfo/italic","text":"{{$:/language/Buttons/Italic/Hint}}"},"$:/config/ShortcutInfo/layout-switcher":{"title":"$:/config/ShortcutInfo/layout-switcher","text":"{{$:/language/LayoutSwitcher/Description}}"},"$:/config/ShortcutInfo/link":{"title":"$:/config/ShortcutInfo/link","text":"{{$:/language/Buttons/Link/Hint}}"},"$:/config/ShortcutInfo/linkify":{"title":"$:/config/ShortcutInfo/linkify","text":"{{$:/language/Buttons/Linkify/Hint}}"},"$:/config/ShortcutInfo/list-bullet":{"title":"$:/config/ShortcutInfo/list-bullet","text":"{{$:/language/Buttons/ListBullet/Hint}}"},"$:/config/ShortcutInfo/list-number":{"title":"$:/config/ShortcutInfo/list-number","text":"{{$:/language/Buttons/ListNumber/Hint}}"},"$:/config/ShortcutInfo/mono-block":{"title":"$:/config/ShortcutInfo/mono-block","text":"{{$:/language/Buttons/MonoBlock/Hint}}"},"$:/config/ShortcutInfo/mono-line":{"title":"$:/config/ShortcutInfo/mono-line","text":"{{$:/language/Buttons/MonoLine/Hint}}"},"$:/config/ShortcutInfo/new-image":{"title":"$:/config/ShortcutInfo/new-image","text":"{{$:/language/Buttons/NewImage/Hint}}"},"$:/config/ShortcutInfo/new-journal":{"title":"$:/config/ShortcutInfo/new-journal","text":"{{$:/language/Buttons/NewJournal/Hint}}"},"$:/config/ShortcutInfo/new-tiddler":{"title":"$:/config/ShortcutInfo/new-tiddler","text":"{{$:/language/Buttons/NewTiddler/Hint}}"},"$:/config/ShortcutInfo/open-control-panel":{"title":"$:/config/ShortcutInfo/open-control-panel","text":"{{$:/language/Buttons/OpenControlPanel/Hint}}"},"$:/config/ShortcutInfo/picture":{"title":"$:/config/ShortcutInfo/picture","text":"{{$:/language/Buttons/Picture/Hint}}"},"$:/config/ShortcutInfo/preview":{"title":"$:/config/ShortcutInfo/preview","text":"{{$:/language/Buttons/Preview/Hint}}"},"$:/config/ShortcutInfo/quote":{"title":"$:/config/ShortcutInfo/quote","text":"{{$:/language/Buttons/Quote/Hint}}"},"$:/config/ShortcutInfo/refresh":{"title":"$:/config/ShortcutInfo/refresh","text":"{{$:/language/Buttons/Refresh/Hint}}"},"$:/config/ShortcutInfo/save-tiddler":{"title":"$:/config/ShortcutInfo/save-tiddler","text":"{{$:/language/Buttons/Save/Hint}}"},"$:/config/ShortcutInfo/save-wiki":{"title":"$:/config/ShortcutInfo/save-wiki","text":"{{$:/language/Buttons/SaveWiki/Hint}}"},"$:/config/ShortcutInfo/sidebar-search":{"title":"$:/config/ShortcutInfo/sidebar-search","text":"{{$:/language/Buttons/SidebarSearch/Hint}}"},"$:/config/ShortcutInfo/stamp":{"title":"$:/config/ShortcutInfo/stamp","text":"{{$:/language/Buttons/Stamp/Hint}}"},"$:/config/ShortcutInfo/strikethrough":{"title":"$:/config/ShortcutInfo/strikethrough","text":"{{$:/language/Buttons/Strikethrough/Hint}}"},"$:/config/ShortcutInfo/subscript":{"title":"$:/config/ShortcutInfo/subscript","text":"{{$:/language/Buttons/Subscript/Hint}}"},"$:/config/ShortcutInfo/superscript":{"title":"$:/config/ShortcutInfo/superscript","text":"{{$:/language/Buttons/Superscript/Hint}}"},"$:/config/ShortcutInfo/toggle-sidebar":{"title":"$:/config/ShortcutInfo/toggle-sidebar","text":"{{$:/language/Buttons/ToggleSidebar/Hint}}"},"$:/config/ShortcutInfo/transcludify":{"title":"$:/config/ShortcutInfo/transcludify","text":"{{$:/language/Buttons/Transcludify/Hint}}"},"$:/config/ShortcutInfo/underline":{"title":"$:/config/ShortcutInfo/underline","text":"{{$:/language/Buttons/Underline/Hint}}"},"$:/config/StoryTiddlerTemplateFilters/draft":{"title":"$:/config/StoryTiddlerTemplateFilters/draft","tags":"$:/tags/StoryTiddlerTemplateFilter","text":"[is[draft]then{$:/config/ui/EditTemplate}]"},"$:/config/StoryTiddlerTemplateFilters/default":{"title":"$:/config/StoryTiddlerTemplateFilters/default","tags":"$:/tags/StoryTiddlerTemplateFilter","text":"[{$:/config/ui/ViewTemplate}]"},"$:/config/SwitcherTargets/layout":{"title":"$:/config/SwitcherTargets/layout","text":"$:/snippets/LayoutSwitcher"},"$:/config/SwitcherTargets/language":{"title":"$:/config/SwitcherTargets/language","text":"$:/snippets/languageswitcher"},"$:/config/SwitcherTargets/palette":{"title":"$:/config/SwitcherTargets/palette","text":"$:/core/ui/ControlPanel/Palette"},"$:/config/SwitcherTargets/theme":{"title":"$:/config/SwitcherTargets/theme","text":"$:/core/ui/ControlPanel/Theme"},"$:/config/SyncFilter":{"title":"$:/config/SyncFilter","text":"[is[tiddler]] -[[$:/core]] -[[$:/library/sjcl.js]] -[prefix[$:/boot/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/isEncrypted]] -[prefix[$:/status/]] -[prefix[$:/state/]] -[prefix[$:/temp/]]\n"},"$:/config/SyncSystemTiddlersFromServer":{"title":"$:/config/SyncSystemTiddlersFromServer","text":"no"},"$:/core/config/TagPillDragFilter":{"title":"$:/core/config/TagPillDragFilter","text":"[all[current]tagging[]] +[!is[draft]]"},"$:/config/Tags/MinLength":{"title":"$:/config/Tags/MinLength","text":"0"},"$:/config/TextEditor/EditorHeight/Height":{"title":"$:/config/TextEditor/EditorHeight/Height","text":"400px"},"$:/config/TextEditor/EditorHeight/Mode":{"title":"$:/config/TextEditor/EditorHeight/Mode","text":"auto"},"$:/config/TiddlerColourFilters/color-field":{"title":"$:/config/TiddlerColourFilters/color-field","tags":"$:/tags/TiddlerColourFilter","text":"[has[color]then{!!color}]"},"$:/config/TiddlerColourFilters/default":{"title":"$:/config/TiddlerColourFilters/default","tags":"$:/tags/TiddlerColourFilter","text":"[[$:/config/DefaultTiddlerColour]has[text]get[text]trim[]]"},"$:/config/TiddlerIconFilters/icon-field":{"title":"$:/config/TiddlerIconFilters/icon-field","tags":"$:/tags/TiddlerIconFilter","text":"[has[icon]then{!!icon}]"},"$:/config/TiddlerIconFilters/default":{"title":"$:/config/TiddlerIconFilters/default","tags":"$:/tags/TiddlerIconFilter","text":"[{$:/config/DefaultTiddlerIcon}has[text]]"},"$:/config/TiddlerInfo/Default":{"title":"$:/config/TiddlerInfo/Default","text":"$:/core/ui/TiddlerInfo/Fields"},"$:/config/TiddlerInfo/Mode":{"title":"$:/config/TiddlerInfo/Mode","text":"popup"},"$:/config/Tiddlers/TitleLinks":{"title":"$:/config/Tiddlers/TitleLinks","text":"no"},"$:/config/Toolbar/ButtonClass":{"title":"$:/config/Toolbar/ButtonClass","text":"tc-btn-invisible"},"$:/config/Toolbar/Icons":{"title":"$:/config/Toolbar/Icons","text":"yes"},"$:/config/Toolbar/Text":{"title":"$:/config/Toolbar/Text","text":"no"},"$:/config/ViewTemplateBodyFilters/testcase":{"title":"$:/config/ViewTemplateBodyFilters/testcase","tags":"$:/tags/ViewTemplateBodyFilter","text":"[tag[$:/tags/wiki-test-spec]type[text/vnd.tiddlywiki-multiple]] [tag[$:/tags/wiki-test-spec-failing]type[text/vnd.tiddlywiki-multiple]] :then[[$:/core/ui/TestCaseTemplate]]"},"$:/config/ViewTemplateBodyFilters/stylesheet":{"title":"$:/config/ViewTemplateBodyFilters/stylesheet","tags":"$:/tags/ViewTemplateBodyFilter","text":"[tag[$:/tags/Stylesheet]then[$:/core/ui/ViewTemplate/body/rendered-plain-text]]"},"$:/config/ViewTemplateBodyFilters/core-ui-tags":{"title":"$:/config/ViewTemplateBodyFilters/core-ui-tags","tags":"$:/tags/ViewTemplateBodyFilter","text":"[tag[$:/tags/PageTemplate]] [tag[$:/tags/EditTemplate]] [tag[$:/tags/ViewTemplate]] [tag[$:/tags/KeyboardShortcut]] [tag[$:/tags/ImportPreview]] [tag[$:/tags/EditPreview]] [tag[$:/tags/EditorToolbar]] [tag[$:/EditorTools]] [tag[$:/tags/Actions]] [tag[$:/tags/ToolbarButtonStyle]] :then[[$:/core/ui/ViewTemplate/body/code]]"},"$:/config/ViewTemplateBodyFilters/system":{"title":"$:/config/ViewTemplateBodyFilters/system","tags":"$:/tags/ViewTemplateBodyFilter","text":"[prefix[$:/boot/]] [prefix[$:/core/macros]] [prefix[$:/core/save/]] [prefix[$:/core/templates/]]  [prefix[$:/config/]] [prefix[$:/core/config/]] [prefix[$:/info/]] [prefix[$:/language/]] [prefix[$:/languages/]] [prefix[$:/snippets/]]  [prefix[$:/info/]] [prefix[$:/state/]] [prefix[$:/status/]] [prefix[$:/temp/]] :and[!is[image]]  :then[[$:/core/ui/ViewTemplate/body/code]]"},"$:/config/ViewTemplateBodyFilters/code-body":{"title":"$:/config/ViewTemplateBodyFilters/code-body","tags":"$:/tags/ViewTemplateBodyFilter","text":"[field:code-body[yes]then[$:/core/ui/ViewTemplate/body/code]]"},"$:/config/ViewTemplateBodyFilters/import":{"title":"$:/config/ViewTemplateBodyFilters/import","tags":"$:/tags/ViewTemplateBodyFilter","text":"[field:plugin-type[import]then[$:/core/ui/ViewTemplate/body/import]]"},"$:/config/ViewTemplateBodyFilters/plugin":{"title":"$:/config/ViewTemplateBodyFilters/plugin","tags":"$:/tags/ViewTemplateBodyFilter","text":"[has[plugin-type]then[$:/core/ui/ViewTemplate/body/plugin]]"},"$:/config/ViewTemplateBodyFilters/hide-body":{"title":"$:/config/ViewTemplateBodyFilters/hide-body","tags":"$:/tags/ViewTemplateBodyFilter","text":"[field:hide-body[yes]then[$:/core/ui/ViewTemplate/body/blank]]"},"$:/config/ViewTemplateBodyFilters/default":{"title":"$:/config/ViewTemplateBodyFilters/default","tags":"$:/tags/ViewTemplateBodyFilter","text":"[[$:/core/ui/ViewTemplate/body/default]]"},"$:/config/ViewTemplateSubtitleFilters/default":{"title":"$:/config/ViewTemplateSubtitleFilters/default","tags":"$:/tags/ViewTemplateSubtitleFilter","text":"[[$:/core/ui/ViewTemplate/subtitle/default]]"},"$:/config/ViewTemplateTagsFilters/default":{"title":"$:/config/ViewTemplateTagsFilters/default","tags":"$:/tags/ViewTemplateTagsFilter","text":"[[$:/core/ui/ViewTemplate/tags/default]]"},"$:/config/ViewTemplateTitleFilters/system":{"title":"$:/config/ViewTemplateTitleFilters/system","tags":"$:/tags/ViewTemplateTitleFilter","text":"[prefix[$:/]then[$:/core/ui/ViewTemplate/title/system]]"},"$:/config/ViewTemplateTitleFilters/default":{"title":"$:/config/ViewTemplateTitleFilters/default","tags":"$:/tags/ViewTemplateTitleFilter","text":"[[$:/core/ui/ViewTemplate/title/default]]"},"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/clone":{"title":"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/clone","text":"hide"},"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/close-others":{"title":"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/close-others","text":"hide"},"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/export-tiddler":{"title":"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/export-tiddler","text":"hide"},"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/info":{"title":"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/info","text":"hide"},"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/more-tiddler-actions":{"title":"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/more-tiddler-actions","text":"show"},"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/new-here":{"title":"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/new-here","text":"hide"},"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/new-journal-here":{"title":"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/new-journal-here","text":"hide"},"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/open-window":{"title":"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/open-window","text":"hide"},"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/permalink":{"title":"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/permalink","text":"hide"},"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/permaview":{"title":"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/permaview","text":"hide"},"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/delete":{"title":"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/delete","text":"hide"},"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold":{"title":"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold","text":"hide"},"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold-bar":{"title":"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold-bar","text":"hide"},"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold-others":{"title":"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold-others","text":"hide"},"$:/config/shortcuts-mac/bold":{"title":"$:/config/shortcuts-mac/bold","text":"meta-B"},"$:/config/shortcuts-mac/italic":{"title":"$:/config/shortcuts-mac/italic","text":"meta-I"},"$:/config/shortcuts-mac/underline":{"title":"$:/config/shortcuts-mac/underline","text":"meta-U"},"$:/config/shortcuts-mac/new-image":{"title":"$:/config/shortcuts-mac/new-image","text":"ctrl-I"},"$:/config/shortcuts-mac/new-journal":{"title":"$:/config/shortcuts-mac/new-journal","text":"ctrl-J"},"$:/config/shortcuts-mac/new-tiddler":{"title":"$:/config/shortcuts-mac/new-tiddler","text":"ctrl-N"},"$:/config/shortcuts-mac/refresh":{"title":"$:/config/shortcuts-mac/refresh","text":"meta-R"},"$:/config/shortcuts-mac/save-wiki":{"title":"$:/config/shortcuts-mac/save-wiki","text":"meta-S"},"$:/config/shortcuts-not-mac/bold":{"title":"$:/config/shortcuts-not-mac/bold","text":"ctrl-B"},"$:/config/shortcuts-not-mac/italic":{"title":"$:/config/shortcuts-not-mac/italic","text":"ctrl-I"},"$:/config/shortcuts-not-mac/underline":{"title":"$:/config/shortcuts-not-mac/underline","text":"ctrl-U"},"$:/config/shortcuts-not-mac/new-image":{"title":"$:/config/shortcuts-not-mac/new-image","text":"alt-I"},"$:/config/shortcuts-not-mac/new-journal":{"title":"$:/config/shortcuts-not-mac/new-journal","text":"alt-J"},"$:/config/shortcuts-not-mac/new-tiddler":{"title":"$:/config/shortcuts-not-mac/new-tiddler","text":"alt-N"},"$:/config/shortcuts-not-mac/refresh":{"title":"$:/config/shortcuts-not-mac/refresh","text":"ctrl-R"},"$:/config/shortcuts/add-field":{"title":"$:/config/shortcuts/add-field","text":"enter"},"$:/config/shortcuts/advanced-search":{"title":"$:/config/shortcuts/advanced-search","text":"ctrl-shift-A"},"$:/config/shortcuts/advanced-search-sidebar":{"title":"$:/config/shortcuts/advanced-search-sidebar","text":"alt-Enter"},"$:/config/shortcuts/cancel-edit-tiddler":{"title":"$:/config/shortcuts/cancel-edit-tiddler","text":"escape"},"$:/config/shortcuts/change-sidebar-layout":{"title":"$:/config/shortcuts/change-sidebar-layout","text":"shift-alt-Down"},"$:/config/shortcuts/delete-field":{"title":"$:/config/shortcuts/delete-field","text":"shift-alt-D"},"$:/config/shortcuts/excise":{"title":"$:/config/shortcuts/excise","text":"ctrl-E"},"$:/config/shortcuts/sidebar-search":{"title":"$:/config/shortcuts/sidebar-search","text":"ctrl-shift-F"},"$:/config/shortcuts/heading-1":{"title":"$:/config/shortcuts/heading-1","text":"ctrl-1"},"$:/config/shortcuts/heading-2":{"title":"$:/config/shortcuts/heading-2","text":"ctrl-2"},"$:/config/shortcuts/heading-3":{"title":"$:/config/shortcuts/heading-3","text":"ctrl-3"},"$:/config/shortcuts/heading-4":{"title":"$:/config/shortcuts/heading-4","text":"ctrl-4"},"$:/config/shortcuts/heading-5":{"title":"$:/config/shortcuts/heading-5","text":"ctrl-5"},"$:/config/shortcuts/heading-6":{"title":"$:/config/shortcuts/heading-6","text":"ctrl-6"},"$:/config/shortcuts/input-accept":{"title":"$:/config/shortcuts/input-accept","text":"Enter"},"$:/config/shortcuts/input-accept-variant":{"title":"$:/config/shortcuts/input-accept-variant","text":"ctrl-Enter"},"$:/config/shortcuts/input-cancel":{"title":"$:/config/shortcuts/input-cancel","text":"Escape"},"$:/config/shortcuts/input-down":{"title":"$:/config/shortcuts/input-down","text":"Down"},"$:/config/shortcuts/input-tab-left":{"title":"$:/config/shortcuts/input-tab-left","text":"alt-ctrl-Left"},"$:/config/shortcuts/input-tab-right":{"title":"$:/config/shortcuts/input-tab-right","text":"alt-ctrl-Right"},"$:/config/shortcuts/input-up":{"title":"$:/config/shortcuts/input-up","text":"Up"},"$:/config/shortcuts/layout-switcher":{"title":"$:/config/shortcuts/layout-switcher","text":"ctrl-shift-L"},"$:/config/shortcuts/link":{"title":"$:/config/shortcuts/link","text":"ctrl-L"},"$:/config/shortcuts/linkify":{"title":"$:/config/shortcuts/linkify","text":"alt-shift-L"},"$:/config/shortcuts/list-bullet":{"title":"$:/config/shortcuts/list-bullet","text":"ctrl-shift-L"},"$:/config/shortcuts/list-number":{"title":"$:/config/shortcuts/list-number","text":"ctrl-shift-N"},"$:/config/shortcuts/mono-block":{"title":"$:/config/shortcuts/mono-block","text":"ctrl-shift-M"},"$:/config/shortcuts/mono-line":{"title":"$:/config/shortcuts/mono-line","text":"ctrl-M"},"$:/config/shortcuts/open-control-panel":{"title":"$:/config/shortcuts/open-control-panel","text":"ctrl-alt-C"},"$:/config/shortcuts/picture":{"title":"$:/config/shortcuts/picture","text":"ctrl-shift-I"},"$:/config/shortcuts/preview":{"title":"$:/config/shortcuts/preview","text":"alt-P"},"$:/config/shortcuts/quote":{"title":"$:/config/shortcuts/quote","text":"ctrl-Q"},"$:/config/shortcuts/save-tiddler":{"title":"$:/config/shortcuts/save-tiddler","text":"ctrl+enter"},"$:/config/shortcuts/save-wiki":{"title":"$:/config/shortcuts/save-wiki","text":"ctrl-S"},"$:/config/shortcuts/stamp":{"title":"$:/config/shortcuts/stamp","text":"ctrl-S"},"$:/config/shortcuts/strikethrough":{"title":"$:/config/shortcuts/strikethrough","text":"ctrl-T"},"$:/config/shortcuts/subscript":{"title":"$:/config/shortcuts/subscript","text":"ctrl-shift-B"},"$:/config/shortcuts/superscript":{"title":"$:/config/shortcuts/superscript","text":"ctrl-shift-P"},"$:/config/shortcuts/toggle-sidebar":{"title":"$:/config/shortcuts/toggle-sidebar","text":"alt-shift-S"},"$:/config/shortcuts/transcludify":{"title":"$:/config/shortcuts/transcludify","text":"alt-shift-T"},"$:/config/ui/EditTemplate":{"title":"$:/config/ui/EditTemplate","text":"$:/core/ui/EditTemplate"},"$:/config/ui/ViewTemplate":{"title":"$:/config/ui/ViewTemplate","text":"$:/core/ui/ViewTemplate"},"$:/config/WikiParserRules/Inline/wikilink":{"title":"$:/config/WikiParserRules/Inline/wikilink","text":"disable"},"$:/snippets/currpalettepreview":{"title":"$:/snippets/currpalettepreview","text":"\\define resolve-colour(macrocall)\n\\import $:/core/macros/utils\n\\whitespace trim\n<$wikify name=\"name\" text=\"\"\"$macrocall$\"\"\">\n<<name>>\n</$wikify>\n\\end\n\\define swatchStyle()\nbackground-color: $(swatchColour)$;\n\\end\n\\define swatch-inner()\n\\whitespace trim\n<$set name=\"swatchColour\" value={{##$(colourResolved)$}}>\n<$list filter=\"[<swatchColour>!prefix[<<colour ]!suffix[>>]]\" variable=\"ignore\">\n<div class=\"tc-swatch\" style=<<swatchStyle>> title=<<swatchTitle>>/>\n&#32;\n</$list>\n<$list filter=\"[<swatchColour>prefix[<<colour ]suffix[>>]]\" variable=\"ignore\">\n<$wikify name=\"colourResolved\" text=\"<$macrocall $name='resolve-colour' macrocall=<<swatchColour>>/>\">\n<<swatch-inner>>\n</$wikify>\n</$list>\n</$set>\n\\end\n\\define swatch()\n\\whitespace trim\n<$set name=\"swatchColour\" value={{##$(colour)$}}>\n<$set name=\"swatchTitle\" value=<<colour>>>\n<$list filter=\"[<swatchColour>!prefix[<<colour ]!suffix[>>]]\" variable=\"ignore\">\n<div class=\"tc-swatch\" style=<<swatchStyle>> title=<<swatchTitle>>/>\n&#32;\n</$list>\n<$list filter=\"[<swatchColour>prefix[<<colour ]suffix[>>]]\" variable=\"ignore\">\n<$wikify name=\"colourResolved\" text=\"<$macrocall $name='resolve-colour' macrocall=<<swatchColour>>/>\">\n<<swatch-inner>>\n</$wikify>\n</$list>\n</$set>\n</$set>\n\\end\n\\whitespace trim\n<div class=\"tc-swatches-horiz\"><$list filter=\"\nforeground\nbackground\nmuted-foreground\nprimary\npage-background\ntab-background\ntiddler-info-background\n\" variable=\"colour\"><<swatch>></$list></div>\n"},"$:/snippets/DebugStylesheets":{"title":"$:/snippets/DebugStylesheets","text":"\\whitespace trim\n<style>[test]{list-style:'❌'}</style>\n<ul>\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Stylesheet]has[modified]]\" counter=\"n\">\n<style>{{!!text}}[test=\"<<n>>\"]{list-style:disc;}</style>\n<li test=<<n>>><$link/></li>\n</$list>\n</ul>\n"},"$:/snippets/download-wiki-button":{"title":"$:/snippets/download-wiki-button","text":"\\define lingo-base() $:/language/ControlPanel/Tools/Download/\n\\whitespace trim\n<$button class=\"tc-btn-big-green\">\n<$action-sendmessage $message=\"tm-download-file\" $param=\"$:/core/save/all\" filename=\"index.html\"/>\n<<lingo Full/Caption>>&#32;{{$:/core/images/save-button-dynamic}}\n</$button>"},"$:/language":{"title":"$:/language","text":"$:/languages/en-GB"},"$:/snippets/languageswitcher":{"title":"$:/snippets/languageswitcher","text":"\\define flag-title()\n$(languagePluginTitle)$/icon\n\\end\n\\whitespace trim\n\n<$linkcatcher to=\"$:/language\">\n<div class=\"tc-chooser tc-language-chooser\">\n<$list filter=\"[[$:/languages/en-GB]] [plugin-type[language]sort[description]]\">\n<$set name=\"cls\" filter=\"[all[current]field:title{$:/language}]\" value=\"tc-chooser-item tc-chosen\" emptyValue=\"tc-chooser-item\"><div class=<<cls>>>\n<$link>\n<span class=\"tc-image-button\">\n<$set name=\"languagePluginTitle\" value=<<currentTiddler>>>\n<$transclude subtiddler=<<flag-title>>>\n<$list filter=\"[all[current]field:title[$:/languages/en-GB]]\">\n<$transclude tiddler=\"$:/languages/en-GB/icon\"/>\n</$list>\n</$transclude>\n</$set>\n</span>\n&#32;\n<$view field=\"description\">\n<$view field=\"name\">\n<$view field=\"title\"/>\n</$view>\n</$view>\n</$link>\n</div>\n</$set>\n</$list>\n</div>\n</$linkcatcher>"},"$:/core/macros/CSS":{"title":"$:/core/macros/CSS","tags":"$:/tags/Macro","text":"<!-- Needs to stay that way for backwards compatibility. See GH issue: #8326 -->\n\\define colour(name)\n\\whitespace trim\n<$transclude tiddler={{$:/palette}} index=\"$name$\">\n\t<$transclude tiddler=\"$:/palettes/Vanilla\" index=\"$name$\">\n\t\t<$transclude tiddler=\"$:/config/DefaultColourMappings/$name$\"/>\n\t</$transclude>\n</$transclude>\n\\end\n\n\\define color(name) <<colour $name$>>\n\n\\define box-shadow(shadow)\n``\n-webkit-box-shadow: $shadow$;\n\t-moz-box-shadow: $shadow$;\n\t\tbox-shadow: $shadow$;\n``\n\\end\n\n\\define filter(filter)\n``\n-webkit-filter: $filter$;\n\t-moz-filter: $filter$;\n\t\tfilter: $filter$;\n``\n\\end\n\n\\define transition(transition)\n``\n-webkit-transition: $transition$;\n\t-moz-transition: $transition$;\n\t\ttransition: $transition$;\n``\n\\end\n\n\\define transform-origin(origin)\n``\n-webkit-transform-origin: $origin$;\n\t-moz-transform-origin: $origin$;\n\t\ttransform-origin: $origin$;\n``\n\\end\n\n\\define background-linear-gradient(gradient)\n``\nbackground-image: linear-gradient($gradient$);\nbackground-image: -o-linear-gradient($gradient$);\nbackground-image: -moz-linear-gradient($gradient$);\nbackground-image: -webkit-linear-gradient($gradient$);\nbackground-image: -ms-linear-gradient($gradient$);\n``\n\\end\n\n\\define column-count(columns)\n``\n-moz-column-count: $columns$;\n-webkit-column-count: $columns$;\ncolumn-count: $columns$;\n``\n\\end\n\n\\procedure datauri(title)\n<$macrocall $name=\"makedatauri\" type={{{ [<title>get[type]] }}} text={{{ [<title>get[text]] }}} _canonical_uri={{{ [<title>get[_canonical_uri]] }}}/>\n\\end\n\n\\procedure if-sidebar(text)\n<$reveal state=\"$:/state/sidebar\" type=\"match\" text=\"yes\" default=\"yes\"><<text>></$reveal>\n\\end\n\n\\procedure if-no-sidebar(text)\n<$reveal state=\"$:/state/sidebar\" type=\"nomatch\" text=\"yes\" default=\"yes\"><<text>></$reveal>\n\\end\n\n\\procedure if-background-attachment(text)\n<$reveal state=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimage\" type=\"nomatch\" text=\"\"><<text>></$reveal>\n\\end\n"},"$:/core/macros/colour-picker":{"title":"$:/core/macros/colour-picker","tags":"$:/tags/Macro","text":"\\define colour-picker-update-recent()\n<$action-listops\n\t$tiddler=\"$:/config/ColourPicker/Recent\"\n\t$subfilter=\"$(colour-picker-value)$ [list[$:/config/ColourPicker/Recent]remove[$(colour-picker-value)$]] +[limit[8]]\"\n/>\n\\end\n\n\\define colour-picker-inner(actions)\n<$button tag=\"a\" tooltip=\"\"\"$(colour-picker-value)$\"\"\">\n$(colour-picker-update-recent)$\n<$transclude $variable=\"__actions__\"/>\n\n<span style=\"display:inline-block; background-color: $(colour-picker-value)$; width: 100%; height: 100%; border-radius: 50%;\"/>\n\n</$button>\n\\end\n\n\\define colour-picker-recent-inner(actions)\n\\whitespace trim\n<$set name=\"colour-picker-value\" value=\"$(recentColour)$\">\n<$macrocall $name=\"colour-picker-inner\" actions=<<__actions__>>/>\n</$set>\n\\end\n\n\\define colour-picker-recent(actions)\n\\whitespace trim\n{{$:/language/ColourPicker/Recent}}<$list filter=\"[list[$:/config/ColourPicker/Recent]]\" variable=\"recentColour\">\n&#32;\n<$macrocall $name=\"colour-picker-recent-inner\" actions=<<__actions__>>/>\n</$list>\n\\end\n\n\\define colour-picker(actions)\n\\whitespace trim\n<div class=\"tc-colour-chooser\">\n\n<$macrocall $name=\"colour-picker-recent\" actions=<<__actions__>>/>\n\n---\n\n<$list filter=\"LightPink Pink Crimson LavenderBlush PaleVioletRed HotPink DeepPink MediumVioletRed Orchid Thistle Plum Violet Magenta Fuchsia DarkMagenta Purple MediumOrchid DarkViolet DarkOrchid Indigo BlueViolet MediumPurple MediumSlateBlue SlateBlue DarkSlateBlue Lavender GhostWhite Blue MediumBlue MidnightBlue DarkBlue Navy RoyalBlue CornflowerBlue LightSteelBlue LightSlateGrey SlateGrey DodgerBlue AliceBlue SteelBlue LightSkyBlue SkyBlue DeepSkyBlue LightBlue PowderBlue CadetBlue Azure LightCyan PaleTurquoise Cyan Aqua DarkTurquoise DarkSlateGrey DarkCyan Teal MediumTurquoise LightSeaGreen Turquoise Aquamarine MediumAquamarine MediumSpringGreen MintCream SpringGreen MediumSeaGreen SeaGreen Honeydew LightGreen PaleGreen DarkSeaGreen LimeGreen Lime ForestGreen Green DarkGreen Chartreuse LawnGreen GreenYellow DarkOliveGreen YellowGreen OliveDrab Beige LightGoldenrodYellow Ivory LightYellow Yellow Olive DarkKhaki LemonChiffon PaleGoldenrod Khaki Gold Cornsilk Goldenrod DarkGoldenrod FloralWhite OldLace Wheat Moccasin Orange PapayaWhip BlanchedAlmond NavajoWhite AntiqueWhite Tan BurlyWood Bisque DarkOrange Linen Peru PeachPuff SandyBrown Chocolate SaddleBrown Seashell Sienna LightSalmon Coral OrangeRed DarkSalmon Tomato MistyRose Salmon Snow LightCoral RosyBrown IndianRed Red Brown FireBrick DarkRed Maroon White WhiteSmoke Gainsboro LightGrey Silver DarkGrey Grey DimGrey Black\" variable=\"colour-picker-value\">\n&#32;\n<$macrocall $name=\"colour-picker-inner\" actions=<<__actions__>>/>\n</$list>\n\n---\n\n<$edit-text tiddler=\"$:/config/ColourPicker/New\" tag=\"input\" default=\"\" placeholder=\"\"/>\n&#32;\n<$edit-text tiddler=\"$:/config/ColourPicker/New\" type=\"color\" tag=\"input\"/>\n<$set name=\"colour-picker-value\" value={{$:/config/ColourPicker/New}}>\n<$macrocall $name=\"colour-picker-inner\" actions=<<__actions__>>/>\n</$set>\n\n</div>\n\n\\end\n"},"$:/core/macros/copy-to-clipboard":{"title":"$:/core/macros/copy-to-clipboard","tags":"$:/tags/Macro","text":"\\whitespace trim\n\n\\procedure copy-to-clipboard(src,class:\"tc-btn-invisible\",style)\n<$button message=\"tm-copy-to-clipboard\"\n\tparam=<<src>>\n\tclass=<<class>>\n\tstyle=<<style>>\n\ttooltip={{$:/language/Buttons/CopyToClipboard/Hint}}\n>\n\t{{$:/core/images/copy-clipboard}}\n\t<span class=\"tc-tiny-gap-left\">\n\t\t<$text text={{$:/language/Buttons/CopyToClipboard/Caption}}/>\n\t</span>\n</$button>\n\\end\n\n\\procedure copy-to-clipboard-above-right(src,class:\"tc-btn-invisible\",style)\n<div style=\"position: relative;\">\n\t<div style=\"position: absolute; bottom: 0; right: 0;\">\n\t\t<$macrocall $name=\"copy-to-clipboard\" src=<<src>> class=<<class>> style=<<style>>/>\n\t</div>\n</div>\n\\end\n"},"$:/core/macros/diff":{"title":"$:/core/macros/diff","tags":"$:/tags/Macro","text":"\\whitespace trim\n\n\\procedure compareTiddlerText(sourceTiddlerTitle,sourceSubTiddlerTitle,destTiddlerTitle,destSubTiddlerTitle)\n<$set name=\"source\" tiddler=<<sourceTiddlerTitle>> subtiddler=<<sourceSubTiddlerTitle>>>\n\t<$set name=\"dest\" tiddler=<<destTiddlerTitle>> subtiddler=<<destSubTiddlerTitle>>>\n\t\t<$diff-text source=<<source>> dest=<<dest>>/>\n\t</$set>\n</$set>\n\\end\n\n\\procedure compareTiddlers(sourceTiddlerTitle,sourceSubTiddlerTitle,destTiddlerTitle,destSubTiddlerTitle,exclude)\n<table class=\"tc-diff-tiddlers\">\n\t<tbody>\n\t\t<$set name=\"sourceFields\" filter=\"[<sourceTiddlerTitle>fields[]sort[]]\">\n\t\t\t<$set name=\"destFields\" filter=\"[<destSubTiddlerTitle>subtiddlerfields<destTiddlerTitle>sort[]]\">\n\t\t\t<$list filter=\"[enlist<sourceFields>] [enlist<destFields>] -[enlist<exclude>] +[sort[]]\" variable=\"fieldName\">\n\t\t\t\t<tr>\n\t\t\t\t\t<th>\n\t\t\t\t\t\t<$text text=<<fieldName>>/>\n\t\t\t\t\t</th>\n\t\t\t\t\t<td>\n\t\t\t\t\t\t<$set name=\"source\" tiddler=<<sourceTiddlerTitle>> subtiddler=<<sourceSubTiddlerTitle>> field=<<fieldName>>>\n\t\t\t\t\t\t\t<$set name=\"dest\" tiddler=<<destTiddlerTitle>> subtiddler=<<destSubTiddlerTitle>> field=<<fieldName>>>\n\t\t\t\t\t\t\t\t<$diff-text source=<<source>> dest=<<dest>>>&#32;</$diff-text>\n\t\t\t\t\t\t\t</$set>\n\t\t\t\t\t\t</$set>\n\t\t\t\t\t</td>\n\t\t\t\t</tr>\n\t\t\t</$list>\n\t\t\t</$set>\n\t\t</$set>\n\t</tbody>\n</table>\n\\end\n"},"$:/core/macros/dumpvariables":{"title":"$:/core/macros/dumpvariables","tags":"$:/tags/Macro","text":"\\define dumpvariables()\n\\whitespace trim\n<ul>\n<$list filter=\"[variables[]]\" variable=\"varname\">\n<li>\n<strong><code><$text text=<<varname>>/></code></strong>:<br/>\n<$codeblock code={{{ [<varname>getvariable[]] }}}/>\n</li>\n</$list>\n</ul>\n\\end\n"},"$:/core/macros/export":{"title":"$:/core/macros/export","tags":"$:/tags/Macro","text":"\\function exportButtonFilename(baseFilename)\n[<baseFilename>] [<extension>] +[join[]]\n\\end\n\n\\procedure exportButton(exportFilter:\"[!is[system]sort[title]]\",lingoBase,baseFilename:\"tiddlers\")\n\\whitespace trim\n<$let hint={{{ [<lingoBase>addsuffix[Hint]get[text]] }}}\n\tcaption={{{  [<lingoBase>addsuffix[Caption]get[text]] }}}\n>\n\t<span class=\"tc-popup-keep\">\n\t\t<$button popup=<<qualify \"$:/state/popup/export\">>\n\t\t\ttooltip=<<hint>>\n\t\t\taria-label=<<caption>>\n\t\t\tclass=<<tv-config-toolbar-class>>\n\t\t\tselectedClass=\"tc-selected\"\n\t\t\tdragFilter=<<exportFilter>>\n\t\t>\n\t\t\t<%if [<tv-config-toolbar-icons>match[yes]] %>\n\t\t\t\t{{$:/core/images/export-button}}\n\t\t\t<%endif%>\n\t\t\t<%if [<tv-config-toolbar-text>match[yes]] %>\n\t\t\t\t<span class=\"tc-btn-text\"><$text text=<<caption>>/></span>\n\t\t\t<%endif%>\n\t\t</$button>\n\t</span>\n</$let>\n<$reveal state=<<qualify \"$:/state/popup/export\">> type=\"popup\" position=\"below\" animate=\"yes\">\n\t<div class=\"tc-drop-down\">\n\t\t<$set name=\"count\" value={{{ [subfilter<exportFilter>count[]] }}}>\n\t\t\t<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Exporter]]\">\n\t\t\t\t<$list filter=\"[<currentTiddler>has[condition]subfilter{!!condition}limit[1]] ~[<currentTiddler>!has[condition]then[true]]\"\n\t\t\t\t\tvariable=\"ignore\"\n\t\t\t\t>\n\t\t\t\t\t<$button class=\"tc-btn-invisible\">\n\t\t\t\t\t\t<$action-sendmessage $message=\"tm-download-file\"\n\t\t\t\t\t\t\t$param=<<currentTiddler>>\n\t\t\t\t\t\t\texportFilter=<<exportFilter>>\n\t\t\t\t\t\t\tfilename={{{ [<baseFilename>addsuffix{!!extension}] }}}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<$action-deletetiddler $tiddler=<<qualify \"$:/state/popup/export\">>/>\n\t\t\t\t\t\t<$transclude field=\"description\"/>\n\t\t\t\t\t</$button>\n\t\t\t\t</$list>\n\t\t\t</$list>\n\t\t</$set>\n\t</div>\n</$reveal>\n\\end\n"},"$:/core/macros/image-picker":{"title":"$:/core/macros/image-picker","created":"20170715180840889","modified":"20170715180914005","tags":"$:/tags/Macro","type":"text/vnd.tiddlywiki","text":"\\define image-picker-thumbnail(actions)\n<$button tag=\"a\" tooltip=\"\"\"$(imageTitle)$\"\"\"><$transclude $variable=\"__actions__\"/><$transclude tiddler=<<imageTitle>>/></$button>\n\\end\n\n\\define image-picker-list(filter,actions)\n\\whitespace trim\n<$list filter=\"\"\"$filter$\"\"\" variable=\"imageTitle\">\n<$macrocall $name=\"image-picker-thumbnail\" actions=<<__actions__>>/>\n&#32;\n</$list>\n\\end\n\n\\define image-picker(actions,filter:\"[all[shadows+tiddlers]is[image]] -[type[application/pdf]] +[!has[draft.of]$subfilter$sort[title]]\",subfilter:\"\")\n\\whitespace trim\n<div class=\"tc-image-chooser\">\n<$vars state-system=<<qualify \"$:/state/image-picker/system\">>>\n<$checkbox tiddler=<<state-system>> field=\"text\" checked=\"show\" unchecked=\"hide\" default=\"hide\">\n&#32;\n{{$:/language/SystemTiddlers/Include/Prompt}}\n</$checkbox>\n<$reveal state=<<state-system>> type=\"match\" text=\"hide\" default=\"hide\" tag=\"div\">\n<$macrocall $name=\"image-picker-list\" filter=\"\"\"$filter$ +[!is[system]]\"\"\" actions=<<__actions__>>/>\n</$reveal>\n<$reveal state=<<state-system>> type=\"nomatch\" text=\"hide\" default=\"hide\" tag=\"div\">\n<$macrocall $name=\"image-picker-list\" filter=\"\"\"$filter$\"\"\" actions=<<__actions__>>/>\n</$reveal>\n</$vars>\n</div>\n\\end\n\n\\define image-picker-include-tagged-images(actions)\n<$macrocall $name=\"image-picker\" filter=\"[all[shadows+tiddlers]is[image]] [all[shadows+tiddlers]tag[$:/tags/Image]] -[type[application/pdf]] +[!has[draft.of]sort[title]]\" actions=<<__actions__>>/>\n\\end\n"},"$:/core/macros/keyboard-driven-input":{"title":"$:/core/macros/keyboard-driven-input","tags":"$:/tags/Macro","text":"\\procedure prefix.bracket() [\n\\procedure suffix.bracket() ]\n\n\\function tf.change-input-tab.next-tab() [[all]addprefix<prefix.bracket>addsuffix<prefix.bracket>addsuffix[shadows+tiddlers]addsuffix<suffix.bracket>addsuffix[tag<tag>!has]addsuffix<prefix.bracket>addsuffix[draft.of]addsuffix<suffix.bracket>addsuffix<beforeafter>addsuffix[<currentState>]addsuffix<suffix.bracket>addsuffix[ :else]addsuffix<prefix.bracket>addsuffix<prefix.bracket>addsuffix<beforeafter>addsuffix<suffix.bracket>addsuffix[match]addsuffix<prefix.bracket>addsuffix[after]addsuffix<suffix.bracket>addsuffix[then<firstTab>]addsuffix<suffix.bracket>addsuffix[ :else]addsuffix<prefix.bracket>addsuffix<prefix.bracket>addsuffix<beforeafter>addsuffix<suffix.bracket>addsuffix[match]addsuffix<prefix.bracket>addsuffix[before]addsuffix<suffix.bracket>addsuffix[then<lastTab>]addsuffix<suffix.bracket>]\n\n\\procedure change-input-tab(stateTitle,tag,beforeafter,defaultState,actions)\n\\whitespace trim\n<$set name=\"tabsList\" filter=\"[<explicitTabList>!is[blank]enlist-input[]] :else[all[shadows+tiddlers]tag<tag>!has[draft.of]]\">\n\t<$let\n\t\tcurrentState={{{ [<stateTitle>!is[missing]get[text]] :else[<defaultState>] }}}\n\t\tfirstTab={{{ [enlist<tabsList>nth[1]] }}}\n\t\tlastTab={{{ [enlist<tabsList>last[]] }}}\n\t\tnextTabSubFilter=<<tf.change-input-tab.next-tab>>\n\t\tnextTab={{{ [subfilter<nextTabSubFilter>] }}}\n\t>\n\t\t<$action-setfield $tiddler=<<stateTitle>> text=<<nextTab>>/>\n\t\t<<actions>>\n\t</$let>\n</$set>\n\\end\n\n\\procedure keyboard-input-actions()\n\\whitespace trim\n<%if [<index>match[]] %>\n\t<$action-setfield $tiddler=<<storeTitle>> text={{{ [<tiddler>get<field>] }}}/>\n<% endif %>\n<%if [<index>!match[]] %>\n\t<$action-setfield $tiddler=<<storeTitle>> text={{{ [<tiddler>getindex<index>] }}}/>\n<% endif %>\n\\end\n\n\\procedure input-next-actions-inner()\n\\whitespace trim\n<%if [<nextItem>minlength[1]] %>\n\t<$action-setfield $tiddler=<<selectionStateTitle>> text=<<nextItem>>/>\n\t<%if [<index>match[]] %>\n\t\t<$action-setfield $tiddler=<<tiddler>> $field=<<field>> $value={{{ [<nextItem>] :and[splitregexp[(?:.(?!-))+$]] }}}/>\n\t<% endif %>\n\t<%if [<index>!match[]] %>\n\t\t<$action-setfield $tiddler=<<tiddler>> $index=<<index>> $value={{{ [<nextItem>] :and[splitregexp[(?:.(?!-))+$]] }}}/>\n\t<% endif %>\n\t<$action-setfield $tiddler=<<refreshTitle>> text=\"yes\"/>\n<% endif %>\n\\end\n\n\\procedure input-next-actions-after()\n\\whitespace trim\n<%if [<storeTitle>get[text]minlength<filterMinLength>] [<filterMinLength>match[0]] %>\n\t<$let\n\t\tuserInput={{{ [<storeTitle>get[text]] }}}\n\t\tselectedItem={{{ [<selectionStateTitle>get[text]] }}}\n\t\tconfigTiddler={{{ [subfilter<configTiddlerFilter>] }}}\n\t\tprimaryListFilter={{{ [<configTiddler>get<firstSearchFilterField>] }}}\n\t\tsecondaryListFilter={{{ [<configTiddler>get<secondSearchFilterField>] }}}\n\t>\n\t\t<$set\n\t\t\tname=\"filteredList\"\n\t\t\tfilter=\"[subfilter<primaryListFilter>addsuffix[-primaryList]] :all[subfilter<secondaryListFilter>addsuffix[-secondaryList]]\"\n\t\t>\n\t\t\t<$let\n\t\t\t\tnextItem={{{ [enlist<filteredList>after<selectedItem>] :else[enlist<filteredList>nth[1]] }}}\n\t\t\t\tfirstItem={{{ [enlist<filteredList>nth[1]] }}}\n\t\t\t\tlastItem={{{ [enlist<filteredList>last[]] }}}\n\t\t\t>\n\t\t\t\t<%if [<selectedItem>match<firstItem>!match<lastItem>] [<selectedItem>!match<firstItem>!match<lastItem>] %>\n\t\t\t\t\t<<input-next-actions-inner>>\n\t\t\t\t<%elseif [<selectedItem>match<lastItem>!match<firstItem>] %>\n\t\t\t\t\t<$set name=\"nextItem\" value={{{ [<userInput>addsuffix[-userInput]] }}}>\n\t\t\t\t\t\t<<input-next-actions-inner>>\n\t\t\t\t\t</$set>\n\t\t\t\t<%elseif [<selectedItem>match<firstItem>match<lastItem>] %>\n\t\t\t\t\t<$set name=\"nextItem\" value={{{ [<userInput>addsuffix[-userInput]] }}}>\n\t\t\t\t\t\t<<input-next-actions-inner>>\n\t\t\t\t\t</$set>\n\t\t\t\t<% endif %>\n\t\t\t</$let>\n\t\t</$set>\n\t</$let>\n<% endif %>\n\\end\n\n\\procedure input-next-actions-before()\n\\whitespace trim\n<%if [<storeTitle>get[text]minlength<filterMinLength>] [<filterMinLength>match[0]] %>\n\t<$let\n\t\tuserInput={{{ [<storeTitle>get[text]] }}}\n\t\tselectedItem={{{ [<selectionStateTitle>get[text]] }}}\n\t\tconfigTiddler={{{ [subfilter<configTiddlerFilter>] }}}\n\t\tprimaryListFilter={{{ [<configTiddler>get<firstSearchFilterField>] }}}\n\t\tsecondaryListFilter={{{ [<configTiddler>get<secondSearchFilterField>] }}}\n\t>\n\t\t<$set\n\t\t\tname=\"filteredList\"\n\t\t\tfilter=\"[subfilter<primaryListFilter>addsuffix[-primaryList]] :all[subfilter<secondaryListFilter>addsuffix[-secondaryList]]\"\n\t\t>\n\t\t\t<$let\n\t\t\t\tnextItem={{{ [enlist<filteredList>before<selectedItem>] :else[enlist<filteredList>reverse[]nth[1]] }}}\n\t\t\t\tfirstItem={{{ [enlist<filteredList>nth[1]] }}}\n\t\t\t\tlastItem={{{ [enlist<filteredList>last[]] }}}\n\t\t\t>\n\t\t\t\t<%if [<selectedItem>match<firstItem>!match<lastItem>] %>\n\t\t\t\t\t<$set name=\"nextItem\" value={{{ [<userInput>addsuffix[-userInput]] }}}>\n\t\t\t\t\t\t<<input-next-actions-inner>>\n\t\t\t\t\t</$set>\n\t\t\t\t<%elseif [<selectedItem>match<lastItem>!match<firstItem>] [<selectedItem>!match<firstItem>!match<lastItem>] %>\n\t\t\t\t\t<<input-next-actions-inner>>\n\t\t\t\t<%elseif [<selectedItem>match<firstItem>match<lastItem>] %>\n\t\t\t\t\t<$set name=\"nextItem\" value={{{ [<userInput>addsuffix[-userInput]] }}}>\n\t\t\t\t\t\t<<input-next-actions-inner>>\n\t\t\t\t\t</$set>\n\t\t\t\t<% endif %>\n\t\t\t</$let>\n\t\t</$set>\n\t</$let>\n<% endif %>\n\\end\n\n\\procedure keyboard-driven-input(tiddler,storeTitle,field:\"text\",index:\"\",tag:\"input\",type,focus:\"\",inputAcceptActions,inputAcceptVariantActions,inputCancelActions,placeholder:\"\",default:\"\",class,focusPopup,rows,minHeight,tabindex,size,autoHeight,filterMinLength:\"0\",refreshTitle,selectionStateTitle,cancelPopups:\"\",configTiddlerFilter,firstSearchFilterField:\"first-search-filter\",secondSearchFilterField:\"second-search-filter\")\n\\whitespace trim\n<$keyboard key=\"((input-accept))\" actions=<<inputAcceptActions>>>\n<$keyboard key=\"((input-accept-variant))\" actions=<<inputAcceptVariantActions>>>\n<$keyboard key=\"((input-up))\" actions=<<input-next-actions-before>>>\n<$keyboard key=\"((input-down))\" actions=<<input-next-actions-after>>>\n<$keyboard key=\"((input-cancel))\" actions=<<inputCancelActions>>>\n\t<$edit-text\n\t\ttiddler=<<tiddler>> field=<<field>> index=<<index>>\n\t\tinputActions=<<keyboard-input-actions>> tag=<<tag>> class=<<class>>\n\t\tplaceholder=<<placeholder>> default=<<default>> focusPopup=<<focusPopup>>\n\t\tfocus=<<focus>> type=<<type>> rows=<<rows>> minHeight=<<minHeight>>\n\t\ttabindex=<<tabindex>> size=<<size>> autoHeight=<<autoHeight>>\n\t\trefreshTitle=<<refreshTitle>> cancelPopups=<<cancelPopups>>\n\t/>\n</$keyboard>\n</$keyboard>\n</$keyboard>\n</$keyboard>\n</$keyboard>\n\\end\n"},"$:/core/macros/lingo":{"title":"$:/core/macros/lingo","tags":"$:/tags/Macro","text":"\\define lingo-base()\n$:/language/\n\\end\n\n\\define lingo(title)\n{{$(lingo-base)$$title$}}\n\\end\n"},"$:/core/macros/list":{"title":"$:/core/macros/list","tags":"$:/tags/Macro","text":"\\define list-links(filter,type:\"ul\",subtype:\"li\",class:\"\",emptyMessage,field:\"caption\")\n\\whitespace trim\n<$genesis $type=<<__type__>> class=<<__class__>>>\n\t<$list filter=<<__filter__>> emptyMessage=<<__emptyMessage__>>>\n\t\t<$genesis $type=<<__subtype__>>>\n\t\t\t<$link to={{!!title}}>\n\t\t\t\t<$let tv-wikilinks=\"no\">\n\t\t\t\t\t<$transclude field=<<__field__>>>\n\t\t\t\t\t\t<$view field=\"title\"/>\n\t\t\t\t\t</$transclude>\n\t\t\t\t</$let>\n\t\t\t</$link>\n\t\t</$genesis>\n\t</$list>\n</$genesis>\n\\end\n\n\\define list-links-draggable-drop-actions()\n<$action-listops $tiddler=<<targetTiddler>> $field=<<targetField>> $subfilter=\"+[insertbefore<actionTiddler>,<currentTiddler>]\"/>\n\\end\n\n\\define list-links-draggable(tiddler,field:\"list\",emptyMessage,type:\"ul\",subtype:\"li\",class:\"\",itemTemplate)\n\\whitespace trim\n<span class=\"tc-links-draggable-list\">\n\t<$vars targetTiddler=\"\"\"$tiddler$\"\"\" targetField=\"\"\"$field$\"\"\">\n\t\t<$genesis $type=<<__type__>> class=\"$class$\">\n\t\t\t<$list filter=\"[list[$tiddler$!!$field$]]\" emptyMessage=<<__emptyMessage__>>>\n\t\t\t\t<$droppable\n\t\t\t\t\tactions=<<list-links-draggable-drop-actions>>\n\t\t\t\t\ttag=\"\"\"$subtype$\"\"\"\n\t\t\t\t\tenable=<<tv-enable-drag-and-drop>>\n\t\t\t\t>\n\t\t\t\t\t<div class=\"tc-droppable-placeholder\"/>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<$transclude tiddler=\"\"\"$itemTemplate$\"\"\">\n\t\t\t\t\t\t\t<$link to={{!!title}}>\n\t\t\t\t\t\t\t\t<$let tv-wikilinks=\"no\">\n\t\t\t\t\t\t\t\t\t<$transclude field=\"caption\">\n\t\t\t\t\t\t\t\t\t\t<$view field=\"title\"/>\n\t\t\t\t\t\t\t\t\t</$transclude>\n\t\t\t\t\t\t\t\t</$let>\n\t\t\t\t\t\t\t</$link>\n\t\t\t\t\t\t</$transclude>\n\t\t\t\t\t</div>\n\t\t\t\t</$droppable>\n\t\t\t</$list>\n\t\t\t<$tiddler tiddler=\"\">\n\t\t\t\t<$droppable\n\t\t\t\t\tactions=<<list-links-draggable-drop-actions>> \n\t\t\t\t\ttag=\"div\"\n\t\t\t\t\tenable=<<tv-enable-drag-and-drop>>\n\t\t\t\t>\n\t\t\t\t\t<div class=\"tc-droppable-placeholder\">\n\t\t\t\t\t\t{{$:/core/images/blank}}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div style=\"height:0.5em;\"/>\n\t\t\t\t</$droppable>\n\t\t\t</$tiddler>\n\t\t</$genesis>\n\t</$vars>\n</span>\n\\end\n\n\\define list-tagged-draggable-drop-actions(tag)\n\\whitespace trim\n<!-- Save the current ordering of the tiddlers with this tag -->\n<$set name=\"order\" filter=\"[<__tag__>tagging[]]\">\n\t<!-- Remove any list-after or list-before fields from the tiddlers with this tag -->\n\t<$list filter=\"[<__tag__>tagging[]]\">\n\t\t<$action-deletefield $field=\"list-before\"/>\n\t\t<$action-deletefield $field=\"list-after\"/>\n\t</$list>\n\t<!-- Save the new order to the Tag Tiddler -->\n\t<$action-listops $tiddler=<<__tag__>> $field=\"list\" $filter=\"+[enlist<order>] +[insertbefore<actionTiddler>,<currentTiddler>]\"/>\n\t<!-- Make sure the newly added item has the right tag -->\n\t<!-- Removing this line makes dragging tags within the dropdown work as intended -->\n\t<!--<$action-listops $tiddler=<<actionTiddler>> $tags=<<__tag__>>/>-->\n\t<!-- Using the following 5 lines as replacement makes dragging titles from outside into the dropdown apply the tag -->\n\t<$list filter=\"[<actionTiddler>!contains:tags<__tag__>]\">\n\t\t<$fieldmangler tiddler=<<actionTiddler>>>\n\t\t\t<$action-sendmessage $message=\"tm-add-tag\" $param=<<__tag__>>/>\n\t\t</$fieldmangler>\n\t</$list>\n</$set>\n\\end\n\n\\define list-tagged-draggable(tag,subFilter,emptyMessage,itemTemplate,elementTag:\"div\",storyview:\"\")\n\\whitespace trim\n<span class=\"tc-tagged-draggable-list\">\n\t<$set name=\"tag\" value=<<__tag__>>>\n\t\t<$list\n\t\t\tfilter=\"[<__tag__>tagging[]$subFilter$]\"\n\t\t\temptyMessage=<<__emptyMessage__>>\n\t\t\tstoryview=<<__storyview__>>\n\t\t>\n\t\t\t<$genesis $type=<<__elementTag__>> class=\"tc-menu-list-item\">\n\t\t\t\t<$droppable\n\t\t\t\t\tactions=\"\"\"<$macrocall $name=\"list-tagged-draggable-drop-actions\" tag=<<__tag__>>/>\"\"\"\n\t\t\t\t\tenable=<<tv-enable-drag-and-drop>>\n\t\t\t\t>\n\t\t\t\t\t<$genesis $type=<<__elementTag__>> class=\"tc-droppable-placeholder\"/>\n\t\t\t\t\t<$genesis $type=<<__elementTag__>>>\n\t\t\t\t\t\t<$transclude tiddler=\"\"\"$itemTemplate$\"\"\">\n\t\t\t\t\t\t\t<$link to={{!!title}}>\n\t\t\t\t\t\t\t\t<$view field=\"title\"/>\n\t\t\t\t\t\t\t</$link>\n\t\t\t\t\t\t</$transclude>\n\t\t\t\t\t</$genesis>\n\t\t\t\t</$droppable>\n\t\t\t</$genesis>\n\t\t</$list>\n\t\t<$tiddler tiddler=\"\">\n\t\t\t<$droppable\n\t\t\t\tactions=\"\"\"<$macrocall $name=\"list-tagged-draggable-drop-actions\" tag=<<__tag__>>/>\"\"\"\n\t\t\t\tenable=<<tv-enable-drag-and-drop>>\n\t\t\t>\n\t\t\t\t<$genesis $type=<<__elementTag__>> class=\"tc-droppable-placeholder\"/>\n\t\t\t\t<$genesis $type=<<__elementTag__>> style=\"height:0.5em;\"/>\n\t\t\t</$droppable>\n\t\t</$tiddler>\n\t</$set>\n</span>\n\\end\n"},"$:/core/macros/show-filter-count":{"title":"$:/core/macros/show-filter-count","tags":"$:/tags/Macro","text":"\\whitespace trim\n\n\\procedure show-filter-count(filter)\n<$button class=\"tc-btn-invisible\">\n\t<$action-setfield $tiddler=\"$:/temp/advancedsearch\" $value=<<filter>>/>\n\t<$action-setfield $tiddler=\"$:/temp/advancedsearch/input\" $value=<<filter>>/>\n\t<$action-setfield $tiddler=\"$:/temp/advancedsearch/refresh\" text=\"yes\"/>\n\t<$action-setfield $tiddler=\"$:/state/tab--1498284803\" $value=\"$:/core/ui/AdvancedSearch/Filter\"/>\n\t<$action-navigate $to=\"$:/AdvancedSearch\"/>\n\t<$action-sendmessage $message=\"tm-focus-selector\" $param=\".tc-advanced-search input\"/>\n\t<span class=\"tc-small-gap-right\">''<$count filter=<<filter>>/>''</span>\n\t{{$:/core/images/advanced-search-button}}\n</$button>\n\\end"},"$:/core/macros/tabs":{"title":"$:/core/macros/tabs","tags":"$:/tags/Macro","code-body":"yes","text":"\\define tabs-button()\n\\whitespace trim\n<$button\n\tset=<<tabsState>>\n\tsetTo=<<currentTab>>\n\tdefault=<<__default__>>\n\tselectedClass=\"tc-tab-selected\"\n\ttooltip={{!!tooltip}}\n\trole=\"switch\"\n\tdata-tab-title=<<currentTab>>\n>\n\t<$tiddler tiddler=<<save-currentTiddler>>>\n\t\t<$set name=\"tv-wikilinks\" value=\"no\">\n\t\t\t<$transclude tiddler=<<__buttonTemplate__>> mode=\"inline\">\n\t\t\t\t<$transclude tiddler=<<currentTab>> field=\"caption\">\n\t\t\t\t\t<$macrocall $name=\"currentTab\" $type=\"text/plain\" $output=\"text/plain\"/>\n\t\t\t\t</$transclude>\n\t\t\t</$transclude>\n\t\t</$set>\n\t</$tiddler>\n\t<<__actions__>>\n</$button>\n\\end\n\n\\define tabs-tab()\n\\whitespace trim\n<$set name=\"save-currentTiddler\" value=<<currentTiddler>>>\n\t<$tiddler tiddler=<<currentTab>>>\n\t\t<<tabs-button>>\n\t</$tiddler>\n</$set>\n\\end\n\n\\define tabs-tab-list()\n\\whitespace trim\n<$list filter=<<__tabsList__>> variable=\"currentTab\" storyview=\"pop\">\n\t<<tabs-tab>>\n</$list>\n\\end\n\n\\define tabs-tab-body()\n\\whitespace trim\n<$list filter=<<__tabsList__>> variable=\"currentTab\">\n\t<$reveal type=\"match\" state=<<tabsState>> text=<<currentTab>> default=<<__default__>> retain=<<__retain__>> tag=\"div\">\n\t\t<$transclude tiddler=<<__template__>> mode=\"block\">\n\t\t\t<$transclude tiddler=<<currentTab>> mode=\"block\"/>\n\t\t</$transclude>\n\t</$reveal>\n</$list>\n\\end\n\n\\define tabs(tabsList,default,state:\"$:/state/tab\",class,template,buttonTemplate,retain,actions,explicitState)\n\\whitespace trim\n<$qualify title=<<__state__>> name=\"qualifiedState\">\n\t<$let tabsState={{{ [<__explicitState__>minlength[1]] ~[<qualifiedState>] }}}>\n\t\t<div class={{{ [[tc-tab-set]addsuffix[ ]addsuffix<__class__>] }}}>\n\t\t\t<div class={{{ [[tc-tab-buttons]addsuffix[ ]addsuffix<__class__>] }}}>\n\t\t\t\t<<tabs-tab-list>>\n\t\t\t</div>\n\t\t\t<div class={{{ [[tc-tab-divider]addsuffix[ ]addsuffix<__class__>] }}}/>\n\t\t\t<div class={{{ [[tc-tab-content]addsuffix[ ]addsuffix<__class__>] }}}>\n\t\t\t\t<<tabs-tab-body>>\n\t\t\t</div>\n\t\t</div>\n\t</$let>\n</$qualify>\n\\end"},"$:/core/macros/tag-picker":{"title":"$:/core/macros/tag-picker","tags":"$:/tags/Macro","first-search-filter":"[subfilter<tagListFilter>!is[system]search:title<userInput>]","second-search-filter":"[subfilter<tagListFilter>is[system]search:title<userInput>]","text":"<!--\n\tFields: \"first-search-filter\", \"second-search-filter\" are assigned to the keyboard-driven input macro with parameter: \"configTiddlerFilter\"\n\tThey __need to be the same__ as used for variables: \"nonSystemTagsFilter\" and \"systemTagsFilter\". See code below!\n-->\n\n\\whitespace trim\n\n<!-- tf.tagpicker-dropdown-id is needed if several tap-pickers are shown in one tiddler -->\n\\function tf.tagpicker-dropdown-id()\n\t[<qualify $:/state/popup/tags-auto-complete>]\n\t[[$(saveTiddler)$-[$(tagField)$-$(tagListFilter)$]substitute[]sha256[]] :and[join[/]]\n\\end\n\n\\function tf.tagpicker-dropdown-class() [<tf.tagpicker-dropdown-id>sha256[]addprefix[tc-]]\n\\function tf.get-tagpicker-focus-selector() [<tf.tagpicker-dropdown-class>addprefix[.]] .tc-popup-handle :and[join[ ]]\n\n<!-- clean up temporary tiddlers, so the next \"pick\" starts with a clean input -->\n<!-- This could probably be optimized / removed if we would use different temp-tiddlers\n\t(future improvement because keeping track is comlex for humans)\n-->\n\\procedure delete-tag-state-tiddlers()\n<$action-deletetiddler $filter=\"[<newTagNameTiddler>] [<storeTitle>] [<tagSelectionState>]\"/>\n\\end\n\n<!-- trigger __toggle tag__ by keyboard -->\n\\procedure add-tag-actions()\n<$let tag=<<_tf.getTag>> >\n\t<$action-listops $tiddler=<<saveTiddler>> $field=<<tagField>> $subfilter=':and[toggle<tag>trim[]]'/>\n\t<%if [<tag>] :intersection[<saveTiddler>get<tagField>enlist-input[]] %>\n\t\t<!-- tag has been removed - do nothing -->\n\t<%else%>\n\t\t<<actions>>\n\t<%endif%>\n\t<<delete-tag-state-tiddlers>>\n\t<$action-setfield $tiddler=<<refreshTitle>> text=\"yes\"/>\n</$let>\n\\end\n<!-- <$action-log  /> -->\n\n<!-- ESC key removes the text from the input\nThe second ESC tries to close the \"draft tiddler\"\n-->\n\\procedure clear-tags-actions-inner()\n<%if [<storeTitle>has[text]] :else[<newTagNameTiddler>has[text]] %>\n\t<<delete-tag-state-tiddlers>>\n<%else%>\n\t\t<<cancel-delete-tiddler-actions \"cancel\">>\n<%endif%>\n\\end\n\n<!-- triggered by keyboard only -->\n\\procedure clear-tags-actions()\n<$let userInput=<<_tf.getUserInput>> >\n\t<!-- this list __cannot__ be transformed to conditional IF. The list variable is used! -->\n\t<$list filter=\"[<newTagNameTiddler>get[text]!match<userInput>]\" >\n\t\t<$list-empty>\n\t\t\t<<clear-tags-actions-inner>>\n\t\t</$list-empty>\n\t\t<$action-setfield $tiddler=<<newTagNameTiddler>> text=<<userInput>>/>\n\t\t<$action-setfield $tiddler=<<refreshTitle>> text=\"yes\"/>\n\t</$list>\n</$let>\n\\end\n\n<!-- similar to add-tag-actions __but__ add-only -->\n\\procedure add-button-actions()\n<$action-listops $tiddler=<<saveTiddler>> $field=<<tagField>> $subfilter=\"[<tag>trim[]]\"/>\n<<actions>>\n<<delete-tag-state-tiddlers>>\n<$action-sendmessage $message=\"tm-focus-selector\" $param=<<tf.get-tagpicker-focus-selector>>/>\n\\end\n<!-- <$action-log /> -->\n\n<!-- create dropdown list -->\n\\procedure tag-picker-listTags(filter, suffix, empty)\n<$let userInput=<<_tf.getUserInput>> >\n\t<$list filter=\"[<userInput>minlength{$:/config/Tags/MinLength}limit[1]]\"\n\t\temptyMessage=\"<div class='tc-search-results'>{{$:/language/Search/Search/TooShort}}</div>\" variable=\"listItem\"\n\t>\n\t\t<$list filter=<<filter>> variable=\"tag\">\n\t\t\t<$list-empty>\n\t\t\t\t<span class=\"tc-small-gap-left\"><<empty>></span>\n\t\t\t</$list-empty>\n\t\t\t<!-- The buttonClasses filter is used to define tc-tag-button-selected state -->\n\t\t\t<!-- tf.get-tagpicker-focus-selector has to be resolved for $:/core/ui/TagPickerTagTemplate,\n\t\t\t\tothwerwise qualify in tf.tagpicker-dropdown-id causes problems -->\n\t\t\t<$let currentTiddler=<<tag>>\n\t\t\t\tbutton-classes=`tc-btn-invisible ${[<tag>addsuffix<suffix>] :except[<tagSelectionState>get[text]] :then[[]] ~tc-tag-button-selected }$`\n\t\t\t\tget-tagpicker-focus-selector=`${[<tf.get-tagpicker-focus-selector>]}$`\n\t\t\t>\n\t\t\t\t{{||$:/core/ui/TagPickerTagTemplate}}\n\t\t\t</$let>\n\t\t</$list>\n\t</$list>\n</$let>\n\\end\n\n<!-- tag-picker-inner is the main function -->\n\\procedure tag-picker-inner()\n<div class={{{ [[tc-edit-add-tag]] [<tf.tagpicker-dropdown-class>] :and[join[ ]] }}}>\n\t<div class=\"tc-edit-add-tag-ui\">\n\t\t<span class=\"tc-add-tag-name tc-small-gap-right\">\n\t\t\t<$transclude $variable=\"keyboard-driven-input\"\n\t\t\t\ttiddler=<<newTagNameTiddler>>\n\t\t\t\tstoreTitle=<<storeTitle>>\n\t\t\t\trefreshTitle=<<refreshTitle>>\n\t\t\t\tselectionStateTitle=<<tagSelectionState>>\n\t\t\t\tinputAcceptActions=<<add-tag-actions>>\n\t\t\t\tinputCancelActions=<<clear-tags-actions>>\n\t\t\t\ttag=\"input\"\n\t\t\t\tplaceholder={{$:/language/EditTemplate/Tags/Add/Placeholder}}\n\t\t\t\tfocusPopup=<<tf.tagpicker-dropdown-id>>\n\t\t\t\tclass=\"tc-edit-texteditor tc-popup-handle\"\n\t\t\t\ttabindex=<<tabIndex>>\n\t\t\t\tfocus={{{ [{$:/config/AutoFocus}match[tags]then[true]] :else[[false]] }}}\n\t\t\t\tfilterMinLength={{$:/config/Tags/MinLength}}\n\t\t\t\tcancelPopups=<<cancelPopups>>\n\t\t\t\tconfigTiddlerFilter=\"[[$:/core/macros/tag-picker]]\"\n\t\t\t/>\n\t\t</span>\n\t\t<$button popup=<<tf.tagpicker-dropdown-id>> class=\"tc-btn-invisible tc-btn-dropdown\"\n\t\t\ttooltip={{$:/language/EditTemplate/Tags/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Tags/Dropdown/Caption}}\n\t\t>\n\t\t\t{{$:/core/images/down-arrow}}\n\t\t</$button>\n\t\t<%if [<storeTitle>has[text]] %>\n\t\t\t<$button actions=<<delete-tag-state-tiddlers>> class=\"tc-btn-invisible tc-small-gap tc-btn-dropdown\"\n\t\t\t\ttooltip={{$:/language/EditTemplate/Tags/ClearInput/Hint}} aria-label={{$:/language/EditTemplate/Tags/ClearInput/Caption}}\n\t\t\t>\n\t\t\t\t{{$:/core/images/close-button}}\n\t\t\t</$button>\n\t\t<%endif%>\n\t\t<span class=\"tc-add-tag-button tc-small-gap-left\">\n\t\t\t<$let tag=<<_tf.getTag>>>\n\t\t\t\t<$button set=<<newTagNameTiddler>> actions=<<add-button-actions>> >\n\t\t\t\t\t{{$:/language/EditTemplate/Tags/Add/Button}}\n\t\t\t\t</$button>\n\t\t\t</$let>\n\t\t</span>\n\t</div>\n\t<div class=\"tc-block-dropdown-wrapper\">\n\t\t<%if [<tf.tagpicker-dropdown-id>has[text]] %>\n\t\t\t<div class=\"tc-block-dropdown tc-block-tags-dropdown\">\n\t\t\t\t<$transclude $variable=\"tag-picker-listTags\" filter=<<nonSystemTagsFilter>> suffix=\"-primaryList\" empty={{$:/language/EditTemplate/Tags/EmptyMessage}}/>\n\t\t\t\t<hr>\n\t\t\t\t<$transclude $variable=\"tag-picker-listTags\" filter=<<systemTagsFilter>> suffix=\"-secondaryList\" empty={{$:/language/EditTemplate/Tags/EmptyMessage/System}}/>\n\t\t\t</div>\n\t\t<%endif%>\n\t</div>\n</div>\n\\end\n\n<!-- prepare all variables for tag-picker keyboard handling -->\n\\procedure tag-picker(actions, tagField:\"tags\", tiddler, tagListFilter:\"[tags[]sort[]]\")\n\n\\function _tf.getUserInput() [<storeTitle>get[text]]\n\\function _tf.getTag() [<newTagNameTiddler>get[text]]\n<!-- Use this function if tag-picker is a stand alone macro. Otherwise use \"newTagNameTiddler\" defined for fieldmangler in EditTemplate -->\n\\function _tf.makeTagNameTiddler() [[$:/temp/NewTagName]] [<tagField>!match[tags]] :and[join[/]] [<qualify>] :and[join[]]\n\n<!-- keep those variables because they may \"bleed\" into macros using old syntax -->\n<!-- \"nonSystemTagsFilter\", \"systemTagsFilter\" __need to be the same__ as fields: \"first-search-filter\", \"second-search-filter\" -->\n<$let\n\tpalette={{$:/palette}}\n\tcolourA={{{ [<palette>getindex[foreground]] }}}\n\tcolourB={{{ [<palette>getindex[background]] }}}\n\tfallbackTarget={{{ [<palette>getindex[tag-background]] }}}\n\n\tsaveTiddler={{{ [<tiddler>is[blank]then<currentTiddler>else<tiddler>] }}}\n\n\tnewTagNameTiddler={{{ [[newTagNameTiddler]is[variable]then<newTagNameTiddler>] :else[<_tf.makeTagNameTiddler>] }}}\n\tstoreTitle={{{ [[$:/temp/NewTagName/input]] [<tagField>!match[tags]] :and[join[/]] [<qualify>] :and[join[]] }}}\n\n\tnewTagNameSelectionTiddlerQualified=<<qualify \"$:/temp/NewTagName/selected-item\">>\n\ttagSelectionState={{{ [<newTagNameSelectionTiddler>!match[]] :else[<newTagNameSelectionTiddlerQualified>] }}}\n\n\trefreshTitle=<<qualify \"$:/temp/NewTagName/refresh\">>\n\n\tnonSystemTagsFilter=\"[subfilter<tagListFilter>!is[system]search:title<userInput>]\"\n\tsystemTagsFilter=\"[subfilter<tagListFilter>is[system]search:title<userInput>]\"\n\n\tcancelPopups=\"yes\"\n>\n\t<$transclude $variable=\"tag-picker-inner\"/>\n</$let>\n\\end\n"},"$:/core/macros/tag":{"title":"$:/core/macros/tag","tags":"$:/tags/Macro","text":"\\define tag-pill-styles()\nbackground-color:$(backgroundColor)$;\nfill:$(foregroundColor)$;\ncolor:$(foregroundColor)$;\n\\end\n\n<!-- This has no whitespace trim to avoid modifying $actions$ -->\n\\define tag-pill-inner(tag,icon,colour,fallbackTarget,colourA,colourB,element-tag,element-attributes,actions)\n\\whitespace trim\n<$let\n\tforegroundColor=<<contrastcolour target:\"\"\"$colour$\"\"\" fallbackTarget:\"\"\"$fallbackTarget$\"\"\" colourA:\"\"\"$colourA$\"\"\" colourB:\"\"\"$colourB$\"\"\">>\n\tbackgroundColor=<<__colour__>>\n>\n<$element-tag$\n\t$element-attributes$\n\tclass=\"tc-tag-label tc-btn-invisible\"\n\tstyle=<<tag-pill-styles>>\n>\n\t<<__actions__>>\n\t<$transclude tiddler=<<__icon__>>/>\n\t<span class={{{ [<__tag__>is[missing]then[tc-tag-missing]else[tc-tag-exists]] }}}>\n\t\t<$view tiddler=<<__tag__>> field=\"title\" format=\"text\" />\n\t</span>\n</$element-tag$>\n</$let>\n\\end\n\n\\define tag-pill-body(tag,icon,colour,palette,element-tag,element-attributes,actions)\n\\whitespace trim\n<$macrocall $name=\"tag-pill-inner\"\n\ttag=<<__tag__>>\n\ticon=<<__icon__>>\n\tcolour=<<__colour__>>\n\tfallbackTarget={{$palette$##tag-background}}\n\tcolourA={{$palette$##foreground}}\n\tcolourB={{$palette$##background}}\n\telement-tag=<<__element-tag__>>\n\telement-attributes=<<__element-attributes__>>\n\tactions=<<__actions__>>\n/>\n\\end\n\n\\define tag-pill(tag,element-tag:\"span\",element-attributes:\"\",actions:\"\")\n\\whitespace trim\n<span class=\"tc-tag-list-item\" data-tag-title=<<__tag__>>>\n\t<$let currentTiddler=<<__tag__>>>\n\t\t<$macrocall $name=\"tag-pill-body\"\n\t\t\ttag=<<__tag__>>\n\t\t\ticon={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerIconFilter]!is[draft]get[text]] }}}\n\t\t\tcolour={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}}\n\t\t\tpalette={{$:/palette}}\n\t\t\telement-tag=<<__element-tag__>>\n\t\t\telement-attributes=<<__element-attributes__>>\n\t\t\tactions=<<__actions__>>/>\n\t</$let>\n</span>\n\\end\n\n\\define tag(tag)\n{{$tag$||$:/core/ui/TagTemplate}}\n\\end\n"},"$:/core/macros/testcase":{"title":"$:/core/macros/testcase","tags":"$:/tags/Macro","text":"\\whitespace trim\n\n\\procedure testcase(tiddler)\n<$tiddler tiddler=<<tiddler>>>\n<$transclude $tiddler=\"$:/core/ui/TestCaseTemplate\">\n</$tiddler>\n\\end\n"},"$:/core/macros/thumbnails":{"title":"$:/core/macros/thumbnails","tags":"$:/tags/Macro","text":"<!-- This macro does not use \\whitespace trim because it could affect the caption -->\n\\define thumbnail(link,icon,color,background-color,image,caption,width:\"280\",height:\"157\")\n<$link to=\"\"\"$link$\"\"\"><div class=\"tc-thumbnail-wrapper\"\n><div\n\tclass=\"tc-thumbnail-image\"\n\tstyle=\"width:$width$px;height:$height$px;\"><$reveal\n\ttype=\"nomatch\"\n\ttext=\"\"\n\tdefault=\"\"\"$image$\"\"\"\n\ttag=\"div\"\n\tstyle=\"width:$width$px;height:$height$px;\"\n>[img[$image$]]</$reveal><$reveal\n\ttype=\"match\"\n\ttext=\"\"\n\tdefault=\"\"\"$image$\"\"\"\n\ttag=\"div\"\n\tclass=\"tc-thumbnail-background\"\n\tstyle=\"width:$width$px;height:$height$px;background-color:$background-color$;\"\n></$reveal></div><div\n\tclass=\"tc-thumbnail-icon\"\n\tstyle=\"fill:$color$;color:$color$;\"\n>$icon$</div><div class=\"tc-thumbnail-caption\">$caption$</div></div></$link>\n\\end\n\n\\define thumbnail-right(link,icon,color,background-color,image,caption,width:\"280\",height:\"157\")\n<div class=\"tc-thumbnail-right-wrapper\"><<thumbnail \"\"\"$link$\"\"\" \"\"\"$icon$\"\"\" \"\"\"$color$\"\"\" \"\"\"$background-color$\"\"\" \"\"\"$image$\"\"\" \"\"\"$caption$\"\"\" \"\"\"$width$\"\"\" \"\"\"$height$\"\"\">></div>\n\\end\n\n\\define list-thumbnails(filter,width:\"280\",height:\"157\")\n<$list filter=\"\"\"$filter$\"\"\"><$macrocall $name=\"thumbnail\" link={{!!link}} icon={{!!icon}} color={{!!color}} background-color={{!!background-color}} image={{!!image}} caption={{!!caption}} width=\"\"\"$width$\"\"\" height=\"\"\"$height$\"\"\"/></$list>\n\\end\n"},"$:/core/macros/timeline":{"title":"$:/core/macros/timeline","tags":"$:/tags/Macro","text":"<!-- Override one or both of the following two macros with a global or local macro of the same name \nif you need to change how titles are displayed on a timeline -->\n\n\\procedure timeline-title() <$view field=\"title\"/>\n\\procedure timeline-link() <$link to={{!!title}}><<timeline-title>></$link>\n\\procedure timeline(limit:\"100\",format:\"DDth MMM YYYY\",subfilter:\"\",dateField:\"modified\")\n\\whitespace trim\n<div class=\"tc-timeline\">\n<$set name=\"tv-tids\" filter=`[!is[system]$(subfilter)$has<dateField>!sort<dateField>limit<limit>]`>\n<$list filter=\"[enlist<tv-tids>eachday<dateField>]\">\n<div class=\"tc-menu-list-item\">\n<$view field=<<dateField>> format=\"date\" template=<<format>>/>\n<$list filter=`[enlist<tv-tids>sameday:$(dateField)${!!$(dateField)$}]`>\n<div class=\"tc-menu-list-subitem\">\n<<timeline-link>>\n</div>\n</$list>\n</div>\n</$list>\n</$set>\n</div>\n\\end\n"},"$:/core/macros/toc":{"title":"$:/core/macros/toc","tags":"$:/tags/Macro","text":"\n\\define toc-open-icon() $:/core/images/down-arrow\n\\define toc-closed-icon() $:/core/images/right-arrow\n\n\\define toc-caption()\n\\whitespace trim\n<span class=\"tc-toc-caption tc-tiny-gap-left\">\n<$set name=\"tv-wikilinks\" value=\"no\">\n  <$transclude field=\"caption\">\n    <$view field=\"title\"/>\n  </$transclude>\n</$set>\n</span>\n\\end\n\n\\define toc-body(tag,sort:\"\",itemClassFilter,exclude,path)\n\\whitespace trim\n<ol class=\"tc-toc\">\n  <$list filter=\"\"\"[all[shadows+tiddlers]tag<__tag__>!has[draft.of]$sort$] -[<__tag__>] -[subfilter<__exclude__>]\"\"\">\n    <$let item=<<currentTiddler>> path={{{ [<__path__>addsuffix[/]addsuffix<__tag__>] }}}>\n      <$set name=\"excluded\" filter=\"[subfilter<__exclude__>] [<__tag__>]\">\n        <$set name=\"toc-item-class\" filter=<<__itemClassFilter__>> emptyValue=\"toc-item-selected\" value=\"toc-item\">\n          <li class=<<toc-item-class>>>\n            <$list filter=\"[all[current]toc-link[no]]\" emptyMessage=\"<$link to={{{ [<currentTiddler>get[target]else<currentTiddler>] }}}><<toc-caption>></$link>\">\n              <<toc-caption>>\n            </$list>\n            <$macrocall $name=\"toc-body\" tag=<<item>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<excluded>> path=<<path>>/>\n          </li>\n        </$set>\n      </$set>\n    </$let>\n  </$list>\n</ol>\n\\end\n\n\\define toc(tag,sort:\"\",itemClassFilter:\"\", exclude)\n\\whitespace trim\n<$let __tag__={{{ [<__tag__>is[blank]then<currentTiddler>else<__tag__>] }}} >\n  <$macrocall $name=\"toc-body\"  tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<__exclude__>>/>\n</$let>\n\\end\n\n\\define toc-linked-expandable-body(tag,sort:\"\",itemClassFilter,exclude,path)\n\\whitespace trim\n<!-- helper function -->\n<$qualify name=\"toc-state\" title={{{ [[$:/state/toc]addsuffix<__path__>addsuffix[-]addsuffix<currentTiddler>] }}}>\n  <$set name=\"toc-item-class\" filter=<<__itemClassFilter__>> emptyValue=\"toc-item-selected\" value=\"toc-item\">\n    <li class=<<toc-item-class>>>\n    <$link to={{{ [<currentTiddler>get[target]else<currentTiddler>] }}}>\n      <$reveal type=\"nomatch\" stateTitle=<<toc-state>> text=\"open\">\n        <$button setTitle=<<toc-state>> setTo=\"open\" class=\"tc-btn-invisible tc-popup-keep\">\n          <$transclude tiddler=<<toc-closed-icon>> />\n        </$button>\n      </$reveal>\n      <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n        <$button setTitle=<<toc-state>> setTo=\"close\" class=\"tc-btn-invisible tc-popup-keep\">\n          <$transclude tiddler=<<toc-open-icon>> />\n        </$button>\n      </$reveal>\n      <<toc-caption>>\n    </$link>\n    <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n      <$macrocall $name=\"toc-expandable\" tag=<<currentTiddler>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<__exclude__>> path=<<__path__>>/>\n    </$reveal>\n    </li>\n  </$set>\n</$qualify>\n\\end\n\n\\define toc-unlinked-expandable-body(tag,sort:\"\",itemClassFilter,exclude,path)\n\\whitespace trim\n<!-- helper function -->\n<$qualify name=\"toc-state\" title={{{ [[$:/state/toc]addsuffix<__path__>addsuffix[-]addsuffix<currentTiddler>] }}}>\n  <$set name=\"toc-item-class\" filter=<<__itemClassFilter__>> emptyValue=\"toc-item-selected\" value=\"toc-item\">\n    <li class=<<toc-item-class>>>\n      <$reveal type=\"nomatch\" stateTitle=<<toc-state>> text=\"open\">\n        <$button setTitle=<<toc-state>> setTo=\"open\" class=\"tc-btn-invisible tc-popup-keep\">\n        <$transclude tiddler=<<toc-closed-icon>> />\n          <<toc-caption>>\n        </$button>\n      </$reveal>\n      <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n        <$button setTitle=<<toc-state>> setTo=\"close\" class=\"tc-btn-invisible tc-popup-keep\">\n          <$transclude tiddler=<<toc-open-icon>> />\n          <<toc-caption>>\n        </$button>\n      </$reveal>\n      <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n        <$macrocall $name=\"toc-expandable\" tag=<<currentTiddler>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<__exclude__>> path=<<__path__>>/>\n      </$reveal>\n    </li>\n  </$set>\n</$qualify>\n\\end\n\n\\define toc-expandable-empty-message()\n<$macrocall $name=\"toc-linked-expandable-body\" tag=<<tag>> sort=<<sort>> itemClassFilter=<<itemClassFilter>> exclude=<<excluded>> path=<<path>>/>\n\\end\n\n\\define toc-expandable(tag,sort:\"\",itemClassFilter:\"\",exclude,path)\n\\whitespace trim\n<$let __tag__={{{ [<__tag__>is[blank]then<currentTiddler>else<__tag__>] }}} tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> path={{{ [<__path__>addsuffix[/]addsuffix<__tag__>] }}}>\n  <$set name=\"excluded\" filter=\"[subfilter<__exclude__>] [<__tag__>]\">\n    <ol class=\"tc-toc toc-expandable\">\n      <$list filter=\"\"\"[all[shadows+tiddlers]tag<__tag__>!has[draft.of]$sort$] -[<__tag__>] -[subfilter<__exclude__>]\"\"\">\n        <$list filter=\"[all[current]toc-link[no]]\" emptyMessage=<<toc-expandable-empty-message>> >\n          <$macrocall $name=\"toc-unlinked-expandable-body\" tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=\"\"\"itemClassFilter\"\"\" exclude=<<excluded>> path=<<path>> />\n        </$list>\n      </$list>\n    </ol>\n  </$set>\n</$let>\n\\end\n\n\\define toc-linked-selective-expandable-body(tag,sort:\"\",itemClassFilter,exclude,path)\n\\whitespace trim\n<$qualify name=\"toc-state\" title={{{ [[$:/state/toc]addsuffix<__path__>addsuffix[-]addsuffix<currentTiddler>] }}}>\n  <$set name=\"toc-item-class\" filter=<<__itemClassFilter__>> emptyValue=\"toc-item-selected\" value=\"toc-item\" >\n    <li class=<<toc-item-class>>>\n      <$link to={{{ [<currentTiddler>get[target]else<currentTiddler>] }}}>\n          <$list filter=\"[all[current]tagging[]$sort$limit[1]]  -[subfilter<__exclude__>]\" variable=\"ignore\" emptyMessage=\"<$button class='tc-btn-invisible'>{{$:/core/images/blank}}</$button>\">\n          <$reveal type=\"nomatch\" stateTitle=<<toc-state>> text=\"open\">\n            <$button setTitle=<<toc-state>> setTo=\"open\" class=\"tc-btn-invisible tc-popup-keep\">\n            <$transclude tiddler=<<toc-closed-icon>> />\n            </$button>\n          </$reveal>\n          <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n            <$button setTitle=<<toc-state>> setTo=\"close\" class=\"tc-btn-invisible tc-popup-keep\">\n              <$transclude tiddler=<<toc-open-icon>> />\n            </$button>\n          </$reveal>\n        </$list>\n        <<toc-caption>>\n      </$link>\n      <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n        <$macrocall $name=\"toc-selective-expandable\" tag=<<currentTiddler>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<__exclude__>> path=<<__path__>>/>\n      </$reveal>\n    </li>\n  </$set>\n</$qualify>\n\\end\n\n\\define toc-unlinked-selective-expandable-body(tag,sort:\"\",itemClassFilter,exclude,path)\n\\whitespace trim\n<$qualify name=\"toc-state\" title={{{ [[$:/state/toc]addsuffix<__path__>addsuffix[-]addsuffix<currentTiddler>] }}}>\n  <$set name=\"toc-item-class\" filter=<<__itemClassFilter__>> emptyValue=\"toc-item-selected\" value=\"toc-item\">\n    <li class=<<toc-item-class>>>\n      <$list filter=\"[all[current]tagging[]$sort$limit[1]] -[subfilter<__exclude__>]\" variable=\"ignore\" emptyMessage=\"\"\"<$button class=\"tc-btn-invisible\">{{$:/core/images/blank}}</$button><span class=\"toc-item-muted\"><<toc-caption>></span>\"\"\">\n        <$reveal type=\"nomatch\" stateTitle=<<toc-state>> text=\"open\">\n          <$button setTitle=<<toc-state>> setTo=\"open\" class=\"tc-btn-invisible tc-popup-keep\">\n            <$transclude tiddler=<<toc-closed-icon>> />\n            <<toc-caption>>\n          </$button>\n        </$reveal>\n        <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n          <$button setTitle=<<toc-state>> setTo=\"close\" class=\"tc-btn-invisible tc-popup-keep\">\n            <$transclude tiddler=<<toc-open-icon>> />\n            <<toc-caption>>\n          </$button>\n        </$reveal>\n      </$list>\n      <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n        <$macrocall $name=\"toc-selective-expandable\" tag=<<currentTiddler>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<__exclude__>> path=<<__path__>>/>\n      </$reveal>\n    </li>\n  </$set>\n</$qualify>\n\\end\n\n\\define toc-selective-expandable-empty-message()\n<$macrocall $name=\"toc-linked-selective-expandable-body\" tag=<<tag>> sort=<<sort>> itemClassFilter=<<itemClassFilter>> exclude=<<excluded>> path=<<path>>/>\n\\end\n\n\\define toc-selective-expandable(tag,sort:\"\",itemClassFilter,exclude,path)\n\\whitespace trim\n<$let __tag__={{{ [<__tag__>is[blank]then<currentTiddler>else<__tag__>] }}} tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> path={{{ [<__path__>addsuffix[/]addsuffix<__tag__>] }}}>\n  <$set name=\"excluded\" filter=\"[subfilter<__exclude__>] [<__tag__>]\">\n    <ol class=\"tc-toc toc-selective-expandable\">\n      <$list filter=\"\"\"[all[shadows+tiddlers]tag<__tag__>!has[draft.of]$sort$] -[<__tag__>] -[subfilter<__exclude__>]\"\"\">\n        <$list filter=\"[all[current]toc-link[no]]\" variable=\"ignore\" emptyMessage=<<toc-selective-expandable-empty-message>> >\n          <$macrocall $name=\"toc-unlinked-selective-expandable-body\" tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<excluded>> path=<<path>>/>\n        </$list>\n      </$list>\n    </ol>\n  </$set>\n</$let>\n\\end\n\n\\define toc-tabbed-external-nav(tag,sort:\"\",selectedTiddler:\"$:/temp/toc/selectedTiddler\",unselectedText,missingText,template:\"\",exclude)\n\\whitespace trim\n<$let __tag__={{{ [<__tag__>is[blank]then<currentTiddler>else<__tag__>] }}}>\n  <$tiddler tiddler={{{ [<__selectedTiddler__>get[text]] }}}>\n    <div class=\"tc-tabbed-table-of-contents\">\n      <$linkcatcher to=<<__selectedTiddler__>>>\n        <div class=\"tc-table-of-contents\">\n          <$macrocall $name=\"toc-selective-expandable\" tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=\"[all[current]] -[<__selectedTiddler__>get[text]]\" exclude=<<__exclude__>>/>\n        </div>\n      </$linkcatcher>\n      <div class=\"tc-tabbed-table-of-contents-content\">\n        <$reveal stateTitle=<<__selectedTiddler__>> type=\"nomatch\" text=\"\">\n          <$transclude mode=\"block\" tiddler=<<__template__>>>\n            <h1><<toc-caption>></h1>\n            <$transclude mode=\"block\">$missingText$</$transclude>\n          </$transclude>\n        </$reveal>\n        <$reveal stateTitle=<<__selectedTiddler__>> type=\"match\" text=\"\">\n          $unselectedText$\n        </$reveal>\n      </div>\n    </div>\n  </$tiddler>\n</$let>\n\\end\n\n\\define toc-tabbed-internal-nav(tag,sort:\"\",selectedTiddler:\"$:/temp/toc/selectedTiddler\",unselectedText,missingText,template:\"\",exclude)\n\\whitespace trim\n<$let __tag__={{{ [<__tag__>is[blank]then<currentTiddler>else<__tag__>] }}}>\n  <$linkcatcher to=<<__selectedTiddler__>>>\n    <$macrocall $name=\"toc-tabbed-external-nav\" tag=<<__tag__>> sort=<<__sort__>> selectedTiddler=<<__selectedTiddler__>> unselectedText=<<__unselectedText__>> missingText=<<__missingText__>> template=<<__template__>> exclude=<<__exclude__>> />\n  </$linkcatcher>\n</$let>\n\\end\n"},"$:/core/macros/translink":{"title":"$:/core/macros/translink","tags":"$:/tags/Macro","text":"\\define translink(title,mode:\"block\")\n\\whitespace trim\n<$list filter=\"[<__mode__>match[block]]\">\n<div class=\"tc-translink\">\n<div>\n<$link to=\"\"\"$title$\"\"\">\n<h1><$text text=\"\"\"$title$\"\"\"/></h1>\n</$link>\n<$transclude tiddler=\"\"\"$title$\"\"\" mode=\"block\">\n<$set name=\"currentTiddler\" value=\"\"\"$title$\"\"\"><$transclude tiddler=\"$:/language/MissingTiddler/Hint\"/></$set>\n</$transclude>\n</div>\n</div>\n</$list>\n<$list filter=\"[<__mode__>match[inline]]\">\n<span class=\"tc-translink\">\n<$link to=\"\"\"$title$\"\"\">\n<$text text=\"\"\"$title$\"\"\"/>\n</$link>\n&#32;(<$transclude tiddler=\"\"\"$title$\"\"\" mode=\"inline\">\n<$set name=\"currentTiddler\" value=\"\"\"$title$\"\"\"><$transclude tiddler=\"$:/language/MissingTiddler/Hint\"/></$set>\n</$transclude>)\n</span>\n</$list>\n\\end\n"},"$:/core/macros/tree":{"title":"$:/core/macros/tree","tags":"$:/tags/Macro","text":"\\define leaf-link(full-title,chunk,separator: \"/\")\n<$link to=<<__full-title__>>><$text text=<<__chunk__>>/></$link>\n\\end\n\n\\define leaf-node(prefix,chunk)\n\\whitespace trim\n<li>\n<$list filter=\"[<__prefix__>addsuffix<__chunk__>is[shadow]] [<__prefix__>addsuffix<__chunk__>is[tiddler]]\" variable=\"full-title\">\n<$list filter=\"[<full-title>removeprefix<__prefix__>]\" variable=\"chunk\">\n<span>{{$:/core/images/file}}</span>&#32;<$macrocall $name=\"leaf-link\" full-title=<<full-title>> chunk=<<chunk>>/>\n</$list>\n</$list>\n</li>\n\\end\n\n\\define branch-node(prefix,chunk,separator: \"/\")\n\\whitespace trim\n<li>\n<$set name=\"reveal-state\" value={{{ [[$:/state/tree/]addsuffix<__prefix__>addsuffix<__chunk__>] }}}>\n<$reveal type=\"nomatch\" stateTitle=<<reveal-state>> text=\"show\">\n<$button setTitle=<<reveal-state>> setTo=\"show\" class=\"tc-btn-invisible\">\n{{$:/core/images/folder}}&#32;<$text text=<<__chunk__>>/>\n</$button>\n</$reveal>\n<$reveal type=\"match\" stateTitle=<<reveal-state>> text=\"show\">\n<$button setTitle=<<reveal-state>> setTo=\"hide\" class=\"tc-btn-invisible\">\n{{$:/core/images/folder}}&#32;<$text text=<<__chunk__>>/>\n</$button>\n</$reveal>\n&#32;\n<span>(<$count filter=\"[all[shadows+tiddlers]removeprefix<__prefix__>removeprefix<__chunk__>] -[<__prefix__>addsuffix<__chunk__>]\"/>)</span>\n<$reveal type=\"match\" stateTitle=<<reveal-state>> text=\"show\">\n<$macrocall $name=\"tree-node\" prefix={{{ [<__prefix__>addsuffix<__chunk__>] }}} separator=<<__separator__>>/>\n</$reveal>\n</$set>\n</li>\n\\end\n\n\\define tree-node(prefix,separator: \"/\")\n\\whitespace trim\n<ol>\n<$list filter=\"[all[shadows+tiddlers]removeprefix<__prefix__>splitbefore<__separator__>sort[]!suffix<__separator__>]\" variable=\"chunk\">\n<$macrocall $name=\"leaf-node\" prefix=<<__prefix__>> chunk=<<chunk>> separator=<<__separator__>>/>\n</$list>\n<$list filter=\"[all[shadows+tiddlers]removeprefix<__prefix__>splitbefore<__separator__>sort[]suffix<__separator__>]\" variable=\"chunk\">\n<$macrocall $name=\"branch-node\" prefix=<<__prefix__>> chunk=<<chunk>> separator=<<__separator__>>/>\n</$list>\n</ol>\n\\end\n\n\\define tree(prefix: \"$:/\",separator: \"/\")\n\\whitespace trim\n<div class=\"tc-tree\">\n<span><$text text=<<__prefix__>>/></span>\n<div>\n<$macrocall $name=\"tree-node\" prefix=<<__prefix__>> separator=<<__separator__>>/>\n</div>\n</div>\n\\end\n"},"$:/core/macros/utils":{"title":"$:/core/macros/utils","text":"\\define colour(colour)\n$colour$\n\\end\n"},"$:/snippets/minifocusswitcher":{"title":"$:/snippets/minifocusswitcher","text":"\\whitespace trim\n<$select tiddler=\"$:/config/AutoFocus\">\n<$list filter=\"title tags text type fields\">\n<option value=<<currentTiddler>>><<currentTiddler>></option>\n</$list>\n</$select>\n"},"$:/snippets/minilanguageswitcher":{"title":"$:/snippets/minilanguageswitcher","text":"\\whitespace trim\n<$select tiddler=\"$:/language\">\n<$list filter=\"[[$:/languages/en-GB]] [plugin-type[language]sort[title]]\">\n<option value=<<currentTiddler>>><$view field=\"description\"><$view field=\"name\"><$view field=\"title\"/></$view></$view></option>\n</$list>\n</$select>"},"$:/snippets/minithemeswitcher":{"title":"$:/snippets/minithemeswitcher","text":"\\define lingo-base() $:/language/ControlPanel/Theme/\n\\whitespace trim\n<<lingo Prompt>>&#32;<$select tiddler=\"$:/theme\">\n<$list filter=\"[plugin-type[theme]sort[title]]\">\n<option value=<<currentTiddler>>><$view field=\"name\"><$view field=\"title\"/></$view></option>\n</$list>\n</$select>"},"$:/snippets/modules":{"title":"$:/snippets/modules","text":"\\define describeModuleType(type)\n{{$:/language/Docs/ModuleTypes/$type$}}\n\\end\n\\whitespace trim\n<$list filter=\"[moduletypes[]]\">\n\n!! <$macrocall $name=\"currentTiddler\" $type=\"text/plain\" $output=\"text/plain\"/>\n\n<$macrocall $name=\"describeModuleType\" type=<<currentTiddler>>/>\n\n<ul><$list filter=\"[all[current]modules[]]\"><li><$link><<currentTiddler>></$link>\n</li>\n</$list>\n</ul>\n</$list>\n"},"$:/palette":{"title":"$:/palette","text":"$:/palettes/Vanilla"},"$:/snippets/paletteeditor":{"title":"$:/snippets/paletteeditor","text":"<$transclude tiddler=\"$:/PaletteManager\"/>\n"},"$:/snippets/palettepreview":{"title":"$:/snippets/palettepreview","text":"\\whitespace trim\n<$set name=\"currentTiddler\" value={{$:/palette}}>\n{{||$:/snippets/currpalettepreview}}\n</$set>\n"},"$:/snippets/paletteswitcher":{"title":"$:/snippets/paletteswitcher","text":"\\whitespace trim\n<$linkcatcher to=\"$:/palette\">\n<div class=\"tc-chooser\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Palette]sort[name]]\">\n<$set name=\"cls\" filter=\"[all[current]prefix{$:/palette}]\" value=\"tc-chooser-item tc-chosen\" emptyValue=\"tc-chooser-item\">\n<div class=<<cls>>>\n<$link to={{!!title}}>\n''<$view field=\"name\" format=\"text\"/>''\n&#32;-&#32;\n<$view field=\"description\" format=\"text\"/>\n{{||$:/snippets/currpalettepreview}}\n</$link>\n</div>\n</$set>\n</$list>\n</div>\n</$linkcatcher>\n"},"$:/snippets/peek-stylesheets":{"title":"$:/snippets/peek-stylesheets","text":"\\define expandable-stylesheets-list()\n\\whitespace trim\n<ol>\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Stylesheet]!has[draft.of]]\">\n<$vars state=<<qualify \"$:/state/peek-stylesheets/open/\">>>\n<$set name=\"state\" value={{{ [<state>addsuffix<currentTiddler>] }}}>\n<li>\n<$reveal type=\"match\" state=<<state>> text=\"yes\" tag=\"span\">\n<$button set=<<state>> setTo=\"no\" class=\"tc-btn-invisible\">\n{{$:/core/images/down-arrow}}\n</$button>\n</$reveal>\n<$reveal type=\"nomatch\" state=<<state>> text=\"yes\" tag=\"span\">\n<$button set=<<state>> setTo=\"yes\" class=\"tc-btn-invisible\">\n{{$:/core/images/right-arrow}}\n</$button>\n</$reveal>\n<$link>\n<$view field=\"title\"/>\n</$link>\n<$reveal type=\"match\" state=<<state>> text=\"yes\" tag=\"div\">\n<$set name=\"source\" tiddler=<<currentTiddler>>>\n<$wikify name=\"styles\" text=<<source>>>\n<$codeblock code=<<styles>> language=\"css\"/>\n</$wikify>\n</$set>\n</$reveal>\n</li>\n</$set>\n</$vars>\n</$list>\n</ol>\n\\end\n\n\\define stylesheets-list()\n\\whitespace trim\n<ol>\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Stylesheet]!has[draft.of]]\">\n<li>\n<$link>\n<$view field=\"title\"/>\n</$link>\n<$set name=\"source\" tiddler=<<currentTiddler>>>\n<$wikify name=\"styles\" text=<<source>>>\n<pre>\n<code>\n<$text text=<<styles>>/>\n</code>\n</pre>\n</$wikify>\n</$set>\n</li>\n</$list>\n</ol>\n\\end\n\\whitespace trim\n\n<$vars modeState=<<qualify \"$:/state/peek-stylesheets/mode/\">>>\n\n<$reveal type=\"nomatch\" state=<<modeState>> text=\"expanded\" tag=\"div\">\n<$button set=<<modeState>> setTo=\"expanded\" class=\"tc-btn-invisible\">{{$:/core/images/chevron-right}} {{$:/language/ControlPanel/Stylesheets/Expand/Caption}}</$button>\n</$reveal>\n<$reveal type=\"match\" state=<<modeState>> text=\"expanded\" tag=\"div\">\n<$button set=<<modeState>> setTo=\"restored\" class=\"tc-btn-invisible\">{{$:/core/images/chevron-down}} {{$:/language/ControlPanel/Stylesheets/Restore/Caption}}</$button>\n</$reveal>\n\n<$reveal type=\"nomatch\" state=<<modeState>> text=\"expanded\" tag=\"div\">\n<<expandable-stylesheets-list>>\n</$reveal>\n<$reveal type=\"match\" state=<<modeState>> text=\"expanded\" tag=\"div\">\n<<stylesheets-list>>\n</$reveal>\n\n</$vars>\n"},"$:/temp/search":{"title":"$:/temp/search","text":""},"$:/tags/AdvancedSearch":{"title":"$:/tags/AdvancedSearch","list":"[[$:/core/ui/AdvancedSearch/Standard]] [[$:/core/ui/AdvancedSearch/System]] [[$:/core/ui/AdvancedSearch/Shadows]] [[$:/core/ui/AdvancedSearch/Filter]]"},"$:/tags/AdvancedSearch/FilterButton":{"title":"$:/tags/AdvancedSearch/FilterButton","list":"$:/core/ui/AdvancedSearch/Filter/FilterButtons/dropdown $:/core/ui/AdvancedSearch/Filter/FilterButtons/clear $:/core/ui/AdvancedSearch/Filter/FilterButtons/export $:/core/ui/AdvancedSearch/Filter/FilterButtons/delete"},"$:/tags/ControlPanel":{"title":"$:/tags/ControlPanel","list":"$:/core/ui/ControlPanel/Info $:/core/ui/ControlPanel/Appearance $:/core/ui/ControlPanel/Settings $:/core/ui/ControlPanel/Saving $:/core/ui/ControlPanel/Plugins $:/core/ui/ControlPanel/Tools $:/core/ui/ControlPanel/Internals"},"$:/tags/ControlPanel/Info":{"title":"$:/tags/ControlPanel/Info","list":"$:/core/ui/ControlPanel/Basics $:/core/ui/ControlPanel/Advanced"},"$:/tags/ControlPanel/Plugins":{"title":"$:/tags/ControlPanel/Plugins","list":"$:/core/ui/ControlPanel/Plugins/Installed/Plugins $:/core/ui/ControlPanel/Plugins/Installed/Themes $:/core/ui/ControlPanel/Plugins/Installed/Languages"},"$:/tags/EditTemplate":{"title":"$:/tags/EditTemplate","list":"[[$:/core/ui/EditTemplate/controls]] [[$:/core/ui/EditTemplate/title]] [[$:/core/ui/EditTemplate/tags]] [[$:/core/ui/EditTemplate/shadow]] [[$:/core/ui/ViewTemplate/classic]] [[$:/core/ui/EditTemplate/body]] [[$:/core/ui/EditTemplate/type]] [[$:/core/ui/EditTemplate/fields]]"},"$:/tags/EditTemplateBodyFilter":{"title":"$:/tags/EditTemplateBodyFilter","list":"$:/config/EditTemplateBodyFilters/canonical-uri $:/config/EditTemplateBodyFilters/default"},"$:/tags/EditToolbar":{"title":"$:/tags/EditToolbar","list":"[[$:/core/ui/Buttons/delete]] [[$:/core/ui/Buttons/cancel]] [[$:/core/ui/Buttons/save]]"},"$:/tags/EditorToolbar":{"title":"$:/tags/EditorToolbar","list":"$:/core/ui/EditorToolbar/paint $:/core/ui/EditorToolbar/opacity $:/core/ui/EditorToolbar/line-width $:/core/ui/EditorToolbar/rotate-left $:/core/ui/EditorToolbar/clear $:/core/ui/EditorToolbar/bold $:/core/ui/EditorToolbar/italic $:/core/ui/EditorToolbar/strikethrough $:/core/ui/EditorToolbar/underline $:/core/ui/EditorToolbar/superscript $:/core/ui/EditorToolbar/subscript $:/core/ui/EditorToolbar/mono-line $:/core/ui/EditorToolbar/mono-block $:/core/ui/EditorToolbar/quote $:/core/ui/EditorToolbar/list-bullet $:/core/ui/EditorToolbar/list-number $:/core/ui/EditorToolbar/heading-1 $:/core/ui/EditorToolbar/heading-2 $:/core/ui/EditorToolbar/heading-3 $:/core/ui/EditorToolbar/heading-4 $:/core/ui/EditorToolbar/heading-5 $:/core/ui/EditorToolbar/heading-6 $:/core/ui/EditorToolbar/link $:/core/ui/EditorToolbar/excise $:/core/ui/EditorToolbar/picture $:/core/ui/EditorToolbar/stamp $:/core/ui/EditorToolbar/size $:/core/ui/EditorToolbar/editor-height $:/core/ui/EditorToolbar/more $:/core/ui/EditorToolbar/preview $:/core/ui/EditorToolbar/preview-type"},"$:/tags/Manager/ItemMain":{"title":"$:/tags/Manager/ItemMain","list":"$:/Manager/ItemMain/WikifiedText $:/Manager/ItemMain/RawText $:/Manager/ItemMain/Fields"},"$:/tags/Manager/ItemSidebar":{"title":"$:/tags/Manager/ItemSidebar","list":"$:/Manager/ItemSidebar/Tags $:/Manager/ItemSidebar/Colour $:/Manager/ItemSidebar/Icon $:/Manager/ItemSidebar/Tools"},"$:/tags/MoreSideBar":{"title":"$:/tags/MoreSideBar","list":"[[$:/core/ui/MoreSideBar/All]] [[$:/core/ui/MoreSideBar/Recent]] [[$:/core/ui/MoreSideBar/Tags]] [[$:/core/ui/MoreSideBar/Missing]] [[$:/core/ui/MoreSideBar/Drafts]] [[$:/core/ui/MoreSideBar/Orphans]] [[$:/core/ui/MoreSideBar/Types]] [[$:/core/ui/MoreSideBar/System]] [[$:/core/ui/MoreSideBar/Shadows]] [[$:/core/ui/MoreSideBar/Explorer]] [[$:/core/ui/MoreSideBar/Plugins]]","text":""},"$:/tags/PageControls":{"title":"$:/tags/PageControls","list":"[[$:/core/ui/Buttons/home]] [[$:/core/ui/Buttons/close-all]] [[$:/core/ui/Buttons/fold-all]] [[$:/core/ui/Buttons/unfold-all]] [[$:/core/ui/Buttons/permaview]] [[$:/core/ui/Buttons/new-tiddler]] [[$:/core/ui/Buttons/new-journal]] [[$:/core/ui/Buttons/new-image]] [[$:/core/ui/Buttons/import]] [[$:/core/ui/Buttons/export-page]] [[$:/core/ui/Buttons/control-panel]] [[$:/core/ui/Buttons/advanced-search]] [[$:/core/ui/Buttons/manager]] [[$:/core/ui/Buttons/tag-manager]] [[$:/core/ui/Buttons/language]] [[$:/core/ui/Buttons/palette]] [[$:/core/ui/Buttons/theme]] [[$:/core/ui/Buttons/layout]] [[$:/core/ui/Buttons/storyview]] [[$:/core/ui/Buttons/encryption]] [[$:/core/ui/Buttons/timestamp]] [[$:/core/ui/Buttons/full-screen]] [[$:/core/ui/Buttons/print]] [[$:/core/ui/Buttons/save-wiki]] [[$:/core/ui/Buttons/refresh]] [[$:/core/ui/Buttons/network-activity]] [[$:/core/ui/Buttons/more-page-actions]]"},"$:/tags/PageTemplate":{"title":"$:/tags/PageTemplate","list":"[[$:/core/ui/PageTemplate/topleftbar]] [[$:/core/ui/PageTemplate/toprightbar]] [[$:/core/ui/PageTemplate/sidebar]] [[$:/core/ui/PageTemplate/story]] [[$:/core/ui/PageTemplate/alerts]]","text":""},"$:/tags/PluginLibrary":{"title":"$:/tags/PluginLibrary","list":"$:/config/OfficialPluginLibrary"},"$:/tags/SideBar":{"title":"$:/tags/SideBar","list":"[[$:/core/ui/SideBar/Open]] [[$:/core/ui/SideBar/Recent]] [[$:/core/ui/SideBar/Tools]] [[$:/core/ui/SideBar/More]]","text":""},"$:/tags/SideBarSegment":{"title":"$:/tags/SideBarSegment","list":"[[$:/core/ui/SideBarSegments/site-title]] [[$:/core/ui/SideBarSegments/site-subtitle]] [[$:/core/ui/SideBarSegments/page-controls]] [[$:/core/ui/SideBarSegments/search]] [[$:/core/ui/SideBarSegments/tabs]]"},"$:/tags/StoryTiddlerTemplateFilter":{"title":"$:/tags/StoryTiddlerTemplateFilter","list":"$:/config/StoryTiddlerTemplateFilters/draft $:/config/StoryTiddlerTemplateFilters/default"},"$:/tags/TestCase/Actions":{"title":"$:/tags/TestCase/Actions","list":""},"$:/tags/TextEditor/Snippet":{"title":"$:/tags/TextEditor/Snippet","list":"$:/language/Snippets/ProcedureDefinition $:/language/Snippets/FunctionDefinition $:/language/Snippets/ListByTag $:/language/Snippets/Table4x3 $:/language/Snippets/TableOfContents $:/language/Snippets/MacroDefinition"},"$:/tags/TiddlerColourFilter":{"title":"$:/tags/TiddlerColourFilter","list":"$:/config/TiddlerColourFilters/color-field $:/config/TiddlerColourFilters/default","text":""},"$:/tags/TiddlerIconFilter":{"title":"$:/tags/TiddlerIconFilter","list":"$:/config/TiddlerIconFilters/icon-field $:/config/TiddlerIconFilters/default","text":""},"$:/tags/TiddlerInfo":{"title":"$:/tags/TiddlerInfo","list":"[[$:/core/ui/TiddlerInfo/Tools]] [[$:/core/ui/TiddlerInfo/References]] [[$:/core/ui/TiddlerInfo/Tagging]] [[$:/core/ui/TiddlerInfo/List]] [[$:/core/ui/TiddlerInfo/Listed]] [[$:/core/ui/TiddlerInfo/Fields]]","text":""},"$:/tags/TiddlerInfo/Advanced":{"title":"$:/tags/TiddlerInfo/Advanced","list":"[[$:/core/ui/TiddlerInfo/Advanced/ShadowInfo]] [[$:/core/ui/TiddlerInfo/Advanced/PluginInfo]]"},"$:/tags/ViewTemplate":{"title":"$:/tags/ViewTemplate","list":"[[$:/core/ui/ViewTemplate/title]] [[$:/core/ui/ViewTemplate/unfold]] [[$:/core/ui/ViewTemplate/subtitle]] [[$:/core/ui/ViewTemplate/tags]] [[$:/core/ui/ViewTemplate/classic]] [[$:/core/ui/ViewTemplate/body]] [[$:/core/ui/ViewTemplate/lazy-loading]]"},"$:/tags/ViewTemplateBodyFilter":{"title":"$:/tags/ViewTemplateBodyFilter","list":"$:/config/ViewTemplateBodyFilters/testcase $:/config/ViewTemplateBodyFilters/hide-body $:/config/ViewTemplateBodyFilters/code-body $:/config/ViewTemplateBodyFilters/stylesheet $:/config/ViewTemplateBodyFilters/core-ui-advanced-search $:/config/ViewTemplateBodyFilters/core-ui-tags $:/config/ViewTemplateBodyFilters/import $:/config/ViewTemplateBodyFilters/plugin $:/config/ViewTemplateBodyFilters/system $:/config/ViewTemplateBodyFilters/default"},"$:/tags/ViewTemplate/Subtitle":{"title":"$:/tags/ViewTemplate/Subtitle","list":"$:/core/ui/ViewTemplate/subtitle/modifier $:/core/ui/ViewTemplate/subtitle/modified"},"$:/tags/ViewTemplateTitleFilter":{"title":"$:/tags/ViewTemplateTitleFilter","list":"$:/config/ViewTemplateTitleFilters/system $:/config/ViewTemplateTitleFilters/default","text":""},"$:/tags/ViewToolbar":{"title":"$:/tags/ViewToolbar","list":"[[$:/core/ui/Buttons/more-tiddler-actions]] [[$:/core/ui/Buttons/info]] [[$:/core/ui/Buttons/new-here]] [[$:/core/ui/Buttons/new-journal-here]] [[$:/core/ui/Buttons/clone]] [[$:/core/ui/Buttons/export-tiddler]] [[$:/core/ui/Buttons/edit]] [[$:/core/ui/Buttons/delete]] [[$:/core/ui/Buttons/permalink]] [[$:/core/ui/Buttons/permaview]] [[$:/core/ui/Buttons/open-window]] [[$:/core/ui/Buttons/close-others]] [[$:/core/ui/Buttons/close]] [[$:/core/ui/Buttons/fold-others]] [[$:/core/ui/Buttons/fold]]"},"$:/snippets/themeswitcher":{"title":"$:/snippets/themeswitcher","text":"\\whitespace trim\n<$linkcatcher to=\"$:/theme\">\n<div class=\"tc-chooser\">\n<$list filter=\"[plugin-type[theme]sort[title]]\">\n<$set name=\"cls\" filter=\"[all[current]field:title{$:/theme}] [[$:/theme]!has[text]addsuffix[s/tiddlywiki/vanilla]field:title<currentTiddler>] +[limit[1]]\" value=\"tc-chooser-item tc-chosen\" emptyValue=\"tc-chooser-item\">\n<div class=<<cls>>><$link to={{!!title}}>\n''<$view field=\"name\" format=\"text\"/>''\n&#32;\n<$view field=\"description\" format=\"text\"/>\n</$link>\n</div>\n</$set>\n</$list>\n</div>\n</$linkcatcher>"},"$:/core/wiki/title":{"title":"$:/core/wiki/title","text":"\\whitespace trim\n{{$:/SiteTitle}}\n<$list filter=\"[{$:/SiteSubtitle}trim[]minlength[1]]\" variable=\"ignore\">\n&#32;---&#32;{{$:/SiteSubtitle}}\n</$list>"},"$:/view":{"title":"$:/view","text":"classic"},"$:/snippets/viewswitcher":{"title":"$:/snippets/viewswitcher","text":"\\define icon()\n$:/core/images/storyview-$(storyview)$\n\\end\n\\whitespace trim\n<$linkcatcher to=\"$:/view\">\n<div class=\"tc-chooser tc-viewswitcher\">\n<$list filter=\"[storyviews[]]\" variable=\"storyview\">\n<$set name=\"cls\" filter=\"[<storyview>prefix{$:/view}]\" value=\"tc-chooser-item tc-chosen\" emptyValue=\"tc-chooser-item\"><div class=<<cls>>>\n<$button tag=\"a\" class=\"tc-tiddlylink tc-btn-invisible\" to=<<storyview>>><$transclude tiddler=<<icon>>/><$text text=<<storyview>>/></$button>\n</div>\n</$set>\n</$list>\n</div>\n</$linkcatcher>\n"}}}
no
{"tiddlers":{"$:/config/SyncFilter":{"title":"$:/config/SyncFilter","text":"[is[tiddler]] -[[$:/StoryList]] -[[$:/HistoryList]] -[[$:/Import]] -[[$:/isEncrypted]] -[[$:/library/sjcl.js]] -[[$:/core]] -[[$:/plugins/federatial/xememex]] -[[$:/plugins/federatial/xememex/raw-markup]] -[[$:/plugins/tiddlywiki/tw2parser]] -[[$:/themes/tiddlywiki/snowwhite]] -[[$:/themes/tiddlywiki/vanilla]] -[prefix[$:/boot/]] -[prefix[$:/plugins/federatial/xememex/config/]] -[prefix[$:/status/]] -[prefix[$:/state/]] -[prefix[$:/temp/]]"},"$:/plugins/federatial/xememex/bag-operator.js":{"title":"$:/plugins/federatial/xememex/bag-operator.js","text":"/*\\\ntitle: $:/plugins/federatial/xememex/bag-operator.js\ntype: application/javascript\nmodule-type: filteroperator\n\nSelects those tiddlers that are stored in the bag named in the operand\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.frombag = function(source,operator,options) {\n\tvar data,title,results = [];\n\tif(operator.operand){\n\t\tsource(function(tiddler,title) {\n\t\t\ttitle = tiddler ? tiddler.fields.title : title;\n\t\t\tvar bagName = options.wiki.extractTiddlerDataItem(\"$:/state/federatial/xememex/tiddlers/bag\",title,\"\");\n\t\t\tif(bagName === operator.operand) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n","type":"application/javascript","module-type":"filteroperator"},"$:/plugins/federatial/xememex/icon":{"title":"$:/plugins/federatial/xememex/icon","tags":"$:/tags/Image","text":"<svg class=\"tc-image-xememex-plugin tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <path d=\"M79.7435765,9.49213757 L64.0237949,36.9372695 L48.0705582,9.08454876 L63.5596004,-1.13686838e-13 L79.7435765,9.49213757 Z M90.764123,15.9558486 L118.119201,32 L118.119201,96 L103.155698,104.776312 L71.5125369,49.0659545 L90.764123,15.9558486 Z M91.9243286,111.363674 L63.5596004,128 L35.7919091,111.713845 L64.0152972,61.3155681 L91.9243286,111.363674 Z M24.6598969,105.184758 L9,96 L9,32 L36.9468534,15.6087636 L56.5307941,49.0734527 L24.6598969,105.184758 Z\"></path>\n</svg>"},"$:/plugins/tiddlywiki/tiddlyweb/icon/cloud":{"title":"$:/plugins/tiddlywiki/tiddlyweb/icon/cloud","tags":"$:/tags/Image","text":"<svg class=\"tc-image-cloud tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\"><g><path d=\"M24 103C10.745 103 0 92.255 0 79c0-9.697 5.75-18.05 14.027-21.836A24.787 24.787 0 0114 56c0-13.255 10.745-24 24-24 1.373 0 2.718.115 4.028.337C48.628 24.2 58.707 19 70 19c19.882 0 36 16.118 36 36v.082c12.319 1.016 22 11.336 22 23.918 0 12.239-9.16 22.337-20.999 23.814L107 103H24z\"/><path class=\"tc-image-cloud-idle\" d=\"M57.929 84.698a6 6 0 01-8.485 0L35.302 70.556a6 6 0 118.485-8.485l9.9 9.9L81.97 43.686a6 6 0 018.485 8.486L57.929 84.698z\"/><path class=\"tc-image-cloud-progress tc-animate-rotate-slow\" d=\"M44.8 40a3.6 3.6 0 100 7.2h2.06A23.922 23.922 0 0040 64c0 13.122 10.531 23.785 23.603 23.997L64 88l.001-7.2c-9.171 0-16.626-7.348-16.798-16.477L47.2 64c0-5.165 2.331-9.786 5.999-12.868L53.2 55.6a3.6 3.6 0 107.2 0v-12a3.6 3.6 0 00-3.6-3.6h-12zM64 40v7.2c9.278 0 16.8 7.522 16.8 16.8 0 5.166-2.332 9.787-6 12.869V72.4a3.6 3.6 0 10-7.2 0v12a3.6 3.6 0 003.6 3.6h12a3.6 3.6 0 100-7.2l-2.062.001A23.922 23.922 0 0088 64c0-13.255-10.745-24-24-24z\"/></g></svg>"},"$:/plugins/tiddlywiki/tiddlyweb/save/offline":{"title":"$:/plugins/tiddlywiki/tiddlyweb/save/offline","text":"\\import [subfilter{$:/core/config/GlobalImportFilter}]\n\\define saveTiddlerFilter()\n[is[tiddler]] -[[$:/boot/boot.css]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] -[[$:/plugins/tiddlywiki/filesystem]] -[[$:/plugins/tiddlywiki/tiddlyweb]] -[prefix[$:/temp/]] +[sort[title]] $(publishFilter)$\n\\end\n{{$:/core/templates/tiddlywiki5.html}}\n"},"$:/core/ui/Buttons/save-wiki":{"title":"$:/core/ui/Buttons/save-wiki","tags":"$:/tags/PageControls","caption":"{{$:/plugins/tiddlywiki/tiddlyweb/icon/cloud}} Server status","description":"Status of synchronisation with server","text":"\\whitespace trim\n\\define config-title()\n$:/config/PageControlButtons/Visibility/$(listItem)$\n\\end\n<$button popup=<<qualify \"$:/state/popup/save-wiki\">> tooltip=\"Status of synchronisation with server\" aria-label=\"Server status\" class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<span class=\"tc-dirty-indicator\">\n<%if [<tv-config-toolbar-icons>match[yes]] %>\n{{$:/plugins/tiddlywiki/tiddlyweb/icon/cloud}}\n<%endif%>\n<%if [<tv-config-toolbar-text>match[yes]] %>\n<span class=\"tc-btn-text\"><$text text=\"Server status\"/></span>\n<%endif%>\n</span>\n</$button>\n<$reveal state=<<qualify \"$:/state/popup/save-wiki\">> type=\"popup\" position=\"belowleft\" animate=\"yes\">\n<div class=\"tc-drop-down\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/SyncerDropdown]!has[draft.of]]\" variable=\"listItem\">\n<$transclude tiddler=<<listItem>>/>\n</$list>\n</div>\n</$reveal>\n"},"$:/config/SaveWikiButton/Template":{"title":"$:/config/SaveWikiButton/Template","text":"$:/plugins/federatial/xememex/save/offline"},"$:/plugins/tiddlywiki/tiddlyweb/styles":{"title":"$:/plugins/tiddlywiki/tiddlyweb/styles","tags":"[[$:/tags/Stylesheet]]","text":"\\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline macrocallblock\n\nbody.tc-dirty span.tc-dirty-indicator svg {\n\ttransition: fill 250ms ease-in-out;\n}\n\nbody .tc-image-cloud-idle {\n\tfill: <<colour background>>;\n\ttransition: opacity 250ms ease-in-out;\n\topacity: 1;\n\tdisplay: unset;\n}\n\nbody.tc-dirty .tc-image-cloud-idle {\n\topacity: 0;\n\tdisplay: none;\n}\n\nbody .tc-image-cloud-progress {\n\ttransition: opacity 250ms ease-in-out;\n\ttransform-origin: 50% 50%;\n\ttransform: rotate(359deg);\n\tanimation: animation-rotate-slow 2s infinite linear;\n\tfill: <<colour background>>;\n\tdisplay: none;\n\topacity: 0;\n}\n\nbody.tc-dirty .tc-image-cloud-progress {\n\topacity: 1;\n\tdisplay: unset;\n}\n\n@keyframes animation-rotate-slow {\n\tfrom {\n\t\ttransform: rotate(0deg);\n\t}\n\tto {\n\t\ttransform: scale(359deg);\n\t}\n}\n"},"$:/plugins/tiddlywiki/tiddlyweb/syncer-actions/copy-logs":{"title":"$:/plugins/tiddlywiki/tiddlyweb/syncer-actions/copy-logs","tags":"$:/tags/SyncerDropdown","text":"<$button message=\"tm-copy-syncer-logs-to-clipboard\" class=\"tc-btn-invisible\">\n{{$:/core/images/copy-clipboard}} Copy syncer logs to clipboard\n</$button>\n"},"$:/plugins/tiddlywiki/tiddlyweb/syncer-actions/login-status":{"title":"$:/plugins/tiddlywiki/tiddlyweb/syncer-actions/login-status","tags":"$:/tags/SyncerDropdown","text":"<$reveal state=\"$:/status/IsLoggedIn\" type=\"match\" text=\"yes\">\n<div class=\"tc-drop-down-info\">\nYou are logged in<$reveal state=\"$:/status/UserName\" type=\"nomatch\" text=\"\" default=\"\"> as <strong><$text text={{$:/status/UserName}}/></strong></$reveal><$reveal state=\"$:/status/IsReadOnly\" type=\"match\" text=\"yes\" default=\"no\"> (read-only)</$reveal>\n</div>\n<hr/>\n</$reveal>\n"},"$:/plugins/tiddlywiki/tiddlyweb/syncer-actions/login":{"title":"$:/plugins/tiddlywiki/tiddlyweb/syncer-actions/login","tags":"$:/tags/SyncerDropdown","text":"<$reveal state=\"$:/status/IsLoggedIn\" type=\"nomatch\" text=\"yes\">\n<$button message=\"tm-login\" class=\"tc-btn-invisible\">\n{{$:/core/images/unlocked-padlock}} Login\n</$button>\n</$reveal>\n"},"$:/plugins/tiddlywiki/tiddlyweb/syncer-actions/logout":{"title":"$:/plugins/tiddlywiki/tiddlyweb/syncer-actions/logout","tags":"$:/tags/SyncerDropdown","text":"<$reveal state=\"$:/status/IsLoggedIn\" type=\"match\" text=\"yes\">\n<$button message=\"tm-logout\" class=\"tc-btn-invisible\">\n{{$:/core/images/cancel-button}} Logout\n</$button>\n</$reveal>\n"},"$:/plugins/tiddlywiki/tiddlyweb/syncer-actions/refresh":{"title":"$:/plugins/tiddlywiki/tiddlyweb/syncer-actions/refresh","tags":"$:/tags/SyncerDropdown","text":"<$reveal state=\"$:/status/IsLoggedIn\" type=\"match\" text=\"yes\">\n<$button tooltip=\"Get latest changes from the server\" aria-label=\"Refresh from server\" class=\"tc-btn-invisible\">\n<$action-sendmessage $message=\"tm-server-refresh\"/>\n{{$:/core/images/refresh-button}}<span class=\"tc-btn-text\"><$text text=\"Get latest changes from the server\"/></span>\n</$button>\n</$reveal>\n"},"$:/plugins/tiddlywiki/tiddlyweb/syncer-actions/save-snapshot":{"title":"$:/plugins/tiddlywiki/tiddlyweb/syncer-actions/save-snapshot","tags":"$:/tags/SyncerDropdown","text":"<$button class=\"tc-btn-invisible\">\n<$wikify name=\"site-title\" text={{$:/config/SaveWikiButton/Filename}}>\n<$action-sendmessage $message=\"tm-download-file\" $param={{$:/config/SaveWikiButton/Template}} filename=<<site-title>>/>\n</$wikify>\n{{$:/core/images/download-button}} Save snapshot for offline use\n</$button>\n"},"$:/tags/SyncerDropdown":{"title":"$:/tags/SyncerDropdown","list":"$:/plugins/tiddlywiki/tiddlyweb/syncer-actions/login-status $:/plugins/tiddlywiki/tiddlyweb/syncer-actions/login $:/plugins/tiddlywiki/tiddlyweb/syncer-actions/refresh $:/plugins/tiddlywiki/tiddlyweb/syncer-actions/logout $:/plugins/tiddlywiki/tiddlyweb/syncer-actions/save-snapshot $:/plugins/tiddlywiki/tiddlyweb/syncer-actions/copy-logs"},"$:/plugins/federatial/xememex/info-segment":{"title":"$:/plugins/federatial/xememex/info-segment","tags":"$:/tags/TiddlerInfoSegment","text":"<$reveal type=\"nomatch\" state=<<folded-state>> text=\"hide\" tag=\"div\" retain=\"yes\" animate=\"yes\">\n<div class=\"tc-xememex-tiddler-info tc-subtitle\">\nBag: <$view tiddler=\"$:/state/federatial/xememex/tiddlers/bag\" index=<<currentTiddler>>>(none)</$view>\n</div>\n</$reveal>\n"},"$:/plugins/federatial/xememex/login":{"title":"$:/plugins/federatial/xememex/login","text":"<$reveal state=\"$:/status/IsLoggedIn\" type=\"nomatch\" text=\"yes\">\nLog in to Xememex: <$button message=\"tm-login\">Login</$button>\n</$reveal>\n\n<$reveal state=\"$:/status/IsLoggedIn\" type=\"match\" text=\"yes\">\nLogged in as {{$:/status/UserName}} <$button message=\"tm-logout\">Logout</$button> <$button message=\"tm-server-refresh\">Fetch updates from server</$button>\n</$reveal>"},"$:/core/modules/widgets/on-render.js":{"title":"$:/core/modules/widgets/on-render.js","text":"/*\\\ntitle: $:/core/modules/widgets/on-render.js\ntype: application/javascript\nmodule-type: widget\n\nOnRender variable widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar OnRenderWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nOnRenderWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nOnRenderWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n\tif(this.isWithinVisibleDocument()) {\n\t\twindow.setTimeout(this.handleTimeoutEvent.bind(this),0);\n\t}\n};\n\nOnRenderWidget.prototype.isWithinVisibleDocument = function() {\n\treturn $tw.browser && !this.document.isTiddlyWikiFakeDom && $tw.utils.domContains(this.document,this.parentDomNode);\n};\n\nOnRenderWidget.prototype.handleTimeoutEvent = function() {\n\tif(this.isWithinVisibleDocument()) {\n\t\t$tw.taskDaemon.invoke({\n\t\t\twidget: this,\n\t\t\tname: this.getAttribute(\"name\"),\n\t\t\tactions: this.getAttribute(\"actions\"),\n\t\t\tminimumInterval: parseInt(this.getAttribute(\"minimumInterval\"),10) || 0\n\t\t});\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nOnRenderWidget.prototype.execute = function() {\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nOnRenderWidget.prototype.refresh = function(changedTiddlers) {\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports[\"on-render\"] = OnRenderWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/DefaultTiddlers":{"title":"$:/DefaultTiddlers","text":"[list[DefaultTiddlers!!text]]"},"$:/core/ui/PageTemplate/drafts":{"title":"$:/core/ui/PageTemplate/drafts","text":"This tiddler is overridden by Xememex to remove the red drafts indicator"},"$:/language/PluginReloadWarning":{"title":"$:/language/PluginReloadWarning","text":"Please refresh this page {{$:/core/ui/Buttons/refresh}} to allow changes to ~JavaScript plugins to take effect\n\n"},"$:/SiteSubtitle":{"title":"$:/SiteSubtitle","text":"<$transclude tiddler=\"SiteSubtitle\">A place for thinking</$transclude>"},"$:/SiteTitle":{"title":"$:/SiteTitle","text":"<$transclude tiddler=\"SiteTitle\">Xememex</$transclude>"},"$:/config/SyncPollingInterval":{"title":"$:/config/SyncPollingInterval","text":"30000"},"$:/core/ui/AboveStory/tw2-plugin-check":{"title":"$:/core/ui/AboveStory/tw2-plugin-check","text":"(Disabled TW2 plugin check)\n"},"$:/plugins/federatial/xememex/raw-markup-boot.js":{"title":"$:/plugins/federatial/xememex/raw-markup-boot.js","text":"/*\\\ntitle: $:/plugins/federatial/xememex/raw-markup-boot.js\ntype: application/javascript\nmodule-type: library\n\nBoot code that is transcluded by a rawmarkup startup tiddler\n\n\\*/\n\n(function() {\n\nvar MAP_BAG_TITLE = \"$:/state/federatial/xememex/tiddlers/bag\",\n\tMAP_ETAG_TITLE = \"$:/state/federatial/xememex/tiddlers/etag\",\n\tCONFIG_RECIPE_TITLE = \"$:/plugins/federatial/xememex/config/recipe\";\n\nif($xememex && $xememex.server && $xememex.server.addEventListener) {\n\t$xememex.server.addEventListener(\"login-status-change\",handleLoginStatusChange);\n}\n\nvar hasBooted = false;\n\nfunction handleLoginStatusChange(user) {\n\tvar requireLogin  = $xememex.config[\"require-login\"];\n\tif(user || (!requireLogin && $xememex.server.isAnonymousAccount())) {\n\t\t$xememex.server.removeEventListener(\"login-status-change\",handleLoginStatusChange);\n\t\t$xememex.pill.showDropdown();\n\t\t$xememex.pill.setProgress(1);\n\t\t$xememex.pill.showProgress();\n\t\t$xememex.pill.hideAuth();\n\t\tif(!hasBooted) {\n\t\t\tbootXememex();\n\t\t}\n\t} else {\n\t\tif(requireLogin) {\n\t\t\t$xememex.pill.showDropdown();\n\t\t} else {\n\t\t\tbootTiddlyWiki();\n\t\t}\n\t}\n}\n\nfunction bootXememex() {\n\thasBooted = true;\n\t// Get the tiddlers we need from within the HTML file\n\tvar tiddlerStoreMap = getTiddlerStoreMap(),\n\t\tbagMap = JSON.parse(getTiddlerText(tiddlerStoreMap[MAP_BAG_TITLE])),\n\t\tetagMap = JSON.parse(getTiddlerText(tiddlerStoreMap[MAP_ETAG_TITLE])),\n\t\trecipeName = getTiddlerText(tiddlerStoreMap[CONFIG_RECIPE_TITLE]),\n\t\tbagsToLoad = null,\n\t\ttiddlersToReload = null;\n\t\ttaskFunctions = {\n\t\t\t// Get the recipe details\n\t\t\tgetRecipeDetails: {\n\t\t\t\tprogressContribution: 1,\n\t\t\t\thandler: function(startProgress,lengthProgress,callback) {\n\t\t\t\t\t$xememex.server.jsonRequest({\n\t\t\t\t\t\turl: \"recipes/\" + fullyEncodeURIComponent(recipeName),\n\t\t\t\t\t\tprogress: function(lengthComputable,loaded,total) {\n\t\t\t\t\t\t\tsetProgressIndicator(startProgress,lengthProgress,lengthComputable,loaded,total);\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcallback: function(err,recipeInfo) {\n\t\t\t\t\t\t\tif(err) {\n\t\t\t\t\t\t\t\treturn callback(err);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// Get the details of the bags to be loaded\n\t\t\t\t\t\t\tbagsToLoad = recipeInfo.recipe.map(function(recipeLine) {\n\t\t\t\t\t\t\t\treturn recipeLine[0];\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tcallback(null);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t},\n\t\t\t// Get the cached content of each bag\n\t\t\tgetCachedBags: {\n\t\t\t\tprogressContribution: 50,\n\t\t\t\thandler: function(startProgress,lengthProgress,callback) {\n\t\t\t\t\tasync.eachOfSeries(bagsToLoad,function(bagName,bagIndex,callback) {\n\t\t\t\t\t\tvar startProgressBag = startProgress + (lengthProgress / bagsToLoad.length) * bagIndex,\n\t\t\t\t\t\t\tlengthProgressBag = lengthProgress / bagsToLoad.length,\n\t\t\t\t\t\t\tlengthProgressBagFirst = lengthProgressBag / 20;\n\t\t\t\t\t\t$xememex.server.jsonRequest({\n\t\t\t\t\t\t\turl: \"bags/\" + fullyEncodeURIComponent(bagName),\n\t\t\t\t\t\t\tprogress: function(lengthComputable,loaded,total) {\n\t\t\t\t\t\t\t\tsetProgressIndicator(startProgressBag,lengthProgressBagFirst,lengthComputable,loaded,total);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tcallback: function(err,bagInfo) {\n\t\t\t\t\t\t\t\tif(err) {\n\t\t\t\t\t\t\t\t\treturn callback(err);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Load the tiddlers from the bag\n\t\t\t\t\t\t\t\t$xememex.httpRequest({\n\t\t\t\t\t\t\t\t\turl: bagInfo.cacheUrl,\n\t\t\t\t\t\t\t\t\tprogress: function(lengthComputable,loaded,total) {\n\t\t\t\t\t\t\t\t\t\tsetProgressIndicator(startProgressBag + lengthProgressBagFirst,lengthProgressBag - lengthProgressBagFirst,lengthComputable,loaded,total);\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tcallback: function(err,data) {\n\t\t\t\t\t\t\t\t\t\tif(err) {\n\t\t\t\t\t\t\t\t\t\t\treturn callback(err);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tvar tiddlerInfoArray;\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\ttiddlerInfoArray = JSON.parse(data);\n\t\t\t\t\t\t\t\t\t\t} catch(e) {\n\t\t\t\t\t\t\t\t\t\t\treturn handleError(\"JSON parse error reading bag \" + bagName)\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tif(tiddlerInfoArray) {\n\t\t\t\t\t\t\t\t\t\t\ttiddlerInfoArray.forEach(function(tiddlerInfo) {\n\t\t\t\t\t\t\t\t\t\t\t\t$tw.preloadTiddlers.push(tiddlerInfo.fields);\n\t\t\t\t\t\t\t\t\t\t\t\tbagMap[tiddlerInfo.fields.title] = bagName;\n\t\t\t\t\t\t\t\t\t\t\t\tetagMap[tiddlerInfo.fields.title] = tiddlerInfo.etag;\n\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tcallback(null);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t},callback);\n\t\t\t\t}\n\t\t\t},\n\t\t\t// Get the skinny recipe tiddlers\n\t\t\tgetSkinnyRecipeTiddlers: {\n\t\t\t\tprogressContribution: 5,\n\t\t\t\thandler: function(startProgress,lengthProgress,callback) {\n\t\t\t\t\ttiddlersToReload = [];\n\t\t\t\t\t$xememex.server.jsonRequest({\n\t\t\t\t\t\turl: \"recipes/\" + fullyEncodeURIComponent(recipeName) + \"/tiddlers.json\",\n\t\t\t\t\t\tprogress: function(lengthComputable,loaded,total) {\n\t\t\t\t\t\t\tsetProgressIndicator(startProgress,lengthProgress,lengthComputable,loaded,total);\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcallback: function(err,data) {\n\t\t\t\t\t\t\tif(err) {\n\t\t\t\t\t\t\t\treturn callback(err);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// Process each incoming tiddler to see if it is newer than any existing one\n\t\t\t\t\t\t\tfor(var t=0; t<data.length; t++) {\n\t\t\t\t\t\t\t\tvar tiddlerDetails = data[t],\n\t\t\t\t\t\t\t\t\tetag = etagMap[tiddlerDetails.title];\n\t\t\t\t\t\t\t\tif(!etag || etag !== tiddlerDetails.etag) {\n\t\t\t\t\t\t\t\t\ttiddlersToReload.push(tiddlerDetails.title);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcallback(null);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t},\n\t\t\t// Reload any necessary tiddlers\n\t\t\treloadNewTiddlers: {\n\t\t\t\tprogressContribution: 2,\n\t\t\t\thandler: function(startProgress,lengthProgress,callback) {\n\t\t\t\t\tasync.eachOfSeries(tiddlersToReload,function(title,index,callback) {\n\t\t\t\t\t\t$xememex.server.jsonRequest({\n\t\t\t\t\t\t\turl: \"recipes/\" + fullyEncodeURIComponent(recipeName) + \"/tiddlers/\" + fullyEncodeURIComponent(title),\n\t\t\t\t\t\t\tprogress: function(lengthComputable,loaded,total) {\n\t\t\t\t\t\t\t\tsetProgressIndicator(startProgress + (lengthProgress / tiddlersToReload.length) * index,lengthProgress / tiddlersToReload.length,lengthComputable,loaded,total);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tcallback: function(err,tiddlerInfo) {\n\t\t\t\t\t\t\t\tif(err) {\n\t\t\t\t\t\t\t\t\treturn callback(err);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t$tw.preloadTiddlers.push(tiddlerInfo.fields);\n\t\t\t\t\t\t\t\tetagMap[title] = tiddlerInfo.etag;\n\t\t\t\t\t\t\t\tbagMap[title] = tiddlerInfo.bag;\n\t\t\t\t\t\t\t\tcallback(null);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t},callback);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t// Work out which tasks we need to run\n\tvar tasks = [];\n\tif($xememex.config[\"load-cached-bags\"]) {\n\t\ttasks.push(taskFunctions.getRecipeDetails);\n\t\ttasks.push(taskFunctions.getCachedBags);\n\t}\n\ttasks.push(taskFunctions.getSkinnyRecipeTiddlers);\n\ttasks.push(taskFunctions.reloadNewTiddlers);\n\t// Work out the progress contribution\n\tvar totalProgressContribution = 0;\n\ttasks.forEach(function(task) {\n\t\ttotalProgressContribution += task.progressContribution;\n\t});\n\t// Execute them\n\tvar currentProgressMark = 0;\n\tasync.eachOfSeries(tasks,\n\t\tfunction(task,index,callback) {\n\t\t\t// Give each task its proportion of the total progress time\n\t\t\tvar startProgressChunk = (currentProgressMark / totalProgressContribution) * 100,\n\t\t\t\tlengthProgressChunk = (task.progressContribution / totalProgressContribution) * 100;\n\t\t\ttask.handler(startProgressChunk,lengthProgressChunk,function(err) {\n\t\t\t\tcurrentProgressMark += task.progressContribution;\n\t\t\t\tcallback(err);\n\t\t\t});\n\t\t},\n\t\tfunction(err) {\n\t\t// Raise any errors\n\t\tif(err) {\n\t\t\treturn handleError(err);\t\t\t\n\t\t}\n\t\t// Save the bag/etag data and boot TiddlyWiki\n\t\t$tw.preloadTiddlers.push({title: MAP_BAG_TITLE, type: \"application/json\", text: JSON.stringify(bagMap)});\n\t\t$tw.preloadTiddlers.push({title: MAP_ETAG_TITLE, type: \"application/json\", text: JSON.stringify(etagMap)});\n\t\tbootTiddlyWiki();\n\t});\n}\n\nfunction setProgressIndicator(startChunk,lengthChunk,lengthComputable,loaded,total) {\n\tvar p;\n\tif(lengthComputable) {\n\t\tp = startChunk + lengthChunk * (loaded / total);\n\t} else {\n\t\tp = startChunk;\n\t}\n\t$xememex.pill.setProgress(p); // Progress 0-100\n}\n\nfunction bootTiddlyWiki() {\n\t$xememex.pill.hideDropdown();\n\t$tw.boot.boot();\t\n}\n\nfunction handleError(err) {\n\tvar msg;\n\tif(err === 401) {\n\t\tmsg = \"Access Denied\";\n\t} else {\n\t\tmsg = err.toString();\n\t}\n\talert(msg);\n}\n\n/*\nGet an object mapping tiddler titles to the DOM node containing the tiddler\n*/\nfunction getTiddlerStoreMap() {\n\tvar map = Object.create(null);\n\tvar e = document.getElementById(\"storeArea\").firstElementChild;\n\twhile(e) {\n\t\tmap[e.getAttribute(\"title\") || \"\"] = e;\n\t\te = e.nextElementSibling;\n\t}\n\treturn map;\n}\n\n/*\nGet the text of a tiddler identified by its DIV\n*/\nfunction getTiddlerText(e) {\n\tif(e) {\n\t\treturn e.firstElementChild.textContent;\t\t\n\t} else {\n\t\treturn undefined;\n\t}\n}\n\n/*\nWe also encode single quote because it is not URL safe for API Gateway (see http://stackoverflow.com/questions/18251399/why-doesnt-encodeuricomponent-encode-single-quotes-apostrophes)\n*/\nfunction fullyEncodeURIComponent(str) {\n\treturn encodeURIComponent(str).replace(/'/g,\"%27\");\n}\n\n})();\n","type":"application/javascript","module-type":"library"},"$:/plugins/federatial/xememex/readme":{"title":"$:/plugins/federatial/xememex/readme","text":"This plugin contains Xememex client utilities for TiddlyWiki.\n"},"$:/plugins/federatial/xememex/readonly":{"title":"$:/plugins/federatial/xememex/readonly","tags":"[[$:/tags/Stylesheet]]","text":"\\define button-selector(title)\nbutton.$title$, .tc-drop-down button.$title$, div.$title$\n\\end\n\n\\define hide-edit-controls()\n<$reveal state=\"$:/status/IsReadOnly\" type=\"match\" text=\"yes\" default=\"yes\">\n<<button-selector tc-btn-\\%24\\%3A\\%2Fcore\\%2Fui\\%2FButtons\\%2Fclone>>`,`\n<<button-selector tc-btn-\\%24\\%3A\\%2Fcore\\%2Fui\\%2FButtons\\%2Fdelete>>`,`\n<<button-selector tc-btn-\\%24\\%3A\\%2Fcore\\%2Fui\\%2FButtons\\%2Fedit>>`,`\n<<button-selector tc-btn-\\%24\\%3A\\%2Fcore\\%2Fui\\%2FButtons\\%2Fnew-here>>`,`\n<<button-selector tc-btn-\\%24\\%3A\\%2Fcore\\%2Fui\\%2FButtons\\%2Fnew-journal-here>>`,`\n<<button-selector tc-btn-\\%24\\%3A\\%2Fcore\\%2Fui\\%2FButtons\\%2Fimport>>`,`\n<<button-selector tc-btn-\\%24\\%3A\\%2Fcore\\%2Fui\\%2FButtons\\%2Fmanager>>`,`\n<<button-selector tc-btn-\\%24\\%3A\\%2Fcore\\%2Fui\\%2FButtons\\%2Fnew-image>>`,`\n<<button-selector tc-btn-\\%24\\%3A\\%2Fcore\\%2Fui\\%2FButtons\\%2Fnew-journal>>`,`\n<<button-selector tc-btn-\\%24\\%3A\\%2Fcore\\%2Fui\\%2FButtons\\%2Fnew-tiddler>> `{\n\tdisplay: none;\n}`\n</$reveal>\n\\end\n\n\\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline macrocallblock\n\n<<hide-edit-controls>>\n"},"$:/plugins/federatial/xememex/startup.js":{"title":"$:/plugins/federatial/xememex/startup.js","text":"/*\\\ntitle: $:/plugins/federatial/xememex/startup.js\ntype: application/javascript\nmodule-type: startup\n\nSetup Xememex components\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"xememex-startup\";\nexports.platforms = [\"browser\"];\nexports.before = [\"startup\"];\nexports.after = [\"load-modules\"];\nexports.synchronous = true;\n\nvar STATE_USERNAME_TITLE = \"$:/state/xememex/username\", // Blank if not logged in\n\tSTATE_EMAIL_TITLE = \"$:/state/xememex/email\",\n\tSTATE_GROUPS_TITLE = \"$:/state/xememex/groups\",\n\tSTATE_STATUS_TITLE = \"$:/state/xememex/status\"; // Status: WAITING, LOGGEDIN, LOGGEDOUT\n\nexports.startup = function() {\n\t// Check dependencies\n\tif(!window.$xememex) {\n\t\tconsole.log(\"Xememex is disabled because xememex.js is missing\");\n\t\treturn;\t\t\n\t}\n\tif(!window.AWSCognito) {\n\t\tconsole.log(\"Xememex is disabled because AWSCognito is missing\");\n\t\treturn;\n\t}\n\t// Initialise state tiddlers\n\t$tw.wiki.addTiddler({title: STATE_STATUS_TITLE, text: \"WAITING\"});\n\t$tw.wiki.addTiddler({title: STATE_USERNAME_TITLE, text: \"\"});\n\t// Listen for login/logout events\n\t$xememex.server.addEventListener(\"login-status-change\",function(user) {\n\t\tupdateUserStatus(user);\n\t});\n\t// Initialise user status tiddlers\n\tupdateUserStatus($xememex.server.user);\n};\n\nfunction updateUserStatus(user) {\n\tif(user) {\n\t\t$tw.wiki.addTiddler({title: STATE_STATUS_TITLE, text: \"LOGGEDIN\"});\n\t\t$tw.wiki.addTiddler({title: STATE_USERNAME_TITLE, text: user.name});\n\t\t$tw.wiki.addTiddler({title: STATE_EMAIL_TITLE, text: user.email});\n\t\t$tw.wiki.addTiddler({title: STATE_GROUPS_TITLE, text: user.groups.map(function(t){return \"* \" + t;}).join(\"\\n\"), list: user.groups});\n\t} else {\n\t\t$tw.wiki.addTiddler({title: STATE_STATUS_TITLE, text: \"LOGGEDOUT\"});\n\t\t$tw.wiki.addTiddler({title: STATE_USERNAME_TITLE, text: \"\"});\n\t\t$tw.wiki.addTiddler({title: STATE_EMAIL_TITLE, text: \"\"});\n\t\t$tw.wiki.addTiddler({title: STATE_GROUPS_TITLE, list: []});\n\t}\n}\n\n})();\n","type":"application/javascript","module-type":"startup"},"$:/plugins/federatial/xememex/status-button":{"title":"$:/plugins/federatial/xememex/status-button","tags":"$:/tags/TopRightBar","list-before":"$:/core/ui/TopBar/menu","text":"<span class=\"tc-popup-keep\">\n<$reveal state=\"$:/status/IsLoggedIn\" type=\"nomatch\" text=\"yes\">\n<$button message=\"tm-login\" tooltip=\"Login to Xememex\" class=\"tc-btn-invisible tc-status-button tc-status-button-logged-out\" selectedClass=\"tc-selected\">\n{{$:/plugins/federatial/xememex/icon}} Log in\n</$button>\n</$reveal>\n<$reveal state=\"$:/status/IsLoggedIn\" type=\"match\" text=\"yes\">\n<$button popup=<<qualify \"$:/state/popup/xememex-status-button\">> tooltip=\"Xememex login status\" class=\"tc-btn-invisible tc-status-button tc-status-button-logged-in\" selectedClass=\"tc-selected\">\n{{$:/plugins/federatial/xememex/icon}} Logged in as ''{{$:/status/UserName}}''\n</$button>\n</$reveal>\n</span>\n<$reveal state=<<qualify \"$:/state/popup/xememex-status-button\">> type=\"popup\" position=\"belowleft\" animate=\"yes\">\n<div class=\"tc-drop-down\">\n<p>\nLogged in as {{$:/status/UserName}} ({{$:/state/xememex/email}})\n<$list filter=\"[list[$:/state/xememex/groups!!list]sort[]]\">\n//<$text text=<<currentTiddler>>/>//\n</$list>\n</p>\n<$button message=\"tm-logout\" tag=\"a\">Logout</$button> <$button message=\"tm-server-refresh\" tag=\"a\">Fetch updates from server</$button>\n</div>\n</$reveal>"},"$:/plugins/federatial/xememex/styles":{"title":"$:/plugins/federatial/xememex/styles","tags":"[[$:/tags/Stylesheet]]","text":"\\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline macrocallblock\n\n/*\n** Background\n*/\n\nhtml body.tc-body {\n\tdisabled-background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='49' viewBox='0 0 28 49'%3E%3Cg fill-rule='evenodd'%3E%3Cg fill-opacity='0.82' fill-rule='nonzero'%3E%3Cpath d='M13.99 9.25l13 7.5v15l-13 7.5L1 31.75v-15l12.99-7.5zM3 17.9v12.7l10.99 6.34 11-6.35V17.9l-11-6.34L3 17.9zM0 15l12.98-7.5V0h-2v6.35L0 12.69v2.3zm0 18.5L12.98 41v8h-2v-6.85L0 35.81v-2.3zM15 0v7.5L27.99 15H28v-2.31h-.01L17 6.35V0h-2zm0 49v-8l12.99-7.5H28v2.31h-.01L17 42.15V49h-2z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E\");\n}\n\n/*\n** Hide irrelevant toolbar buttons\n*/\n\nbutton.tc-btn-\\%24\\%3A\\%2Fcore\\%2Fui\\%2FButtons\\%2Fencryption, div.tc-btn-\\%24\\%3A\\%2Fcore\\%2Fui\\%2FButtons\\%2Fencryption {\n\tdisplay: none;\t\n}\n\n\n/*\n** Login status button\n*/\n\nbutton.tc-btn-invisible.tc-status-button {\n\tcolor: white;\n\tborder-radius:4px;\n\tpadding: 3px 5px;\n\tfont-size: 0.85em;\n}\n\nbutton.tc-btn-invisible.tc-status-button svg {\n\tfill: white;\n}\n\nbutton.tc-btn-invisible.tc-status-button:hover {\n\tcolor: white;\n\tfill: white;\n}\n\nbutton.tc-btn-invisible.tc-status-button.tc-status-button-logged-in {\n\tbackground: green;\n}\n\nbutton.tc-btn-invisible.tc-status-button.tc-status-button-logged-out {\n\tbackground: blue;\t\n}\n\nbutton.tc-btn-invisible.tc-status-button.tc-status-button-logged-in:hover,\nbutton.tc-btn-invisible.tc-status-button.tc-status-button-logged-out:hover {\n\tbackground: black;\n}\n\nbutton.tc-btn-invisible.tc-status-button.tc-status-button-logged-in:hover svg,\nbutton.tc-btn-invisible.tc-status-button.tc-status-button-logged-out:hover svg {\n\tcolor: white;\n\tfill: white;\n}\n\n/*\n** Syncer stus\n*/\n\n.tc-syncer-status {\n}\n\n.tc-syncer-status-queued-out {\n\tposition: fixed;\n\ttop: 0;\n\tleft: 0;\n    line-height: 0;\n}\n\n.tc-syncer-status-in-progress {\n\tposition: fixed;\n\ttext-align: center;\n\ttop: 0;\n\tleft: 0;\n\tright: 0;\n    line-height: 0;\n}\n\n.tc-syncer-status-queued-in {\n\tposition: fixed;\n\ttext-align: right;\n\ttop: 0;\n\tright: 0;\n    line-height: 0;\n}\n\n.tc-syncer-status-item {\n\tdisplay: inline-block;\n\tmargin: 1px;\n\twidth: 3px;\n\theight: 3px;\n}\n\n.tc-syncer-status-queued-out .tc-syncer-status-item {\n\tbackground: red;\n}\n\n.tc-syncer-status-in-progress .tc-syncer-status-item {\n\tbackground: blue;\n}\n\n.tc-syncer-status-queued-in .tc-syncer-status-item {\n\tbackground: green;\n}\n\n"},"$:/plugins/federatial/xememex/syncadaptor.js":{"title":"$:/plugins/federatial/xememex/syncadaptor.js","text":"/*\\\ntitle: $:/plugins/federatial/xememex/syncadaptor.js\ntype: application/javascript\nmodule-type: syncadaptor\n\nA sync adaptor module for synchronising with Xememex servers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar CONFIG_HOST_TIDDLER = \"$:/config/tiddlyweb/host\",\n\tCONFIG_SYNC_DISABLE_LOAD_FROM_SERVER = \"$:/config/SyncDisableLoadFromServer\",\n\tDEFAULT_HOST_TIDDLER = \"$protocol$//$host$/\",\n\tLOGIN_MODAL_TITLE = \"$:/plugins/federatial/xememex/login-modal\";\n\nfunction XememexAdaptor(options) {\n\tthis.wiki = options.wiki;\n\tthis.logger = new $tw.utils.Logger(\"XememexAdaptor\");\n\tthis.recipe = $tw.wiki.getTiddlerText(\"$:/plugins/federatial/xememex/config/recipe\");\n\tthis.isReadOnly = true;\n\tif($xememex && $xememex.server) {\n\t\t$xememex.server.addEventListener(\"login-status-change\",function(user) {\n\t\t\tif($tw.syncer) {\n\t\t\t\t$tw.syncer.getStatus();\t\t\t\t\n\t\t\t}\n\t\t});\n\t}\n}\n\nXememexAdaptor.prototype.name = \"xememex\";\n\nXememexAdaptor.prototype.setLoggerSaveBuffer = function(loggerForSaving) {\n\tthis.logger.setSaveBuffer(loggerForSaving);\n};\n\nXememexAdaptor.prototype.isReady = function() {\n\treturn true;\n};\n\nXememexAdaptor.prototype.getTiddlerInfo = function(tiddlerOrTitle) {\n\tvar title = tiddlerOrTitle;\n\tif(title instanceof $tw.Tiddler) {\n\t\ttitle = tiddlerOrTitle.fields.title;\n\t}\n\tvar etag = this.wiki.extractTiddlerDataItem(\"$:/state/federatial/xememex/tiddlers/etag\",title),\n\t\tbag = this.wiki.extractTiddlerDataItem(\"$:/state/federatial/xememex/tiddlers/bag\",title);\n\tif(etag && bag) {\n\t\treturn {\n\t\t\ttitle: title,\n\t\t\tetag: etag,\n\t\t\tbag: bag\n\t\t};\n\t} else {\n\t\treturn undefined;\n\t}\n};\n\nXememexAdaptor.prototype.getTiddlerRevision = function(title) {\n\treturn this.wiki.extractTiddlerDataItem(\"$:/state/federatial/xememex/tiddlers/etag\",title);\n};\n\nXememexAdaptor.prototype.setTiddlerInfo = function(title,etag,bag) {\n\tthis.wiki.setText(\"$:/state/federatial/xememex/tiddlers/etag\",null,title,etag,{suppressTimestamp: true});\n\tthis.wiki.setText(\"$:/state/federatial/xememex/tiddlers/bag\",null,title,bag,{suppressTimestamp: true});\n};\n\nXememexAdaptor.prototype.removeTiddlerInfo = function(title) {\n\tthis.wiki.setText(\"$:/state/federatial/xememex/tiddlers/etag\",null,title,undefined,{suppressTimestamp: true});\n\tthis.wiki.setText(\"$:/state/federatial/xememex/tiddlers/bag\",null,title,undefined,{suppressTimestamp: true});\n};\n\n/*\nGet the current status of the TiddlyWeb connection\nReturns err,isLoggedIn,username,isReadOnly via callback\n*/\nXememexAdaptor.prototype.getStatus = function(callback) {\n\tvar self = this;\n\tif(!$xememex || !$xememex.server) {\n\t\treturn callback(null,false,null,true);\n\t}\n\t$xememex.server.getSession(function(err,user) {\n\t\tif(err) {\n\t\t\treturn callback(err);\n\t\t}\n\t\t$xememex.server.jsonRequest({\n\t\t\turl: \"recipes/\" + fullyEncodeURIComponent(self.recipe),\n\t\t\tcallback: function(err,recipeInfo) {\n\t\t\t\tif(err) {\n\t\t\t\t\treturn callback(null,false,null,true);\n\t\t\t\t}\n\t\t\t\tif(user) {\n\t\t\t\t\t$xememex.pill.hideDropdown();\n\t\t\t\t}\n\t\t\t\tself.isReadOnly = !recipeInfo[\"topmost-user-writable-bag\"];\n\t\t\t\tself.shouldRefreshFromServer = !!recipeInfo[\"refresh-from-server\"];\n\t\t\t\tcallback(null,!!user,user && user.name,self.isReadOnly);\n\t\t\t}\n\t\t});\n\t});\n};\n\n/*\nAttempt to login and invoke the callback(err)\n*/\nXememexAdaptor.prototype.login = function(username,password,callback) {\n\tvar self = this;\n\t$xememex.server.login(username,password,null,null,function(err) {\n\t\tif(err) {\n\t\t\tself.logger.log(\"login error: \" + err);\n\t\t\tif(err.code) {\n\t\t\t\tswitch(err.code) {\n\t\t\t\t\tcase \"UserNotFoundException\":\n\t\t\t\t\t\terr = \"Username `\" + username + \"` not found. Please check that you have typed your username correctly\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"NotAuthorizedException\":\n\t\t\t\t\t\terr = \"User `\" + username + \"` is not authorised. Please check that you have typed your password correctly\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\terr = \"<pre><code>\" + err + \"</code></pre>\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tself.logger.alert(err);\n\t\t}\n\t\tcallback(err);\n\t});\n};\n\n/*\nDisplay our custom login prompt\n*/\nXememexAdaptor.prototype.displayLoginPrompt = function() {\n\t$xememex.pill.hideProgress();\n\t$xememex.pill.showLogin();\n\t$xememex.pill.showDropdown();\n};\n\n/*\nHandle forgotten password link\n*/\nXememexAdaptor.prototype.forgotPassword = function() {\n\t$xememex.server.forgotPassword(data.email,function(err,result) {\n\t\tif(err) {\n\t\t\tself.logger.log(\"Error handling forgotten password\",err);\n\t\t\tvar msg = err;\n\t\t\tswitch(err.code) {\n\t\t\t\tcase \"UserNotFoundException\":\n\t\t\t\t\tmsg  = \"Email address not found\";\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\treturn alert(msg);\n\t\t}\n\t\tif(result) {\n\t\t\talert(\"Please check your email for your new temporary password\");\n\t\t}\n\t});\n};\n\n/*\n*/\nXememexAdaptor.prototype.logout = function(callback) {\n\t$xememex.server.logout();\n};\n\n/*\nGet metadata for any new tiddlers from the server\n*/\nXememexAdaptor.prototype.getUpdatedTiddlers = function(syncer,callback) {\n\tvar self = this;\n\tif(!$xememex || !$xememex.server) {\n\t\treturn callback(null,null);\n\t}\n\tif($tw.wiki.getTiddlerText(CONFIG_SYNC_DISABLE_LOAD_FROM_SERVER) === \"yes\") {\n\t\treturn callback(null,null);\n\t}\n\tif(!self.shouldRefreshFromServer) {\n\t\treturn callback(null,null);\n\t}\n\t$xememex.server.jsonRequest({\n\t\turl: \"recipes/\" + fullyEncodeURIComponent(this.recipe) + \"/tiddlers.json\",\n\t\tcallback: function(err,data) {\n\t\t\tif(err) {\n\t\t\t\tif(err.toString() === \"Error: Not logged in\") {\n\t\t\t\t\treturn callback(null,null);\n\t\t\t\t}\n\t\t\t\tself.logger.log(\"Error retrieving skinny tiddler: \" + err);\n\t\t\t\treturn callback(null,null);\n\t\t\t}\n\t\t\t// Prepare results\n\t\t\tvar result = {\n\t\t\t\tmodifications: [],\n\t\t\t\tdeletions: []\n\t\t\t};\n\t\t\t// Process each incoming tiddler to see if it is newer than any existing one, keeping track of which tiddlers are found\n\t\t\tvar currentTitles = syncer.getSyncedTiddlers();\n\t\t\tfor(var t=0; t<data.length; t++) {\n\t\t\t\tvar tiddlerDetails = data[t],\n\t\t\t\t\tpos = currentTitles.indexOf(tiddlerDetails.title);\n\t\t\t\tif(pos != -1) {\n\t\t\t\t\tcurrentTitles.splice(pos,1);\n\t\t\t\t}\n\t\t\t\tvar tiddlerInfo = syncer.tiddlerInfo[tiddlerDetails.title];\n\t\t\t\tif(!tiddlerInfo || tiddlerDetails.etag !== tiddlerInfo.revision) {\n\t\t\t\t\tresult.modifications.push(tiddlerDetails.title);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Delete any tiddlers we've got that were not listed in the incoming\n\t\t\t$tw.utils.each(currentTitles,function(title) {\n\t\t\t\tresult.deletions.push(title);\n\t\t\t});\n\t\t\tcallback(null,result);\n\t\t}\n\t});\n};\n\n/*\nSave a tiddler and invoke the callback with (err,adaptorInfo,revision)\n*/\nXememexAdaptor.prototype.saveTiddler = function(tiddler,callback) {\n\tif(this.isReadOnly) {\n\t\treturn callback(null,{bag: \"default\"},\"\");\n\t}\n\tvar self = this,\n\t\ttitle = tiddler.fields.title;\n\tif(!$xememex || !$xememex.server) {\n\t\treturn callback(\"Not logged in\",null);\n\t}\n\t$xememex.server.jsonRequest({\n\t\ttype: \"PUT\",\n\t\turl: \"recipes/\" + fullyEncodeURIComponent(this.recipe) + \"/tiddlers/\" + fullyEncodeURIComponent(title),\n\t\theaders: {\n\t\t\t\"Content-type\": \"application/json\"\n\t\t},\n\t\tdata: JSON.stringify(tiddler.getFieldStrings(),null,$tw.config.preferences.jsonSpaces),\n\t\tcallback: function(err,data) {\n\t\t\tconsole.log(\"Back from saveTiddler\",err,data);\n\t\t\tif(err) {\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\tif(data && data.errorMessage) {\n\t\t\t\treturn callback(data.errorMessage)\n\t\t\t}\n\t\t\tself.setTiddlerInfo(title,data.etag,data.bag);\n\t\t\tcallback(err,{bag: data.bag},data.etag);\n\t\t}\n\t});\n};\n\n/*\nLoad a tiddler and invoke the callback with (err,tiddlerFields)\n\nIf the tiddler is not found, err and tiddlerFields are both null\n*/\nXememexAdaptor.prototype.loadTiddler = function(title,callback) {\n\tvar self = this;\n\tif(!$xememex || !$xememex.server) {\n\t\treturn callback(\"Not logged in\",null);\n\t}\n\t$xememex.server.jsonRequest({\n\t\turl: \"recipes/\" + fullyEncodeURIComponent(this.recipe) + \"/tiddlers/\" + fullyEncodeURIComponent(title),\n\t\tcallback: function(err,data) {\n\t\t\tconsole.log(\"Back from loadTiddler\",err,data);\n\t\t\tif(!err) {\n\t\t\t\tself.setTiddlerInfo(title,data.etag,data.bag);\n\t\t\t\treturn callback(null,data.fields);\n\t\t\t} else if(err === 404) {\n\t\t\t\treturn callback(null,null);\n\t\t\t} else {\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t}\n\t});\n};\n\n/*\nLoad one or more tiddlers and invoke the callback with (err,tiddlerFieldsArray)\n*/\nXememexAdaptor.prototype.batchLoadTiddlers = function(titles,callback) {\n\tvar self = this,\n\t\tpayload = titles.map(function(title) {\n\t\t\treturn {\n\t\t\t\ttype: \"GET\",\n\t\t\t\ttitle: title\n\t\t\t};\n\t\t});\n\tif(!$xememex || !$xememex.server) {\n\t\treturn callback(\"Not logged in\",null);\n\t}\n\t$xememex.server.jsonRequest({\n\t\ttype: \"POST\",\n\t\turl: \"recipes/\" + fullyEncodeURIComponent(this.recipe) + \"/batch\",\n\t\theaders: {\n\t\t\t\"Content-type\": \"application/json\"\n\t\t},\n\t\tdata: JSON.stringify(payload,null,$tw.config.preferences.jsonSpaces),\n\t\tcallback: function(err,data) {\n\t\t\tconsole.log(\"Back from batchLoadTiddlers\",err,data);\n\t\t\tif(err) {\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\tvar tiddlers = [];\n\t\t\tdata.forEach(function(tiddlerInfo) {\n\t\t\t\ttiddlers.push(tiddlerInfo.fields);\n\t\t\t\tself.setTiddlerInfo(tiddlerInfo.fields.title,tiddlerInfo.etag,tiddlerInfo.bag);\t\t\t\t\n\t\t\t});\n\t\t\tcallback(err,tiddlers);\n\t\t}\n\t});\n};\n\n/*\nDelete a tiddler and invoke the callback with (err)\noptions include:\ntiddlerInfo: the syncer's tiddlerInfo for this tiddler\n*/\nXememexAdaptor.prototype.deleteTiddler = function(title,callback,options) {\n\tif(this.isReadOnly) {\n\t\treturn callback(null);\n\t}\n\tvar self = this,\n\t\ttiddlerInfo = this.getTiddlerInfo(title),\n\t\tbagName = tiddlerInfo && tiddlerInfo.bag;\n\tif(!$xememex || !$xememex.server) {\n\t\treturn callback(\"Not logged in\",null);\n\t}\n\tif(bagName) {\n\t\t$xememex.server.request({\n\t\t\ttype: \"DELETE\",\n\t\t\turl: \"recipes/\" + fullyEncodeURIComponent(self.recipe) + \"/tiddlers/\" + fullyEncodeURIComponent(title),\n\t\t\theaders: {\n\t\t\t\t\"Content-type\": \"application/json\"\n\t\t\t},\n\t\t\tcallback: function(err,data,httpRequest) {\n\t\t\t\tconsole.log(\"Back from deleteTiddler\",err,data,httpRequest.response);\n\t\t\t\tif(data && data.errorMessage) {\n\t\t\t\t\treturn callback(data.errorMessage)\n\t\t\t\t} else if(err === 400 && httpRequest.response === \"ERROR_TIDDLER_IS_NOT_IN_TOP_BAG_IN_RECIPE\") {\n\t\t\t\t\tself.logger.alert(\"'<$text text=\\\"\\\"\\\"\" + title + \"\\\"\\\"\\\"/>' cannot be deleted because it is not from the topmost bag of the recipe '\" + self.recipe + \"'\");\n\t\t\t\t\t$tw.syncer.enqueueLoadTiddler(title);\n\t\t\t\t\tvar story = new $tw.Story();\n\t\t\t\t\tstory.navigateTiddler(title);\n\t\t\t\t\treturn callback(null);\n\t\t\t\t} else if(err) {\n\t\t\t\t\tcallback(err,data);\n\t\t\t\t} else {\n\t\t\t\t\tself.removeTiddlerInfo(title);\n\t\t\t\t\tcallback(err,data);\t\t\t\t\t\n\t\t\t\t}\n\t\t\t}\n\t\t});\t\t\n\t} else {\n\t\t// If we don't have a record of the tiddler then it was never synced to the server so we don't need to delete it\n\t\t$tw.utils.nextTick(function() {\n\t\t\tcallback(null);\n\t\t});\n\t}\n};\n\n/*\nWe also encode single quote because it is not URL safe for API Gateway (see http://stackoverflow.com/questions/18251399/why-doesnt-encodeuricomponent-encode-single-quotes-apostrophes)\n*/\nfunction fullyEncodeURIComponent(str) {\n\treturn encodeURIComponent(str).replace(/'/g,\"%27\");\n}\n\nif($tw.browser) {\n\texports.adaptorClass = XememexAdaptor;\n}\n\n})();\n","type":"application/javascript","module-type":"syncadaptor"},"$:/core/modules/startup/task-daemon.js":{"title":"$:/core/modules/startup/task-daemon.js","text":"/*\\\ntitle: $:/core/modules/startup/task-daemon.js\ntype: application/javascript\nmodule-type: startup\n\nTask daemon for on-render widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"task-daemon\";\nexports.platforms = [\"browser\"];\nexports.after = [\"startup\"];\nexports.synchronous = true;\n\t\t\nexports.startup = function() {\n\t$tw.taskDaemon = new TaskDaemon();\n};\n\nfunction TaskDaemon() {\n\tthis.lastInvocationTime = {}; // Hashmap by task name of dates\n}\n\n/*\nOptions include:\n\nwidget: reference to the widget triggering the task\nname: name for this task\nactions: actions comprising the task\nminimumInterval: minimum interval between invocations in milliseconds\n*/\nTaskDaemon.prototype.invoke = function(options) {\n\tvar now = new Date();\n\tif(options.name) {\n\t\tif(options.minimumInterval && this.lastInvocationTime[options.name]) {\n\t\t\tif((now - this.lastInvocationTime[options.name]) < options.minimumInterval) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tthis.lastInvocationTime[options.name] = now;\n\t}\nconsole.log(\"Invoking actions\",options.actions)\n\toptions.widget.invokeActionString(options.actions,options.widget,{});\n}\n\n})();\n","type":"application/javascript","module-type":"startup"},"$:/plugins/federatial/xememex/save/offline":{"title":"$:/plugins/federatial/xememex/save/offline","text":"\\define saveTiddlerFilter()\n[is[tiddler]] -[prefix[$:/state/]] -[prefix[$:/status/]] -[[$:/HistoryList]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] -[prefix[$:/plugins/federatial/xememex]] -[[$:/isEncrypted]] +[sort[title]]\n\\end\n{{$:/core/templates/tiddlywiki5.html}}\n"},"$:/plugins/federatial/xememex/save/all-prefix":{"title":"$:/plugins/federatial/xememex/save/all-prefix","text":"\\define saveTiddlerFilter()\n[is[tiddler]] -[prefix[$:/state/popup/]] -[[$:/HistoryList]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]]\n\\end\n{{$:/plugins/federatial/xememex/templates/tiddlywiki5.html-prefix}}\n"},"$:/plugins/federatial/xememex/save/all-suffix":{"title":"$:/plugins/federatial/xememex/save/all-suffix","text":"\\define saveTiddlerFilter()\n[is[tiddler]] -[prefix[$:/state/popup/]] -[[$:/HistoryList]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]]\n\\end\n{{$:/plugins/federatial/xememex/templates/tiddlywiki5.html-suffix}}\n"},"$:/plugins/federatial/xememex/save/empty-prefix":{"title":"$:/plugins/federatial/xememex/save/empty-prefix","text":"\\define saveTiddlerFilter()\n[[$:/core]] [[$:/isEncrypted]] [[$:/themes/tiddlywiki/snowwhite]] [[$:/themes/tiddlywiki/vanilla]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]]\n\\end\n{{$:/plugins/federatial/xememex/templates/tiddlywiki5.html-prefix}}\n"},"$:/plugins/federatial/xememex/save/empty-suffix":{"title":"$:/plugins/federatial/xememex/save/empty-suffix","text":"\\define saveTiddlerFilter()\n[[$:/core]] [[$:/isEncrypted]] [[$:/themes/tiddlywiki/snowwhite]] [[$:/themes/tiddlywiki/vanilla]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]]\n\\end\n{{$:/plugins/federatial/xememex/templates/tiddlywiki5.html-suffix}}\n"},"$:/plugins/federatial/xememex/templates/tiddlywiki5.html-prefix":{"title":"$:/plugins/federatial/xememex/templates/tiddlywiki5.html-prefix","text":"<$set name=\"saveTiddlerAndShadowsFilter\" filter=\"[subfilter<saveTiddlerFilter>] [subfilter<saveTiddlerFilter>plugintiddlers[]]\">\n`<!doctype html>\n`{{$:/core/templates/MOTW.html}}`<html lang=\"`<$text text={{{ [{$:/language}get[name]] }}}/>`\">\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n<!--~~ Raw markup for the top of the head section ~~-->\n`{{{ [<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified/TopHead]] ||$:/core/templates/raw-static-tiddler}}}`\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=Edge\"/>\n<meta name=\"application-name\" content=\"TiddlyWiki\" />\n<meta name=\"generator\" content=\"TiddlyWiki\" />\n<meta name=\"tiddlywiki-version\" content=\"`{{$:/core/templates/version}}`\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\" />\n<meta name=\"mobile-web-app-capable\" content=\"yes\"/>\n<meta name=\"format-detection\" content=\"telephone=no\" />\n<meta name=\"copyright\" content=\"`{{$:/core/copyright.txt}}`\" />\n<link id=\"faviconLink\" rel=\"shortcut icon\" href=\"favicon.ico\">\n<title>`{{$:/core/wiki/title}}`</title>\n<!--~~ This is a Tiddlywiki file. The points of interest in the file are marked with this pattern ~~-->\n\n<!--~~ Raw markup ~~-->\n`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/core/wiki/rawmarkup]] ||$:/core/templates/plain-text-tiddler}}}\n{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkup]] ||$:/core/templates/plain-text-tiddler}}}\n{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified]] ||$:/core/templates/raw-static-tiddler}}}`\n</head>\n<body class=\"tc-body\">\n<!--~~ Raw markup for the top of the body section ~~-->\n`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified/TopBody]] ||$:/core/templates/raw-static-tiddler}}}`\n<!--~~ Static styles ~~-->\n<div id=\"styleArea\">\n`{{$:/boot/boot.css||$:/core/templates/css-tiddler}}`\n</div>\n<!--~~ Static content for Google and browsers without JavaScript ~~-->\n<noscript>\n<div id=\"splashArea\">\n`{{$:/core/templates/static.area}}`\n</div>\n</noscript>\n<!--~~ Ordinary tiddlers ~~-->\n<div id=\"storeArea\" style=\"display:none;\">\n`\n"},"$:/plugins/federatial/xememex/templates/tiddlywiki5.html-suffix":{"title":"$:/plugins/federatial/xememex/templates/tiddlywiki5.html-suffix","text":"\\define tiddlers()\n<$list filter=<<saveTiddlerFilter>> template=\"$:/core/templates/html-div-tiddler\"/>\n\\end\n<$set name=\"saveTiddlerAndShadowsFilter\" filter=\"[subfilter<saveTiddlerFilter>] [subfilter<saveTiddlerFilter>plugintiddlers[]]\">\n<<tiddlers>>\n`</div>\n<!--~~ Library modules ~~-->\n<div id=\"libraryModules\" style=\"display:none;\">\n`{{{ [is[system]type[application/javascript]library[yes]] ||$:/core/templates/javascript-tiddler}}}`\n</div>\n<!--~~ Boot kernel prologue ~~-->\n<div id=\"bootKernelPrefix\" style=\"display:none;\">\n`{{ $:/boot/bootprefix.js ||$:/core/templates/javascript-tiddler}}`\n</div>\n<!--~~ Boot kernel ~~-->\n<div id=\"bootKernel\" style=\"display:none;\">\n`{{ $:/boot/boot.js ||$:/core/templates/javascript-tiddler}}`\n</div>\n<!--~~ Raw markup for the bottom of the body section ~~-->\n`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified/BottomBody]] ||$:/core/templates/raw-static-tiddler}}}`\n</body>\n</html>`\n"},"$:/plugins/federatial/xememex/upgrader.js":{"title":"$:/plugins/federatial/xememex/upgrader.js","text":"/*\\\ntitle: $:/plugins/federatial/xememex/upgrader.js\ntype: application/javascript\nmodule-type: upgrader\n\nUpgrader module that suppresses Xememex-specific system tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar DONT_IMPORT_PREFIX_LIST = [\"$:/plugins/federatial/xememex\"];\n\nexports.upgrade = function(wiki,titles,tiddlers) {\n\tvar self = this,\n\t\tmessages = {};\n\t// Check for tiddlers on our list\n\t$tw.utils.each(titles,function(title) {\n\t\tfor(var t=0; t<DONT_IMPORT_PREFIX_LIST.length; t++) {\n\t\t\tvar prefix = DONT_IMPORT_PREFIX_LIST[t];\n\t\t\tif(title.substr(0,prefix.length) === prefix) {\n\t\t\t\ttiddlers[title] = Object.create(null);\n\t\t\t\tmessages[title] = \"Xememex system tiddler blocked\";\n\t\t\t}\n\t\t}\n\t});\n\treturn messages;\n};\n\n})();\n","type":"application/javascript","module-type":"upgrader"}}}
```
<script>

window.$tw = window.$tw || {};

$tw.boot = $tw.boot || {};

$tw.preloadTiddlers = $tw.preloadTiddlers || [];

$tw.boot.suppressBoot = true;

window.$xememex = {
	config: {
		"require-login": false,
		"load-cached-bags": false,
		"pill-button": false,
		"pill-dropdown": "modal",
		"show-cancel": true
	}
}

</script>
<script src="../~lib/xememex.js" onerror="console.log('Cannot load xememex.js');$tw.boot.suppressBoot = false;"></script>
<script>
```
{{$:/plugins/federatial/xememex/raw-markup-boot.js}}
```
</script>
```
{"tiddlers":{"$:/core/ui/ViewTemplate/classic":{"title":"$:/core/ui/ViewTemplate/classic","tags":"$:/tags/ViewTemplate $:/tags/EditTemplate","type":"text/vnd.tiddlywiki","text":"\n\n"},"$:/core/modules/widgets/classictransclude.js":{"title":"$:/core/modules/widgets/classictransclude.js","text":"/*\\\ntitle: $:/core/modules/widgets/classictransclude.js\ntype: application/javascript\nmodule-type: widget\n\nTransclude widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\nvar sliceSeparator = \"::\";\nvar sectionSeparator = \"##\";\n\nfunction getsectionname(title) {\n\tif(!title)\n\t\treturn \"\";\n\tvar pos = title.indexOf(sectionSeparator);\n\tif(pos != -1) {\n\t\treturn title.substr(pos + sectionSeparator.length);\n\t}\n\treturn \"\";\n}\nfunction getslicename(title) { \n\tif(!title)\n\t\treturn \"\";\n\tvar pos = title.indexOf(sliceSeparator);\n\tif(pos != -1) {\n\t\treturn title.substr(pos + sliceSeparator.length);\n\t}\n\treturn \"\";\n};\nfunction gettiddlername(title) {\n\tif(!title)\n\t\treturn \"\";\n\tvar pos = title.indexOf(sectionSeparator);\n\n\tif(pos != -1) {\n\t\treturn title.substr(0,pos);\n\t}\n\tpos = title.indexOf(sliceSeparator);\n\tif(pos != -1) {\n\t\treturn title.substr(0,pos);\n\t}\n\treturn title;\n}\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar TranscludeWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nTranscludeWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nTranscludeWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nTranscludeWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.rawTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.transcludeTitle = gettiddlername(this.rawTitle);\n\tthis.section = getsectionname(this.rawTitle);\n\tthis.slice = getslicename(this.rawTitle);\n\t// Check for recursion\n\tvar recursionMarker = this.makeRecursionMarker();\n\tif(this.parentWidget && this.parentWidget.hasVariable(\"transclusion\",recursionMarker)) {\n\t\tthis.makeChildWidgets([{type: \"text\", text: $tw.language.getString(\"Error/RecursiveTransclusion\")}]);\n\t\treturn;\n\t}\n\t// Check for correct type\n\tvar existingTiddler = this.wiki.getTiddler(this.transcludeTitle);\n\t// Check if we're dealing with a classic tiddler\n\tif(existingTiddler && existingTiddler.hasField(\"type\") && existingTiddler.fields.type !== \"text/x-tiddlywiki\") {\n\t\tthis.makeChildWidgets([{type: \"text\", text: \"Tiddler not of type 'text/x-tiddlywiki'\"}]);\n\t\treturn;\n\t}\n\tif(existingTiddler && !existingTiddler.hasField(\"type\")) {\n\t\tthis.makeChildWidgets([{type: \"text\", text: \"Tiddler not of type 'text/x-tiddlywiki'\"}]);\n\t\treturn;\n\t}\t\t\n\t// Set context variables for recursion detection\n\tthis.setVariable(\"transclusion\",recursionMarker);\n\t// Parse \n\tvar text = this.wiki.getTiddlerText(this.transcludeTitle);\n\tif (!!this.section||!!this.slice) {\n\t\ttext =this.refineTiddlerText(text, this.section, this.slice);\n\t}\n\n\tthis.options  ={};\n\tthis.options.parseAsInline = false;\n\tvar parser = this.wiki.parseText(\"text/x-tiddlywiki\",text,{});\n\tvar\tparseTreeNodes = parser ? parser.tree : this.parseTreeNode.children;\n\t// Construct the child widgets\n\tthis.makeChildWidgets(parseTreeNodes);\n};\n/*\nCompose a string comprising the title, field and/or index to identify this transclusion for recursion detection\n*/\nTranscludeWidget.prototype.makeRecursionMarker = function() {\n\tvar output = [];\n\toutput.push(\"{\");\n\toutput.push(this.getVariable(\"currentTiddler\",{defaultValue: \"\"}));\n\toutput.push(\"|\");\n\toutput.push(this.transcludeTitle || \"\");\n\toutput.push(\"|\");\n\toutput.push(this.transcludeField || \"\");\n\toutput.push(\"|\");\n\toutput.push(this.transcludeIndex || \"\");\n\toutput.push(\"|\");\n\toutput.push(this.section || \"\");\n\toutput.push(\"|\");\n\toutput.push(this.slice || \"\");\n\toutput.push(\"}\");\n\treturn output.join(\"\");\n};\n\nTranscludeWidget.prototype.slicesRE = /(?:^([\\'\\/]{0,2})~?([\\.\\w]+)\\:\\1[\\t\\x20]*([^\\n]*)[\\t\\x20]*$)|(?:^\\|([\\'\\/]{0,2})~?([\\.\\w]+)\\:?\\4\\|[\\t\\x20]*([^\\|\\n]*)[\\t\\x20]*\\|$)/gm;\n\nTranscludeWidget.prototype.calcAllSlices = function(text)\n{\n\tvar slices = {};\n\tthis.slicesRE.lastIndex = 0;\n\tvar m = this.slicesRE.exec(text);\n\twhile(m) {\n\t\tif(m[2])\n\t\t\tslices[m[2]] = m[3];\n\t\telse\n\t\t\tslices[m[5]] = m[6];\n\t\tm = this.slicesRE.exec(text);\n\t}\n\treturn slices;\n};\n\n// Returns the slice of text of the given name\nTranscludeWidget.prototype.getTextSlice = function(text,sliceName)\n{\n\treturn (this.calcAllSlices(text))[sliceName];\n};\n\nTranscludeWidget.prototype.refineTiddlerText = function(text,section,slice)\n{\n\tvar textsection = null;\n\tif (slice) {\n\t\tvar textslice = this.getTextSlice(text,slice);\n\t\tif(textslice)\n\t\t\treturn textslice;\n\t}\n\tif(!section)\n\t\treturn text;\n\tvar re = new RegExp(\"(^!{1,6}[ \\t]*\" + $tw.utils.escapeRegExp(section) + \"[ \\t]*\\n)\",\"mg\");\n\tre.lastIndex = 0;\n\tvar match = re.exec(text);\n\tif(match) {\n\t\tvar t = text.substr(match.index+match[1].length);\n\t\tvar re2 = /^!/mg;\n\t\tre2.lastIndex = 0;\n\t\tmatch = re2.exec(t); //# search for the next heading\n\t\tif(match)\n\t\t\tt = t.substr(0,match.index-1);//# don't include final \\n\n\t\treturn t;\n\t}\n\treturn \"\";\n}\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nTranscludeWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tiddler ||changedTiddlers[this.transcludeTitle]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\t\t\n\t}\n};\n\nexports.classictransclude = TranscludeWidget;\n\n})();\n","type":"application/javascript","module-type":"widget"},"$:/macros/tiddlywiki/entry.js":{"title":"$:/macros/tiddlywiki/entry.js","text":"/*\\\ntitle: $:/macros/tiddlywiki/entry.js\ntype: application/javascript\nmodule-type: macro\n\\*/\n(function(){\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n/*\nInformation about this macro\nreturns value of key in a data json tiddler\nnote that macros are not connected with the refresh mechanism -use with caution.\n*/\nexports.name = \"entryof\";\n\nexports.params = [\n\t{ name: \"key\" }, { name: \"map\" }\n];\n/*\nRun the macro\n*/\nexports.run = function(key,map) {\n\ttry {\n\t\treturn  JSON.parse(map)[key];\n\t} catch(e) {\n\t\treturn \"\";\n\t}\n}\n})();\n","type":"application/javascript","module-type":"macro"},"$:/plugins/tiddlywiki/tw2parser/image-css":{"title":"$:/plugins/tiddlywiki/tw2parser/image-css","tags":"$:/tags/Stylesheet","type":"text/plain","text":".classic-image-left{\n     float: left;\n}\n\n.classic-image-right{\n     float: right;\n}\n"},"$:/plugins/tiddlywiki/tw2parser/macrodefs":{"title":"$:/plugins/tiddlywiki/tw2parser/macrodefs","text":"\\define tiddler(tiddler)\n<$classictransclude tiddler = \"$tiddler$\"/>\n\\end\n\n\\define slider(chkUniqueCookieName tiddler label tooltip)\n<span title=$tooltip$><$button popup=\"$chkUniqueCookieName$\" class=\"tc-btn-invisible tc-slider\">$label$</$button>\n<$reveal type=\"nomatch\" text=\"\" default=\"\" state=\"$chkUniqueCookieName$\" animate=\"yes\">\n<$classictransclude tiddler = \"$tiddler$\"/>\n</$reveal></span>\n\\end\n\n\\define __system_tabinstance(state, currentTab, prompts, labels)\n\t\t<span title=<<entryof \"$currentTab$\" \"\"\"$prompts$\"\"\">> ><$button set=<<qualify \"$state$\">> setTo=\"$currentTab$\" selectedClass=\"tc-tab-selected\">\n\t\t<<entryof \"$currentTab$\" \"\"\"$labels$\"\"\" >>\n\t\t</$button></span>\n\\end\n\n\\define __system_tabs(tabsList,prompts,labels,state:\"$:/state/tab\")\n<div class=\"tc-tab-buttons\">\n\t<$list filter=\"$tabsList$\" variable=\"currentTab\">\n\t\t<$macrocall $name=\"__system_tabinstance\" state=\"$state$\" prompts=\"\"\"$prompts$\"\"\" labels=\"\"\"$labels$\"\"\" currentTab=<<currentTab>>/>\n\t</$list>\n</div>\n<div class=\"tc-tab-divider\"/>\n<div class=\"tc-tab-content\">\n\t<$list filter=\"$tabsList$\" variable=\"currentTab\">\n\t\t<$reveal type=\"match\" state=<<qualify \"$state$\">> text=<<currentTab>> default=\"$default$\">\n\t\t\t<$classictransclude tiddler=<<currentTab>> />\n\t\t</$reveal>\n\t</$list>\n</div>\n\\end\n"},"$:/macros/classic/macroadapter.js":{"title":"$:/macros/classic/macroadapter.js","text":"/*\\\ntitle: $:/macros/classic/macroadapter.js\ntype: application/javascript\nmodule-type: module\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n/*\nInformation about this module:\nrename macros and\nre-jig macro params from tw2 to tw5 style\nnew macros created as a result of adapting tw2 should be \nprepended \"__system\" to distinguish them from the actual used name\n*/\nvar sliceSeparator = \"::\";\nvar sectionSeparator = \"##\";\n\nfunction getsectionname(title) {\n\tif(!title)\n\t\treturn \"\";\n\tvar pos = title.indexOf(sectionSeparator);\n\tif(pos != -1) {\n\t\treturn title.substr(pos + sectionSeparator.length);\n\t}\n\treturn \"\";\n}\nfunction getslicename(title) { \n\tif(!title)\n\t\treturn \"\";\n\tvar pos = title.indexOf(sliceSeparator);\n\tif(pos != -1) {\n\t\treturn title.substr(pos + sliceSeparator.length);\n\t}\n\treturn \"\";\n};\nfunction gettiddlername(title) {\n\tif(!title)\n\t\treturn \"\";\n\tvar pos = title.indexOf(sectionSeparator);\n\n\tif(pos != -1) {\n\t\treturn title.substr(0,pos);\n\t}\n\tpos = title.indexOf(sliceSeparator);\n\tif(pos != -1) {\n\t\treturn title.substr(0,pos);\n\t}\n\treturn title;\n}\n\nvar parserparams = function(paramString) {\n\tvar params = [],\n\t\treParam = /\\s*(?:([A-Za-z0-9\\-_]+)\\s*:)?(?:\\s*(?:\"\"\"([\\s\\S]*?)\"\"\"|\"([^\"]*)\"|'([^']*)'|\\[\\[([^\\]]*)\\]\\]|([^\"'\\s]+)))/mg,\n\t\tparamMatch = reParam.exec(paramString);\n\twhile(paramMatch) {\n\t\t// Process this parameter\n\t\tvar paramInfo = {\n\t\t\tvalue: paramMatch[2] || paramMatch[3] || paramMatch[4] || paramMatch[5] || paramMatch[6]\n\t\t};\n\t\tif(paramMatch[1]) {\n\t\t\tparamInfo.name = paramMatch[1];\n\t\t}\n\t\tparams.push(paramInfo);\n\t\t// Find the next match\n\t\tparamMatch = reParam.exec(paramString);\n\t}\n\treturn params;\n}\nvar tabshandler = function(paramstring) {\n\tvar params = parserparams(paramstring);\n\tvar cookie = params[0].value;\n\tvar numTabs = (params.length-1)/3;\n\tvar t;\n\tvar tabslist = \"\";\n\tvar labelarray = {};\n    var promptarray = {};\n\tfor(t=0; t<numTabs; t++) {\n\t\tvar contentName = params[t*3+3].value;\n\t\ttabslist = tabslist+\" \" + contentName;\n\t\tlabelarray[contentName] = params[t*3+1].value;\n\t\tpromptarray[contentName] = params[t*3+2].value;\n\t} \n\t//Create a list of names (tiddlers, tiddler/sections, tiddler/slices), and create maps from name -> label and name -> prompt\n\t//Use json to implement maps \n\treturn '\"\"\"'+tabslist +'\"\"\" \"\"\"'+JSON.stringify(promptarray)+'\"\"\" \"\"\"'+JSON.stringify(labelarray)+'\"\"\" \"\"\"'+cookie+'\"\"\"';\n};\nvar namedapter = {tabs:'__system_tabs'};\nvar paramadapter = {\n\ttabs: tabshandler\n}\nexports.name = 'macroadapter';\nexports.namedapter = namedapter;\nexports.paramadapter = paramadapter;\n})();\n","type":"application/javascript","module-type":"module"},"$:/plugins/tiddlywiki/tw2parser/readme":{"title":"$:/plugins/tiddlywiki/tw2parser/readme","text":"This experimental plugin provides support for parsing and rendering tiddlers written in TiddlyWiki Classic format (`text/x-tiddlywiki`).\n\n[[Source code|https://github.com/TiddlyWiki/TiddlyWiki5/blob/master/plugins/tiddlywiki/tw2parser]]\n"},"$:/plugins/tiddlywiki/tw2parser/wikitextparser.js":{"title":"$:/plugins/tiddlywiki/tw2parser/wikitextparser.js","text":"/*\\\ntitle: $:/plugins/tiddlywiki/tw2parser/wikitextparser.js\ntype: application/javascript\nmodule-type: parser\n\nParses a block of tiddlywiki-format wiki text into a parse tree object. This is a transliterated version of the old TiddlyWiki code. The plan is to replace it with a new, mostly backwards compatible parser built in PEGJS.\n\nA wikitext parse tree is an array of objects with a `type` field that can be `text`,`macro` or the name of an HTML element.\n\nText nodes are represented as `{type: \"text\", value: \"A string of text\"}`.\n\nMacro nodes look like this:\n`\n{type: \"macro\", name: \"view\", params: {\n\tone: {type: \"eval\", value: \"2+2\"},\n\ttwo: {type: \"string\", value: \"twenty two\"}\n}}\n`\nHTML nodes look like this:\n`\n{type: \"div\", attributes: {\n\tsrc: \"one\"\n\tstyles: {\n\t\t\"background-color\": \"#fff\",\n\t\t\"color\": \"#000\"\n\t}\n}}\n`\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nCreates a new instance of the wiki text parser with the specified options. The\noptions are a hashmap of mandatory members as follows:\n\n\twiki: The wiki object to use to parse any cascaded content (eg transclusion)\n\nPlanned:\n\n\tenableRules: An array of names of wiki text rules to enable. If not specified, all rules are available\n\textraRules: An array of additional rule handlers to add\n\tenableMacros: An array of names of macros to enable. If not specified, all macros are available\n\textraMacros: An array of additional macro handlers to add\n*/\n\nvar WikiTextParser = function(type,text,options) {\n\tthis.wiki = options.wiki;\n\tthis.autoLinkWikiWords = true;\n\tthis.installRules();\n\ttext = text || \"no text\";\n\tthis.source = text;\n\tthis.nextMatch = 0;\n\tthis.children = [];\n\tthis.tree =[];\n\tthis.output = null;\n\tthis.subWikify(this.children);\n\t// prepend tw2 macros locally to the content\n\tvar parser = this.wiki.parseTiddler(\"$:/plugins/tiddlywiki/tw2parser/macrodefs\",{parseAsInline:false});\n\tthis.tree = [{\n\t\ttype: \"element\",\n\t\ttag: \"div\",\n\t\tchildren:this.children\n\t}];\n\t// clone the output of parser \n\tvar root = JSON.parse(JSON.stringify(parser.tree));\n\t// macros are defined in a linear tree; walk down the tree and append the source's parsed content \n\tvar baseroot = root;\n\twhile(root[0] && root[0].children && root[0].children.length !== 0 ){ \n\t\troot = root[0].children;\n\t}\n\troot[0].children[0] = this.tree[0];\n\tthis.tree = baseroot;\n};\n\n\nWikiTextParser.prototype.installRules = function() {\n\tvar rules = require(\"./wikitextrules.js\").rules,\n\t\tpattern = [];\n\tfor(var n=0; n<rules.length; n++) {\n\t\tpattern.push(\"(\" + rules[n].match + \")\");\n\t}\n\tthis.rules = rules;\n\tthis.rulesRegExp = new RegExp(pattern.join(\"|\"),\"mg\");\n};\n\n\nWikiTextParser.prototype.outputText = function(place,startPos,endPos) {\n\tif(startPos < endPos) {\n\t\tplace.push({type: \"text\",text:this.source.substring(startPos,endPos)});\n\t}\n};\n\nWikiTextParser.prototype.subWikify = function(output,terminator) {\n\t// Handle the terminated and unterminated cases separately, this speeds up wikifikation by about 30%\n\tif(terminator)\n\t\tthis.subWikifyTerm(output,new RegExp(\"(\" + terminator + \")\",\"mg\"));\n\telse\n\t\tthis.subWikifyUnterm(output);\n};\n\nWikiTextParser.prototype.subWikifyUnterm = function(output) {\n\t// subWikify can be indirectly recursive, so we need to save the old output pointer\n\tvar oldOutput = this.output;\n\tthis.output = output;\n\t// Get the first match\n\tthis.rulesRegExp.lastIndex = this.nextMatch;\n\tvar ruleMatch = this.rulesRegExp.exec(this.source);\n\twhile(ruleMatch) {\n\t\t// Output any text before the match\n\t\tif(ruleMatch.index > this.nextMatch)\n\t\t\tthis.outputText(this.output,this.nextMatch,ruleMatch.index);\n\t\t// Set the match parameters for the handler\n\t\tthis.matchStart = ruleMatch.index;\n\t\tthis.matchLength = ruleMatch[0].length;\n\t\tthis.matchText = ruleMatch[0];\n\t\tthis.nextMatch = this.rulesRegExp.lastIndex;\n\t\t// Figure out which rule matched and call its handler\n\t\tvar t;\n\t\tfor(t=1; t<ruleMatch.length; t++) {\n\t\t\tif(ruleMatch[t]) {\n\t\t\t\tthis.rules[t-1].handler(this);\n\t\t\t\tthis.rulesRegExp.lastIndex = this.nextMatch;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\t// Get the next match\n\t\truleMatch = this.rulesRegExp.exec(this.source);\n\t}\n\t// Output any text after the last match\n\tif(this.nextMatch < this.source.length) {\n\t\tthis.outputText(this.output,this.nextMatch,this.source.length);\n\t\tthis.nextMatch = this.source.length;\n\t}\n\t// Restore the output pointer\n\tthis.output = oldOutput;\n};\n\nWikiTextParser.prototype.subWikifyTerm = function(output,terminatorRegExp) {\n\t// subWikify can be indirectly recursive, so we need to save the old output pointer\n\tvar oldOutput = this.output;\n\tthis.output = output;\n\t// Get the first matches for the rule and terminator RegExps\n\tterminatorRegExp.lastIndex = this.nextMatch;\n\tvar terminatorMatch = terminatorRegExp.exec(this.source);\n\tthis.rulesRegExp.lastIndex = this.nextMatch;\n\tvar ruleMatch = this.rulesRegExp.exec(terminatorMatch ? this.source.substr(0,terminatorMatch.index) : this.source);\n\twhile(terminatorMatch || ruleMatch) {\n\t\t// Check for a terminator match before the next rule match\n\t\tif(terminatorMatch && (!ruleMatch || terminatorMatch.index <= ruleMatch.index)) {\n\t\t\t// Output any text before the match\n\t\t\tif(terminatorMatch.index > this.nextMatch)\n\t\t\t\tthis.outputText(this.output,this.nextMatch,terminatorMatch.index);\n\t\t\t// Set the match parameters\n\t\t\tthis.matchText = terminatorMatch[1];\n\t\t\tthis.matchLength = terminatorMatch[1].length;\n\t\t\tthis.matchStart = terminatorMatch.index;\n\t\t\tthis.nextMatch = this.matchStart + this.matchLength;\n\t\t\t// Restore the output pointer\n\t\t\tthis.output = oldOutput;\n\t\t\treturn;\n\t\t}\n\t\t// It must be a rule match; output any text before the match\n\t\tif(ruleMatch.index > this.nextMatch)\n\t\t\tthis.outputText(this.output,this.nextMatch,ruleMatch.index);\n\t\t// Set the match parameters\n\t\tthis.matchStart = ruleMatch.index;\n\t\tthis.matchLength = ruleMatch[0].length;\n\t\tthis.matchText = ruleMatch[0];\n\t\tthis.nextMatch = this.rulesRegExp.lastIndex;\n\t\t// Figure out which rule matched and call its handler\n\t\tvar t;\n\t\tfor(t=1; t<ruleMatch.length; t++) {\n\t\t\tif(ruleMatch[t]) {\n\t\t\t\tthis.rules[t-1].handler(this);\n\t\t\t\tthis.rulesRegExp.lastIndex = this.nextMatch;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\t// Get the next match\n\t\tterminatorRegExp.lastIndex = this.nextMatch;\n\t\tterminatorMatch = terminatorRegExp.exec(this.source);\n\t\truleMatch = this.rulesRegExp.exec(terminatorMatch ? this.source.substr(0,terminatorMatch.index) : this.source);\n\t}\n\t// Output any text after the last match\n\tif(this.nextMatch < this.source.length) {\n\t\tthis.outputText(this.output,this.nextMatch,this.source.length);\n\t\tthis.nextMatch = this.source.length;\n\t}\n\t// Restore the output pointer\n\tthis.output = oldOutput;\n};\n\nexports[\"text/x-tiddlywiki\"] = WikiTextParser;\n\n})();\n","type":"application/javascript","module-type":"parser"},"$:/plugins/tiddlywiki/tw2parser/wikitextrules.js":{"title":"$:/plugins/tiddlywiki/tw2parser/wikitextrules.js","text":"/*\\\ntitle: $:/plugins/tiddlywiki/tw2parser/wikitextrules.js\ntype: application/javascript\nmodule-type: module\n\nRule modules for the wikitext parser\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\nvar macroadapter = require(\"$:/macros/classic/macroadapter.js\");\nvar textPrimitives = {\n\tupperLetter: \"[A-Z\\u00c0-\\u00de\\u0150\\u0170]\",\n\tlowerLetter: \"[a-z0-9_\\\\-\\u00df-\\u00ff\\u0151\\u0171]\",\n\tanyLetter:   \"[A-Za-z0-9_\\\\-\\u00c0-\\u00de\\u00df-\\u00ff\\u0150\\u0170\\u0151\\u0171]\",\n\tanyLetterStrict: \"[A-Za-z0-9\\u00c0-\\u00de\\u00df-\\u00ff\\u0150\\u0170\\u0151\\u0171]\",\n\tsliceSeparator: \"::\",\n\tsectionSeparator: \"##\",\n\turlPattern: \"(?:file|http|https|mailto|ftp|irc|news|data):[^\\\\s'\\\"]+(?:/|\\\\b)\",\n\tunWikiLink: \"~\",\n\tbrackettedLink: \"\\\\[\\\\[([^\\\\]]+)\\\\]\\\\]\",\n\ttitledBrackettedLink: \"\\\\[\\\\[([^\\\\[\\\\]\\\\|]+)\\\\|([^\\\\[\\\\]\\\\|]+)\\\\]\\\\]\"\n};\n\ntextPrimitives.wikiLink = \"(?:(?:\" + textPrimitives.upperLetter + \"+\" +\n\t\t\t\t\t\t\ttextPrimitives.lowerLetter + \"+\" +\n\t\t\t\t\t\t\ttextPrimitives.upperLetter +\n\t\t\t\t\t\t\ttextPrimitives.anyLetter + \"*)|(?:\" +\n\t\t\t\t\t\t\ttextPrimitives.upperLetter + \"{2,}\" +\n\t\t\t\t\t\t\ttextPrimitives.lowerLetter + \"+))\";\n\ntextPrimitives.cssLookahead = \"(?:(\" + textPrimitives.anyLetter +\n\t\"+)\\\\(([^\\\\)\\\\|\\\\n]+)(?:\\\\):))|(?:(\" + textPrimitives.anyLetter + \"+):([^;\\\\|\\\\n]+);)\";\n\ntextPrimitives.cssLookaheadRegExp = new RegExp(textPrimitives.cssLookahead,\"mg\");\n\ntextPrimitives.tiddlerForcedLinkRegExp = new RegExp(\"(?:\" + textPrimitives.titledBrackettedLink + \")|(?:\" +\n\ttextPrimitives.brackettedLink + \")|(?:\" +\n\ttextPrimitives.urlPattern + \")\",\"mg\");\n\ntextPrimitives.tiddlerAnyLinkRegExp = new RegExp(\"(\"+ textPrimitives.wikiLink + \")|(?:\" +\n\ttextPrimitives.titledBrackettedLink + \")|(?:\" +\n\ttextPrimitives.brackettedLink + \")|(?:\" +\n\ttextPrimitives.urlPattern + \")\",\"mg\");\n\n// Helper to add an attribute to an HTML node\nvar setAttr = function(node,attr,value) {\n\tif(!node.attributes) {\n\t\tnode.attributes = {};\n\t}\n\tnode.attributes[attr] ={type: \"string\", value:value} ;\n};\n\nvar inlineCssHelper = function(w) {\n\tvar styles = [];\n\ttextPrimitives.cssLookaheadRegExp.lastIndex = w.nextMatch;\n\tvar lookaheadMatch = textPrimitives.cssLookaheadRegExp.exec(w.source);\n\twhile(lookaheadMatch && lookaheadMatch.index == w.nextMatch) {\n\t\tvar s,v;\n\t\tif(lookaheadMatch[1]) {\n\t\t\ts = lookaheadMatch[1];\n\t\t\tv = lookaheadMatch[2];\n\t\t} else {\n\t\t\ts = lookaheadMatch[3];\n\t\t\tv = lookaheadMatch[4];\n\t\t}\n\t\tif(s==\"bgcolor\")\n\t\t\ts = \"backgroundColor\";\n\t\tif(s==\"float\")\n\t\t\ts = \"cssFloat\";\n\t\tstyles.push({style: s, value: v});\n\t\tw.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;\n\t\ttextPrimitives.cssLookaheadRegExp.lastIndex = w.nextMatch;\n\t\tlookaheadMatch = textPrimitives.cssLookaheadRegExp.exec(w.source);\n\t}\n\treturn styles;\n};\n\nvar applyCssHelper = function(e,styles) {\n\n\tif(styles.length > 0) {\n\n\t\tfor(var t=0; t< styles.length; t++) {\n\t\t\t$tw.utils.addStyleToParseTreeNode(e,$tw.utils.roundTripPropertyName(styles[t].style),styles[t].value);\n\t\t}\n\t}\n\t\n};\n\nvar enclosedTextHelper = function(w) {\n\tthis.lookaheadRegExp.lastIndex = w.matchStart;\n\tvar lookaheadMatch = this.lookaheadRegExp.exec(w.source);\n\tif(lookaheadMatch && lookaheadMatch.index == w.matchStart) {\n\t\tvar text = lookaheadMatch[1];\n\t\tw.output.push({type:\"element\",tag:this.element,\n\t\t\tchildren:[{type: \"text\",text: lookaheadMatch[1]}]});\n\t\tw.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;\n\t}\n};\n\nvar insertMacroCall = function(w,output,macroName,paramString) {\n\tvar params = [],\n\t\treParam = /\\s*(?:([A-Za-z0-9\\-_]+)\\s*:)?(?:\\s*(?:\"\"\"([\\s\\S]*?)\"\"\"|\"([^\"]*)\"|'([^']*)'|\\[\\[([^\\]]*)\\]\\]|([^\"'\\s]+)))/mg,\n\t\tparamMatch = reParam.exec(paramString);\n\twhile(paramMatch) {\n\t\t// Process this parameter\n\t\tvar paramInfo = {\n\t\t\tvalue: paramMatch[2] || paramMatch[3] || paramMatch[4] || paramMatch[5] || paramMatch[6]\n\t\t};\n\t\tif(paramMatch[1]) {\n\t\t\tparamInfo.name = paramMatch[1];\n\t\t}\n\t\tparams.push(paramInfo);\n\t\t// Find the next match\n\t\tparamMatch = reParam.exec(paramString);\n\t}\n\toutput.push({\n\t\ttype: \"macrocall\",\n\t\tname: macroName,\n\t\tparams: params,\n\t\tisBlock: false\n\t});\n}\n\n\nvar isLinkExternal = function(to) {\n\tvar externalRegExp = /(?:file|http|https|mailto|ftp|irc|news|obsidian|data|skype):[^\\s'\"]+(?:\\/|\\b)/i;\n\treturn externalRegExp.test(to);\n};\nvar rules = [\n{\n\tname: \"table\",\n\tmatch: \"^\\\\|(?:[^\\\\n]*)\\\\|(?:[fhck]?)$\",\n\tlookaheadRegExp: /^\\|([^\\n]*)\\|([fhck]?)$/mg,\n\trowTermRegExp: /(\\|(?:[fhck]?)$\\n?)/mg,\n\tcellRegExp: /(?:\\|([^\\n\\|]*)\\|)|(\\|[fhck]?$\\n?)/mg,\n\tcellTermRegExp: /((?:\\x20*)\\|)/mg,\n\trowTypes: {\"c\":\"caption\", \"h\":\"thead\", \"\":\"tbody\", \"f\":\"tfoot\"},\n\thandler: function(w)\n\t{\n\t\tvar table = {type:\"element\",tag:\"table\",attributes: {\"class\": {type: \"string\", value:\"table\"}},\n\t\t\t\t\tchildren: []};\n\t\t\n\t\tw.output.push(table);\n\t\tvar prevColumns = [];\n\t\tvar currRowType = null;\n\t\tvar rowContainer;\n\t\tvar rowCount = 0;\n\t\tw.nextMatch = w.matchStart;\n\t\tthis.lookaheadRegExp.lastIndex = w.nextMatch;\n\t\tvar lookaheadMatch = this.lookaheadRegExp.exec(w.source);\n\t\twhile(lookaheadMatch && lookaheadMatch.index == w.nextMatch) {\n\t\t\tvar nextRowType = lookaheadMatch[2];\n\t\t\tif(nextRowType == \"k\") {\n\t\t\t\ttable.attributes[\"class\"] = lookaheadMatch[1];\n\t\t\t\tw.nextMatch += lookaheadMatch[0].length+1;\n\t\t\t} else {\n\t\t\t\tif(nextRowType != currRowType) {\n\t\t\t\t\trowContainer = {type:\"element\",tag:this.rowTypes[nextRowType],children: []};\n\t\t\t\t\ttable.children.push(rowContainer);\n\t\t\t\t\tcurrRowType = nextRowType;\n\t\t\t\t}\n\t\t\t\tif(currRowType == \"c\") {\n\t\t\t\t\t// Caption\n\t\t\t\t\tw.nextMatch++;\n\t\t\t\t\t// Move the caption to the first row if it isn't already\n\t\t\t\t\tif(table.children.length !== 1) {\n\t\t\t\t\t\ttable.children.pop(); // Take rowContainer out of the children array\n\t\t\t\t\t\ttable.children.splice(0,0,rowContainer); // Insert it at the bottom\t\t\t\t\t\t\n\t\t\t\t\t}\n\t\t\t\t\trowContainer.attributes={};\n\t\t\t\t\trowContainer.attributes.align = rowCount === 0 ? \"top\" : \"bottom\";\n\t\t\t\t\tw.subWikifyTerm(rowContainer.children,this.rowTermRegExp);\n\t\t\t\t} else {\n\t\t\t\t\tvar theRow = {type:\"element\",tag:\"tr\",\n\t\t\t\t\t\tattributes: {\"class\": {type: \"string\", value:rowCount%2 ? \"oddRow\" : \"evenRow\"}},\n\t\t\t\t\t\tchildren: []};\n\t\t\t\t\t\n\t\t\t\t\trowContainer.children.push(theRow);\n\t\t\t\t\tthis.rowHandler(w,theRow.children,prevColumns);\n\t\t\t\t\trowCount++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.lookaheadRegExp.lastIndex = w.nextMatch;\n\t\t\tlookaheadMatch = this.lookaheadRegExp.exec(w.source);\n\t\t}\n\t},\n\trowHandler: function(w,e,prevColumns)\n\t{\n\t\tvar col = 0;\n\t\tvar colSpanCount = 1;\n\t\tvar prevCell = null;\n\t\tthis.cellRegExp.lastIndex = w.nextMatch;\n\t\tvar cellMatch = this.cellRegExp.exec(w.source);\n\t\twhile(cellMatch && cellMatch.index == w.nextMatch) {\n\t\t\tif(cellMatch[1] == \"~\") {\n\t\t\t\t// Rowspan\n\t\t\t\tvar last = prevColumns[col];\n\t\t\tif(last) {\n\t\t\t\tlast.rowSpanCount++;\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(last.element,\"rowspan\",last.rowSpanCount);\n\t\t\t\tvar vAlign = $tw.utils.getAttributeValueFromParseTreeNode(last.element,\"valign\",\"center\");\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(last.element,\"valign\",vAlign);\n\t\t\t\tif(colSpanCount > 1) {\n\t\t\t\t\t$tw.utils.addAttributeToParseTreeNode(last.element,\"colspan\",colSpanCount);\n\t\t\t\t\tcolSpanCount = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\tw.nextMatch = this.cellRegExp.lastIndex-1;\n\t\t\t} else if(cellMatch[1] == \">\") {\n\t\t\t\t// Colspan\n\t\t\t\tcolSpanCount++;\n\t\t\t\tw.nextMatch = this.cellRegExp.lastIndex-1;\n\t\t\t} else if(cellMatch[2]) {\n\t\t\t\t// End of row\n\t\t\t\tif(prevCell && colSpanCount > 1) {\n\t\t\t\t\tprevCell.attributes.colspan = colSpanCount;\n\t\t\t\t}\n\t\t\t\tw.nextMatch = this.cellRegExp.lastIndex;\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\t// Cell\n\t\t\t\tw.nextMatch++;\n\t\t\t\tvar styles = inlineCssHelper(w);\n\t\t\t\tvar spaceLeft = false;\n\t\t\t\tvar chr = w.source.substr(w.nextMatch,1);\n\t\t\t\twhile(chr == \" \") {\n\t\t\t\t\tspaceLeft = true;\n\t\t\t\t\tw.nextMatch++;\n\t\t\t\t\tchr = w.source.substr(w.nextMatch,1);\n\t\t\t\t}\n\t\t\t\tvar cell;\n\t\t\t\tif(chr == \"!\") {\n\t\t\t\t\tcell = {type:\"element\",tag:\"th\",children: []};\n\t\t\t\t\te.push(cell);\n\t\t\t\t\tw.nextMatch++;\n\t\t\t\t} else {\n\t\t\t\t\tcell = {type:\"element\",tag:\"td\",children: []};\n\t\t\t\t\te.push(cell);\n\t\t\t\t}\n\t\t\t\tprevCell = cell;\n\t\t\t\tprevColumns[col] = {rowSpanCount:1,element:cell};\n\t\t\t\tif(colSpanCount > 1) {\n\t\t\t\t\t$tw.utils.addAttributeToParseTreeNode(cell,\"colspan\",colSpanCount);\n\t\t\t\t\tcolSpanCount = 1;\n\t\t\t\t}\n\t\t\t\tapplyCssHelper(cell,styles);\n\t\t\t\tw.subWikifyTerm(cell.children,this.cellTermRegExp);\n\t\t\t\tif(!cell.attributes) cell.attributes ={};\n\t\t\t\tif(w.matchText.substr(w.matchText.length-2,1) == \" \") // spaceRight\n\t\t\t\t\t$tw.utils.addAttributeToParseTreeNode(cell,\"align\",spaceLeft ? \"center\" : \"left\");\n\t\t\t\telse if(spaceLeft)\n\t\t\t\t\t$tw.utils.addAttributeToParseTreeNode(cell,\"align\",\"right\");\n\t\t\t\tw.nextMatch--;\n\t\t\t}\n\t\t\tcol++;\n\t\t\tthis.cellRegExp.lastIndex = w.nextMatch;\n\t\t\tcellMatch = this.cellRegExp.exec(w.source);\n\t\t}\n\t}\n},\n\n{\n\tname: \"heading\",\n\tmatch: \"^!{1,6}\",\n\ttermRegExp: /(\\n)/mg,\n\thandler: function(w)\n\t{\n\t\tvar e = {type:\"element\",tag:\"h\" + w.matchLength,children: []};\n\t\tw.output.push(e);\n\t\tw.subWikifyTerm(e.children,this.termRegExp);\n\t}\n},\n\n{\n\tname: \"list\",\n\tmatch: \"^(?:[\\\\*#;:]+)\",\n\tlookaheadRegExp: /^(?:(?:(\\*)|(#)|(;)|(:))+)/mg,\n\ttermRegExp: /(\\n)/mg,\n\thandler: function(w)\n\t{\n\t\tvar stack = [w.output];\n\t\tvar currLevel = 0, currType = null;\n\t\tvar listLevel, listType, itemType, baseType;\n\t\tw.nextMatch = w.matchStart;\n\t\tthis.lookaheadRegExp.lastIndex = w.nextMatch;\n\t\tvar lookaheadMatch = this.lookaheadRegExp.exec(w.source);\n\t\twhile(lookaheadMatch && lookaheadMatch.index == w.nextMatch) {\n\t\t\tif(lookaheadMatch[1]) {\n\t\t\t\tlistType = \"ul\";\n\t\t\t\titemType = \"li\";\n\t\t\t} else if(lookaheadMatch[2]) {\n\t\t\t\tlistType = \"ol\";\n\t\t\t\titemType = \"li\";\n\t\t\t} else if(lookaheadMatch[3]) {\n\t\t\t\tlistType = \"dl\";\n\t\t\t\titemType = \"dt\";\n\t\t\t} else if(lookaheadMatch[4]) {\n\t\t\t\tlistType = \"dl\";\n\t\t\t\titemType = \"dd\";\n\t\t\t}\n\t\t\tif(!baseType)\n\t\t\t\tbaseType = listType;\n\t\t\tlistLevel = lookaheadMatch[0].length;\n\t\t\tw.nextMatch += lookaheadMatch[0].length;\n\t\t\tvar t,e;\n\t\t\tif(listLevel > currLevel) {\n\t\t\t\tfor(t=currLevel; t<listLevel; t++) {\n\t\t\t\t\tvar target = stack[stack.length-1];\n\t\t\t\t\tif(currLevel !== 0 && target.children) {\n\t\t\t\t\t\ttarget = target.children[target.children.length-1];\n\t\t\t\t\t}\n\t\t\t\t\te = {type:\"element\",tag:listType,children: []};\n\t\t\t\t\ttarget.push(e);\n\t\t\t\t\tstack.push(e.children);\n\t\t\t\t}\n\t\t\t} else if(listType!=baseType && listLevel==1) {\n\t\t\t\tw.nextMatch -= lookaheadMatch[0].length;\n\t\t\t\treturn;\n\t\t\t} else if(listLevel < currLevel) {\n\t\t\t\tfor(t=currLevel; t>listLevel; t--)\n\t\t\t\t\tstack.pop();\n\t\t\t} else if(listLevel == currLevel && listType != currType) {\n\t\t\t\tstack.pop();\n\t\t\t\te = {type:\"element\",tag:listType,children: []};\n\t\t\t\tstack[stack.length-1].push(e);\n\t\t\t\tstack.push(e.children);\n\t\t\t}\n\t\t\tcurrLevel = listLevel;\n\t\t\tcurrType = listType;\n\t\t\te = {type:\"element\",tag:itemType,children: []};\n\t\t\tstack[stack.length-1].push(e);\n\t\t\tw.subWikifyTerm(e.children,this.termRegExp);\n\t\t\tthis.lookaheadRegExp.lastIndex = w.nextMatch;\n\t\t\tlookaheadMatch = this.lookaheadRegExp.exec(w.source);\n\t\t}\n\t}\n},\n\n{\n\tname: \"quoteByBlock\",\n\tmatch: \"^<<<\\\\n\",\n\ttermRegExp: /(^<<<(\\n|$))/mg,\n\telement: \"blockquote\",\n\thandler:  function(w) {\n\t\tvar e = {type:\"element\",tag:this.element,children: []};\n\t\tw.output.push(e);\n\t\tw.subWikifyTerm(e.children,this.termRegExp);\n\t}\n},\n\n{\n\tname: \"quoteByLine\",\n\tmatch: \"^>+\",\n\tlookaheadRegExp: /^>+/mg,\n\ttermRegExp: /(\\n)/mg,\n\telement: \"blockquote\",\n\thandler: function(w)\n\t{\n\t\tvar stack = [];\n\t\tvar currLevel = 0;\n\t\tvar newLevel = w.matchLength;\n\t\tvar t,matched,e;\n\t\tdo {\n\t\t\tif(newLevel > currLevel) {\n\t\t\t\tfor(t=currLevel; t<newLevel; t++) {\n\t\t\t\t\tvar f = stack[stack.length-1];\n\t\t\t\t\te = {type:\"element\",tag:this.element,children: []};\n\t\t\t\t\tstack.push(e);\n\t\t\t\t\tif(t ===0){\n\t\t\t\t\t\tw.output.push(e);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tf.children.push(e);\n\t\t\t\t\t\t\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if(newLevel < currLevel) {\n\t\t\t\tfor(t=currLevel; t>newLevel; t--)\n\t\t\t\t\tstack.pop();\n\t\t\t}\n\t\t\tcurrLevel = newLevel;\n\t\t\tw.subWikifyTerm(stack[stack.length-1].children,this.termRegExp);\n\t\t\tstack[stack.length-1].children.push({type:\"element\",tag:\"br\"});\n\t\t\t//e.push({type:\"element\",tag:\"br\"});\n\n\t\t\tthis.lookaheadRegExp.lastIndex = w.nextMatch;\n\t\t\tvar lookaheadMatch = this.lookaheadRegExp.exec(w.source);\n\t\t\tmatched = lookaheadMatch && lookaheadMatch.index == w.nextMatch;\n\t\t\tif(matched) {\n\t\t\t\tnewLevel = lookaheadMatch[0].length;\n\t\t\t\tw.nextMatch += lookaheadMatch[0].length;\n\t\t\t}\n\t\t} while(matched);\n\t}\n},\n\n{\n\tname: \"rule\",\n\tmatch: \"^----+$\\\\n?|<hr ?/?>\\\\n?\",\n\thandler: function(w)\n\t{\n\t\tw.output.push({type:\"element\",tag:\"hr\"});\n\t}\n},\n\n{\n\tname: \"monospacedByLine\",\n\tmatch: \"^(?:/\\\\*\\\\{\\\\{\\\\{\\\\*/|\\\\{\\\\{\\\\{|//\\\\{\\\\{\\\\{|<!--\\\\{\\\\{\\\\{-->)\\\\n\",\n\telement: \"pre\",\n\thandler: function(w)\n\t{\n\t\tswitch(w.matchText) {\n\t\tcase \"/*{{{*/\\n\": // CSS\n\t\t\tthis.lookaheadRegExp = /\\/\\*\\{\\{\\{\\*\\/\\n*((?:^[^\\n]*\\n)+?)(\\n*^\\f*\\/\\*\\}\\}\\}\\*\\/$\\n?)/mg;\n\t\t\tbreak;\n\t\tcase \"{{{\\n\": // monospaced block\n\t\t\tthis.lookaheadRegExp = /^\\{\\{\\{\\n((?:^[^\\n]*\\n)+?)(^\\f*\\}\\}\\}$\\n?)/mg;\n\t\t\tbreak;\n\t\tcase \"//{{{\\n\": // plugin\n\t\t\tthis.lookaheadRegExp = /^\\/\\/\\{\\{\\{\\n\\n*((?:^[^\\n]*\\n)+?)(\\n*^\\f*\\/\\/\\}\\}\\}$\\n?)/mg;\n\t\t\tbreak;\n\t\tcase \"<!--{{{-->\\n\": //template\n\t\t\tthis.lookaheadRegExp = /<!--\\{\\{\\{-->\\n*((?:^[^\\n]*\\n)+?)(\\n*^\\f*<!--\\}\\}\\}-->$\\n?)/mg;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t\tenclosedTextHelper.call(this,w);\n\t}\n},\n\n{\n\tname: \"typedBlock\",\n\t\tmatch: \"^\\\\$\\\\$\\\\$(?:[^ >\\\\r\\\\n]*)\\\\r?\\\\n\",\n\tlookaheadRegExp: /^\\$\\$\\$([^ >\\r\\n]*)\\n((?:^[^\\n]*\\r?\\n)+?)(^\\f*\\$\\$\\$\\r?\\n?)/mg,\n\t//match: \"^\\\\$\\\\$\\\\$(?:[^ >\\\\r\\\\n]*)(?: *> *([^ \\\\r\\\\n]+))?\\\\r?\\\\n\",\n\t//lookaheadRegExp: /^\\$\\$\\$([^ >\\r\\n]*)(?: *> *([^ \\r\\n]+))\\n((?:^[^\\n]*\\n)+?)(^\\f*\\$\\$\\$$\\n?)/mg,\n\thandler: function(w)\n\t{\n\t\tthis.lookaheadRegExp.lastIndex = w.matchStart;\n\t\tvar lookaheadMatch = this.lookaheadRegExp.exec(w.source);\n\t\tif(lookaheadMatch && lookaheadMatch.index == w.matchStart) {\n\t\t\t// The wikitext parsing infrastructure is horribly unre-entrant\n\t\t\tvar parseType = lookaheadMatch[1],\n\t\t\t\trenderType ,//= this.match[2],\n\t\t\t\ttext = lookaheadMatch[2],\n\t\t\t\toldOutput = w.output,\n\t\t\t\toldSource = w.source,\n\t\t\t\toldNextMatch = w.nextMatch,\n\t\t\t\toldChildren = w.children;\n\t\t\t// Parse the block according to the specified type\n\t\t\tvar parser = $tw.wiki.parseText(parseType,text.toString(),{defaultType: \"text/plain\"});\n\n\t\t\tw.output = oldOutput;\n\t\t\tw.source = oldSource;\n\t\t\tw.nextMatch = oldNextMatch;\n\t\t\tw.children = oldChildren;\n\t\t\tfor(var i=0; i<parser.tree.length; i++) {\n\t\t\t\tw.output.push(parser.tree[i]);\n\t\t\t}\n\t\t\tw.nextMatch = this.lookaheadRegExp.lastIndex;\n\t\t}\n\t}\n},\n\n{\n\tname: \"wikifyComment\",\n\tmatch: \"^(?:/\\\\*\\\\*\\\\*|<!---)\\\\n\",\n\thandler: function(w)\n\t{\n\t\tvar termRegExp = (w.matchText == \"/***\\n\") ? (/(^\\*\\*\\*\\/\\n)/mg) : (/(^--->\\n)/mg);\n\t\tw.subWikifyTerm(w.output,termRegExp);\n\t}\n},\n\n{\n\tname: \"macro\",\n\tmatch: \"<<\",\n\tlookaheadRegExp: /<<(?:([!@£\\$%\\^\\&\\*\\(\\)`\\~'\"\\|\\\\\\/;\\:\\.\\,\\+\\=\\-\\_\\{\\}])|([^>\\s]+))(?:\\s*)((?:[^>]|(?:>(?!>)))*)>>/mg,\n\thandler: function(w)\n\t{\n\t\tthis.lookaheadRegExp.lastIndex = w.matchStart;\n\t\tvar lookaheadMatch = this.lookaheadRegExp.exec(w.source),\n\t\t\tname;\n\t\tif(lookaheadMatch && lookaheadMatch.index == w.matchStart) {\n\t\t\tname = lookaheadMatch[1] || lookaheadMatch[2];\n\t\t\tvar params = lookaheadMatch[3], nameold =name;\n\t\t\tif(name) {\n\t\t\t\tif(!!macroadapter.paramadapter[name]) {\n\t\t\t\t\tparams=macroadapter.paramadapter[name](params);\n\t\t\t\t\t//alert(\"going out as \"+params);\n\t\t\t\t}\n\t\t\t\tif(!!macroadapter.namedapter[name]) {\n\t\t\t\t\tname=macroadapter.namedapter[name];\n\t\t\t\t}\n\t\t\t\tw.nextMatch = this.lookaheadRegExp.lastIndex;\n\t\t\t\tinsertMacroCall(w,w.output,name,params);\n\t\t\t}\n\t\t}\n\t}\n},\n\n\n{\n\tname: \"prettyLink\",\n\tmatch: \"\\\\[\\\\[\",\n\tlookaheadRegExp: /\\[\\[(.*?)(?:\\|(~)?(.*?))?\\]\\]/mg,\n\thandler: function(w)\n\t{\n\t\tthis.lookaheadRegExp.lastIndex = w.matchStart;\n\t\tvar lookaheadMatch = this.lookaheadRegExp.exec(w.source);\n\t\tif(lookaheadMatch && lookaheadMatch.index == w.matchStart) {\n\t\t\tvar text = lookaheadMatch[1],\n\t\t\t\tlink = text;\n\t\t\tif(lookaheadMatch[3]) {\n\t\t\t\t// Pretty bracketted link\n\t\t\t\tlink = lookaheadMatch[3];\n\t\t\t}\n\tif(isLinkExternal(link)) {\n\t\tw.output.push({\n\t\t\ttype: \"element\",\n\t\t\ttag: \"a\",\n\t\t\tattributes: {\n\t\t\t\thref: {type: \"string\", value: link},\n\t\t\t\t\"class\": {type: \"string\", value: \"tc-tiddlylink-external\"},\n\t\t\t\ttarget: {type: \"string\", value: \"_blank\"}\n\t\t\t},\n\t\t\tchildren: [{\n\t\t\t\ttype: \"text\", text: text\n\t\t\t}]\n\t\t});\n\t} else {\n\t\tw.output.push({\n\t\t\ttype: \"link\",\n\t\t\tattributes: {\n\t\t\t\tto: {type: \"string\", value: link}\n\t\t\t},\n\t\t\tchildren: [{\n\t\t\t\ttype: \"text\", text: text\n\t\t\t}]\n\t\t});\n\t}\n\n\t\t\tw.nextMatch = this.lookaheadRegExp.lastIndex;\n\t\t}\n\t}\n},\n{\n\tname: \"wikiLink\",\n\tmatch: textPrimitives.unWikiLink+\"?\"+textPrimitives.wikiLink,\n\thandler: function(w)\n\t{\n\t\tif(w.matchText.substr(0,1) == textPrimitives.unWikiLink) {\n\t\t\tw.outputText(w.output,w.matchStart+1,w.nextMatch);\n\t\t\treturn;\n\t\t}\n\t\tif(w.matchStart > 0) {\n\t\t\tvar preRegExp = new RegExp(textPrimitives.anyLetterStrict,\"mg\");\n\t\t\tpreRegExp.lastIndex = w.matchStart-1;\n\t\t\tvar preMatch = preRegExp.exec(w.source);\n\t\t\tif(preMatch.index == w.matchStart-1) {\n\t\t\t\tw.outputText(w.output,w.matchStart,w.nextMatch);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tif(w.autoLinkWikiWords) {\n\t\t\tw.output.push({\n\t\t\t\ttype: \"link\",\n\t\t\t\tattributes: {\n\t\t\t\t\tto: {type: \"string\", value: w.matchText}\n\t\t\t\t},\n\t\t\t\tchildren: [{\n\t\t\t\t\ttype: \"text\",\n\t\t\t\t\ttext: w.source.substring(w.matchStart,w.nextMatch)\n\t\t\t\t}]\n\t\t\t});\n\t\t} else {\t\n\t\t\tw.outputText(w.output,w.matchStart,w.nextMatch);\n\t\t}\n\t}\n},\n\n{\n\tname: \"urlLink\",\n\tmatch: textPrimitives.urlPattern,\n\thandler: function(w)\n\t{\n\t\t\tw.output.push({\n\t\t\ttype: \"element\",\n\t\t\ttag: \"a\",\n\t\t\tattributes: {\n\t\t\t\thref: {type: \"string\", value: w.matchText},\n\t\t\t\t\"class\": {type: \"string\", value: \"tc-tiddlylink-external\"},\n\t\t\t\ttarget: {type: \"string\", value: \"_blank\"}\n\t\t\t},\n\t\t\tchildren: [{\n\t\t\t\ttype: \"text\", text: w.source.substring(w.matchStart,w.nextMatch)\n\t\t\t}]\n\t\t});\n\n\t}\n},\n\n{\n\tname: \"image\",\n\tmatch: \"\\\\[[<>]?[Ii][Mm][Gg]\\\\[\",\n\t// [<] sequence below is to avoid lessThan-questionMark sequence so TiddlyWikis can be included in PHP files\n\tlookaheadRegExp: /\\[([<]?)(>?)[Ii][Mm][Gg]\\[(?:([^\\|\\]]+)\\|)?([^\\[\\]\\|]+)\\](?:\\[([^\\]]*)\\])?\\]/mg,\n\thandler: function(w)\n\t{\n\t\tvar node = {\n\t\t\ttype: \"image\",\n\t\t\tattributes: {}\n\t\t};\n\t\tthis.lookaheadRegExp.lastIndex = w.matchStart;\n\t\tvar lookaheadMatch = this.lookaheadRegExp.exec(w.source),\n\t\t\timageParams = {},\n\t\t\tlinkParams = {};\n\t\tif(lookaheadMatch && lookaheadMatch.index == w.matchStart) {\n\t\t\tif(lookaheadMatch[1]) {\n\t\t\t\tnode.attributes.class = {type: \"string\", value: \"classic-image-left\"};\n\t\t\t} else if(lookaheadMatch[2]) {\n\t\t\t\tnode.attributes.class  = {type: \"string\", value: \"classic-image-right\"};\n\t\t\t}\n\t\t\tif(lookaheadMatch[3]) {\n\t\t\t\tnode.attributes.tooltip = {type: \"string\", value: lookaheadMatch[3]};\n\t\t\t}\n\t\t\tnode.attributes.source = {type: \"string\", value: lookaheadMatch[4]};\n\t\t\tif(lookaheadMatch[5]) {\n\t\t\t\tif(isLinkExternal(lookaheadMatch[5])) {\n\t\t\t\t\tw.output.push({\n\t\t\t\t\t\ttype: \"element\",\n\t\t\t\t\t\ttag: \"a\",\n\t\t\t\t\t\tattributes: {\n\t\t\t\t\t\t\thref: {type: \"string\", value:lookaheadMatch[5]},\n\t\t\t\t\t\t\t\"class\": {type: \"string\", value: \"tc-tiddlylink-external\"},\n\t\t\t\t\t\t\ttarget: {type: \"string\", value: \"_blank\"}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tchildren: [node]\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tw.output.push({\n\t\t\t\t\t\ttype: \"link\",\n\t\t\t\t\t\tattributes: {\n\t\t\t\t\t\t\tto: {type: \"string\", value: lookaheadMatch[5]}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tchildren: [node]\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tw.output.push(node);\n\t\t\t}\n\t\t\tw.nextMatch = this.lookaheadRegExp.lastIndex;\n\t\t}\n\t}\n},\n\n{\n\tname: \"html\",\n\tmatch: \"<[Hh][Tt][Mm][Ll]>\",\n\tlookaheadRegExp: /<[Hh][Tt][Mm][Ll]>((?:.|\\n)*?)<\\/[Hh][Tt][Mm][Ll]>/mg,\n\thandler: function(w)\n\t{\n\t\tthis.lookaheadRegExp.lastIndex = w.matchStart;\n\t\tvar lookaheadMatch = this.lookaheadRegExp.exec(w.source);\n\t\tif(lookaheadMatch && lookaheadMatch.index == w.matchStart) {\n\t\t\tw.output.push({\ttype:\"raw\", html:lookaheadMatch[1]});\n\t\t\tw.nextMatch = this.lookaheadRegExp.lastIndex;\n\t\t}\n\t}\n},\n\n{\n\tname: \"commentByBlock\",\n\tmatch: \"/%\",\n\tlookaheadRegExp: /\\/%((?:.|\\n)*?)%\\//mg,\n\thandler: function(w)\n\t{\n\t\tthis.lookaheadRegExp.lastIndex = w.matchStart;\n\t\tvar lookaheadMatch = this.lookaheadRegExp.exec(w.source);\n\t\tif(lookaheadMatch && lookaheadMatch.index == w.matchStart)\n\t\t\tw.nextMatch = this.lookaheadRegExp.lastIndex;\n\t}\n},\n\n{\n\tname: \"characterFormat\",\n\tmatch: \"''|//|__|\\\\^\\\\^|~~|--(?!\\\\s|$)|\\\\{\\\\{\\\\{|`\",\n\thandler: function(w)\n\t{\n\t\tvar e,lookaheadRegExp,lookaheadMatch;\n\t\tswitch(w.matchText) {\n\t\tcase \"''\":\n\t\t\te = {type:\"element\",tag:\"strong\",children: []};\n\t\t\tw.output.push(e);\n\t\t\tw.subWikifyTerm(e.children,/('')/mg);\n\t\t\tbreak;\n\t\tcase \"//\":\n\t\t\te = {type:\"element\",tag:\"em\",children: []};\n\t\t\tw.output.push(e);\n\t\t\tw.subWikifyTerm(e.children,/(\\/\\/)/mg);\n\t\t\tbreak;\n\t\tcase \"__\":\n\t\t\te = {type:\"element\",tag:\"u\",children: []};\n\t\t\tw.output.push(e);\n\t\t\tw.subWikifyTerm(e.children,/(__)/mg);\n\t\t\tbreak;\n\t\tcase \"^^\":\n\t\t\te = {type:\"element\",tag:\"sup\",children: []};\n\t\t\tw.output.push(e);\n\t\t\tw.subWikifyTerm(e.children,/(\\^\\^)/mg);\n\t\t\tbreak;\n\t\tcase \"~~\":\n\t\t\te = {type:\"element\",tag:\"sub\",children: []};\n\t\t\tw.output.push(e);\n\t\t\tw.subWikifyTerm(e.children,/(~~)/mg);\n\t\t\tbreak;\n\t\tcase \"--\":\n\t\t\te = {type:\"element\",tag:\"strike\",children: []};\n\t\t\tw.output.push(e);\n\t\t\tw.subWikifyTerm(e.children,/(--)/mg);\n\t\t\tbreak;\n\t\tcase \"`\":\n\t\t\tlookaheadRegExp = /`((?:.|\\n)*?)`/mg;\n\t\t\tlookaheadRegExp.lastIndex = w.matchStart;\n\t\t\tlookaheadMatch = lookaheadRegExp.exec(w.source);\n\t\t\tif(lookaheadMatch && lookaheadMatch.index == w.matchStart) {\n\t\t\t\tw.output.push({type:\"element\",tag:\"code\",\n\t\t\t\t\tchildren:[{type: \"text\",text: lookaheadMatch[1]}]});\n\t\t\t}\n\t\t\tbreak;\n\t\tcase \"{{{\":\n\t\t\tlookaheadRegExp = /\\{\\{\\{((?:.|\\n)*?)\\}\\}\\}/mg;\n\t\t\tlookaheadRegExp.lastIndex = w.matchStart;\n\t\t\tlookaheadMatch = lookaheadRegExp.exec(w.source);\n\t\t\tif(lookaheadMatch && lookaheadMatch.index == w.matchStart) {\n\t\t\t\tw.output.push({type:\"element\",tag:\"code\",\n\t\t\t\t\tchildren:[{type: \"text\",text: lookaheadMatch[1]}]});\n\t\t\t\tw.nextMatch = lookaheadRegExp.lastIndex;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t}\n},\n\n{\n\tname: \"customFormat\",\n\tmatch: \"@@|\\\\{\\\\{\",\n\thandler: function(w)\n\t{\n\t\tswitch(w.matchText) {\n\t\tcase \"@@\":\n\t\t\tvar e = {type:\"element\",tag:\"span\",children: []};\n\t\t\tw.output.push(e);\n\t\t\tvar styles = inlineCssHelper(w);\n\t\t\tif(styles.length === 0)\n\t\t\t\tsetAttr(e,\"class\",\"marked\");\n\t\t\telse\n\t\t\t\tapplyCssHelper(e,styles);\n\t\t\tw.subWikifyTerm(e.children,/(@@)/mg);\n\t\t\tbreak;\n\t\tcase \"{{\":\n\t\t\tvar lookaheadRegExp = /\\{\\{[\\s]*([\\-\\w]+[\\-\\s\\w]*)[\\s]*\\{(\\n?)/mg;\n\t\t\tlookaheadRegExp.lastIndex = w.matchStart;\n\t\t\tvar lookaheadMatch = lookaheadRegExp.exec(w.source);\n\t\t\tif(lookaheadMatch) {\n\t\t\t\tw.nextMatch = lookaheadRegExp.lastIndex;\n\t\t\t\te = {type:\"element\",tag:lookaheadMatch[2] == \"\\n\" ? \"div\" : \"span\",\n\t\t\t\t\tattributes: {\"class\": {type: \"string\", value:lookaheadMatch[1]}},children: []};\n\t\t\t\tw.output.push(e);\n\t\t\t\tw.subWikifyTerm(e.children,/(\\}\\}\\})/mg);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t}\n},\n\n{\n\tname: \"mdash\",\n\tmatch: \"--\",\n\thandler: function(w)\n\t{\n\t\tw.output.push({type: \"entity\", entity: \"&mdash;\"});\n\t}\n},\n\n{\n\tname: \"lineBreak\",\n\tmatch: \"\\\\n|<br ?/?>\",\n\thandler: function(w)\n\t{\n\t\tw.output.push({type:\"element\",tag:\"br\"});\n\t}\n},\n\n{\n\tname: \"rawText\",\n\tmatch: \"\\\"{3}|<nowiki>\",\n\tlookaheadRegExp: /(?:\\\"{3}|<nowiki>)((?:.|\\n)*?)(?:\\\"{3}|<\\/nowiki>)/mg,\n\thandler: function(w)\n\t{\n\t\tthis.lookaheadRegExp.lastIndex = w.matchStart;\n\t\tvar lookaheadMatch = this.lookaheadRegExp.exec(w.source);\n\t\tif(lookaheadMatch && lookaheadMatch.index == w.matchStart) {\n\t\t\tw.output.push({type: \"text\",text: lookaheadMatch[1]\n\t\t\t});\n\t\t\tw.nextMatch = this.lookaheadRegExp.lastIndex;\n\t\t}\n\t}\n},\n\n{\n\tname: \"htmlEntitiesEncoding\",\n\tmatch: \"&#?[a-zA-Z0-9]{2,8};\",\n\thandler: function(w)\n\t{\n\t\tw.output.push({type: \"entity\", entity: w.matchText});\n\t}\n}\n\n];\n\nexports.rules = rules;\n\n})();\n","type":"application/javascript","module-type":"module"}}}
no

{
    "tiddlers": {
        "$:/info/browser": {
            "title": "$:/info/browser",
            "text": "no"
        },
        "$:/info/node": {
            "title": "$:/info/node",
            "text": "yes"
        },
        "$:/info/startup-timestamp": {
            "title": "$:/info/startup-timestamp",
            "text": "20241031093721852"
        }
    }
}
{"tiddlers":{"$:/themes/tiddlywiki/snowwhite/base":{"title":"$:/themes/tiddlywiki/snowwhite/base","tags":"[[$:/tags/Stylesheet]]","text":"\\define sidebarbreakpoint-minus-one()\n<$text text={{{ [{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}removesuffix[px]subtract[1]addsuffix[px]] ~[{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}] }}}/>\n\\end\n\n\\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline\n\n.tc-sidebar-header {\n\ttext-shadow: 0 1px 0 <<colour sidebar-foreground-shadow>>;\n}\n\n.tc-tiddler-info {\n\t<<box-shadow \"inset 1px 2px 3px rgba(0,0,0,0.1)\">>\n}\n\n@media screen {\n\t.tc-tiddler-frame {\n\t\t<<box-shadow \"1px 1px 5px rgba(0, 0, 0, 0.3)\">>\n\t}\n}\n\n@media (max-width: <<sidebarbreakpoint-minus-one>>) {\n\t.tc-tiddler-frame {\n\t\t<<box-shadow none>>\n\t}\n}\n\n.tc-page-controls button svg, .tc-tiddler-controls button svg, .tc-topbar button svg {\n\t<<transition \"fill 150ms ease-in-out\">>\n}\n\n.tc-tiddler-controls button.tc-selected,\n.tc-page-controls button.tc-selected {\n\t<<filter \"drop-shadow(0px -1px 2px rgba(0,0,0,0.25))\">>\n}\n\n.tc-tiddler-frame input.tc-edit-texteditor,\n.tc-tiddler-frame select.tc-edit-texteditor {\n\t<<box-shadow \"inset 0 1px 8px rgba(0, 0, 0, 0.15)\">>\n}\n\n.tc-edit-tags {\n\t<<box-shadow \"inset 0 1px 8px rgba(0, 0, 0, 0.15)\">>\n}\n\n.tc-tiddler-frame .tc-edit-tags input.tc-edit-texteditor {\n\t<<box-shadow \"none\">>\n\tborder: none;\n\toutline: none;\n}\n\ntextarea.tc-edit-texteditor {\n\tfont-family: {{$:/themes/tiddlywiki/vanilla/settings/editorfontfamily}};\n}\n\ncanvas.tc-edit-bitmapeditor  {\n\t<<box-shadow \"2px 2px 5px rgba(0, 0, 0, 0.5)\">>\n}\n\n.tc-drop-down {\n\tborder-radius: 4px;\n\t<<box-shadow \"2px 2px 10px rgba(0, 0, 0, 0.5)\">>\n}\n\n.tc-block-dropdown {\n\tborder-radius: 4px;\n\t<<box-shadow \"2px 2px 10px rgba(0, 0, 0, 0.5)\">>\n}\n\n.tc-modal {\n\tborder-radius: 6px;\n\t<<box-shadow \"0 3px 7px rgba(0,0,0,0.3)\">>\n}\n\n.tc-modal-footer {\n\tborder-radius: 0 0 6px 6px;\n\t<<box-shadow \"inset 0 1px 0 #fff\">>;\n}\n\n\n.tc-alert {\n\tborder-radius: 6px;\n\t<<box-shadow \"0 3px 7px rgba(0,0,0,0.6)\">>\n}\n\n.tc-notification {\n\tborder-radius: 6px;\n\t<<box-shadow \"0 3px 7px rgba(0,0,0,0.3)\">>\n\ttext-shadow: 0 1px 0 rgba(255,255,255, 0.8);\n}\n\n.tc-sidebar-lists .tc-tab-set .tc-tab-divider {\n\tborder-top: none;\n\theight: 1px;\n\t<<background-linear-gradient \"left, rgba(0,0,0,0.15) 0%, rgba(0,0,0,0.0) 100%\">>\n}\n\n.tc-more-sidebar > .tc-tab-set > .tc-tab-buttons > button {\n\t<<background-linear-gradient \"left, rgba(0,0,0,0.01) 0%, rgba(0,0,0,0.1) 100%\">>\n}\n\n.tc-more-sidebar > .tc-tab-set > .tc-tab-buttons > button.tc-tab-selected {\n\t<<background-linear-gradient \"left, rgba(0,0,0,0.05) 0%, rgba(255,255,255,0.05) 100%\">>\n}\n\n.tc-message-box img {\n\t<<box-shadow \"1px 1px 3px rgba(0,0,0,0.5)\">>\n}\n\n.tc-plugin-info {\n\t<<box-shadow \"1px 1px 3px rgba(0,0,0,0.5)\">>\n}\n"}}}
{"tiddlers":{"$:/themes/tiddlywiki/vanilla/themetweaks":{"title":"$:/themes/tiddlywiki/vanilla/themetweaks","tags":"$:/tags/ControlPanel/Appearance","caption":"{{$:/language/ThemeTweaks/ThemeTweaks}}","text":"\\define lingo-base() $:/language/ThemeTweaks/\n\n\\define replacement-text()\n[img[$(imageTitle)$]]\n\\end\n\n\\define backgroundimage-dropdown()\n<div class=\"tc-drop-down-wrapper\">\n<$set name=\"state\" value=<<qualify \"$:/state/popup/themetweaks/backgroundimage\">>>\n<$button popup=<<state>> class=\"tc-btn-invisible tc-btn-dropdown\">{{$:/core/images/down-arrow}}</$button>\n<$reveal state=<<state>> type=\"popup\" position=\"belowleft\" text=\"\" default=\"\" class=\"tc-popup-keep\">\n<div class=\"tc-drop-down\" style=\"text-align:center;\">\n<$macrocall $name=\"image-picker\" actions=\"\"\"\n\n<$action-setfield\n\t$tiddler=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimage\"\n\t$value=<<imageTitle>>\n/>\n\n<$action-deletetiddler $tiddler=<<state>>/>\n\n\"\"\"/>\n</div>\n</$reveal>\n</$set>\n</div>\n\\end\n\n\\define backgroundimageattachment-dropdown()\n<$select tiddler=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimageattachment\" default=\"scroll\">\n<option value=\"scroll\"><<lingo Settings/BackgroundImageAttachment/Scroll>></option>\n<option value=\"fixed\"><<lingo Settings/BackgroundImageAttachment/Fixed>></option>\n</$select>\n\\end\n\n\\define backgroundimagesize-dropdown()\n<$select tiddler=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize\" default=\"scroll\">\n<option value=\"auto\"><<lingo Settings/BackgroundImageSize/Auto>></option>\n<option value=\"cover\"><<lingo Settings/BackgroundImageSize/Cover>></option>\n<option value=\"contain\"><<lingo Settings/BackgroundImageSize/Contain>></option>\n</$select>\n\\end\n\n<<lingo ThemeTweaks/Hint>>\n\n! <<lingo Options>>\n\n|<$link to=\"$:/themes/tiddlywiki/vanilla/options/sidebarlayout\"><<lingo Options/SidebarLayout>></$link> |<$select tiddler=\"$:/themes/tiddlywiki/vanilla/options/sidebarlayout\"><option value=\"fixed-fluid\"><<lingo Options/SidebarLayout/Fixed-Fluid>></option><option value=\"fluid-fixed\"><<lingo Options/SidebarLayout/Fluid-Fixed>></option></$select> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/options/stickytitles\"><<lingo Options/StickyTitles>></$link><br>//<<lingo Options/StickyTitles/Hint>>// |<$select tiddler=\"$:/themes/tiddlywiki/vanilla/options/stickytitles\"><option value=\"no\">{{$:/language/No}}</option><option value=\"yes\">{{$:/language/Yes}}</option></$select> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/options/codewrapping\"><<lingo Options/CodeWrapping>></$link> |<$select tiddler=\"$:/themes/tiddlywiki/vanilla/options/codewrapping\"><option value=\"pre\">{{$:/language/No}}</option><option value=\"pre-wrap\">{{$:/language/Yes}}</option></$select> |\n\n! <<lingo Settings>>\n\n|<$link to=\"$:/themes/tiddlywiki/vanilla/settings/fontfamily\"><<lingo Settings/FontFamily>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/settings/fontfamily\" default=\"\" tag=\"input\"/> | |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/settings/codefontfamily\"><<lingo Settings/CodeFontFamily>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/settings/codefontfamily\" default=\"\" tag=\"input\"/> | |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/settings/editorfontfamily\"><<lingo Settings/EditorFontFamily>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/settings/editorfontfamily\" default=\"\" tag=\"input\"/> | |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimage\"><<lingo Settings/BackgroundImage>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimage\" default=\"\" tag=\"input\"/> |<<backgroundimage-dropdown>> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimageattachment\"><<lingo Settings/BackgroundImageAttachment>></$link> |<<backgroundimageattachment-dropdown>> | |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize\"><<lingo Settings/BackgroundImageSize>></$link> |<<backgroundimagesize-dropdown>> | |\n\n! <<lingo Metrics>>\n\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/fontsize\"><<lingo Metrics/FontSize>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/fontsize\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/lineheight\"><<lingo Metrics/LineHeight>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/lineheight\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize\"><<lingo Metrics/BodyFontSize>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/bodylineheight\"><<lingo Metrics/BodyLineHeight>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/bodylineheight\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/storyleft\"><<lingo Metrics/StoryLeft>></$link><br>//<<lingo Metrics/StoryLeft/Hint>>// |^<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/storyleft\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/storytop\"><<lingo Metrics/StoryTop>></$link><br>//<<lingo Metrics/StoryTop/Hint>>// |^<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/storytop\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/storyright\"><<lingo Metrics/StoryRight>></$link><br>//<<lingo Metrics/StoryRight/Hint>>// |^<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/storyright\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/storywidth\"><<lingo Metrics/StoryWidth>></$link><br>//<<lingo Metrics/StoryWidth/Hint>>// |^<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/storywidth\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth\"><<lingo Metrics/TiddlerWidth>></$link><br>//<<lingo Metrics/TiddlerWidth/Hint>>//<br> |^<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint\"><<lingo Metrics/SidebarBreakpoint>></$link><br>//<<lingo Metrics/SidebarBreakpoint/Hint>>// |^<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth\"><<lingo Metrics/SidebarWidth>></$link><br>//<<lingo Metrics/SidebarWidth/Hint>>// |^<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth\" default=\"\" tag=\"input\"/> |\n"},"$:/themes/tiddlywiki/vanilla/base":{"title":"$:/themes/tiddlywiki/vanilla/base","tags":"[[$:/tags/Stylesheet]]","list-before":"","code-body":"yes","text":"\\define custom-background-datauri()\n<$set name=\"background\" value={{$:/themes/tiddlywiki/vanilla/settings/backgroundimage}}>\n<$list filter=\"[<background>is[image]]\">\n`background: url(`\n<$list filter=\"[<background>!has[_canonical_uri]]\">\n`\"`<$macrocall $name=\"datauri\" title={{$:/themes/tiddlywiki/vanilla/settings/backgroundimage}}/>`\"`\n</$list>\n<$list filter=\"[<background>has[_canonical_uri]]\">\n`\"`<$view tiddler={{$:/themes/tiddlywiki/vanilla/settings/backgroundimage}} field=\"_canonical_uri\"/>`\"`\n</$list>\n`) center center;`\n`background-attachment: `{{$:/themes/tiddlywiki/vanilla/settings/backgroundimageattachment}}`;\n-webkit-background-size:` {{$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize}}`;\n-moz-background-size:` {{$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize}}`;\n-o-background-size:` {{$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize}}`;\nbackground-size:` {{$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize}}`;`\n</$list>\n</$set>\n\\end\n\n\\define sidebarbreakpoint()\n<$text text={{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}/>\n\\end\n\n\\define sidebarbreakpoint-minus-one()\n<$text text={{{ [{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}removesuffix[px]subtract[1]addsuffix[px]] ~[{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}] }}}/>\n\\end\n\n\\define if-fluid-fixed(text,hiddenSidebarText)\n<$reveal state=\"$:/themes/tiddlywiki/vanilla/options/sidebarlayout\" type=\"match\" text=\"fluid-fixed\">\n$text$\n<$reveal state=\"$:/state/sidebar\" type=\"nomatch\" text=\"yes\" default=\"yes\">\n$hiddenSidebarText$\n</$reveal>\n</$reveal>\n\\end\n\n\\define if-editor-height-fixed(then,else)\n<$reveal state=\"$:/config/TextEditor/EditorHeight/Mode\" type=\"match\" text=\"fixed\">\n$then$\n</$reveal>\n<$reveal state=\"$:/config/TextEditor/EditorHeight/Mode\" type=\"match\" text=\"auto\">\n$else$\n</$reveal>\n\\end\n\n\\define set-type-selector-min-width()\n<$set name=\"typeLength\" value={{{ [all[shadows+tiddlers]prefix[$:/language/Docs/Types/]get[name]length[]maxall[]] }}}>\n\n\t.tc-type-selector-dropdown-wrapper {\n\t\tmin-width: calc(<<typeLength>>ch + 4em);\n\t}\n\n\t.tc-type-selector-dropdown-wrapper input.tc-edit-typeeditor {\n\t\tmin-width: <<typeLength>>ch;\n\t}\n\n</$set>\n\\end\n\n\\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline macrocallblock\n\n/*\n** Start with the normalize CSS reset, and then belay some of its effects\n*/\n\n{{$:/themes/tiddlywiki/vanilla/reset}}\n\ninput[type=\"search\"] {\n\toutline-offset: initial;\n}\n\nbutton:focus-visible, input:focus-visible, textarea:focus-visible, select:focus-visible {\n\toutline: 2px solid <<colour primary>>;\n\toutline-offset: -2px;\n\tborder-radius: 0.25em;\n}\n\nbutton:-moz-focusring, input:-moz-focusring, textarea:-moz-focusring, select:-moz-focusring {\n\toutline: 2px solid <<colour primary>>;\n\toutline-offset: -2px;\n\tborder-radius: 0.25em;\n}\n\n/*\n** Button default styles. Makes them look consistent for all browsers\n*/\nhtml button {\n\tline-height: 1.2;\n\tcolor: <<colour button-foreground>>;\n\tfill: <<colour button-foreground>>;\n\tbackground: <<colour button-background>>;\n\tborder-color: <<colour button-border>>;\n}\n\nbutton:disabled svg {\n\tfill: <<colour muted-foreground>>;\n}\n\n/*\n** Basic element styles\n*/\n\nhtml, body {\n\tfont-family: {{$:/themes/tiddlywiki/vanilla/settings/fontfamily}};\n\ttext-rendering: optimizeLegibility; /* Enables kerning and ligatures etc. */\n\t-webkit-font-smoothing: antialiased;\n\t-moz-osx-font-smoothing: grayscale;\n}\n\nhtml:-webkit-full-screen {\n\tbackground-color: <<colour page-background>>;\n}\n\nbody.tc-body {\n\tfont-size: {{$:/themes/tiddlywiki/vanilla/metrics/fontsize}};\n\tline-height: {{$:/themes/tiddlywiki/vanilla/metrics/lineheight}};\n\tword-wrap: break-word;\n\t<<custom-background-datauri>>\n\tcolor: <<colour foreground>>;\n\tbackground-color: <<colour page-background>>;\n\tfill: <<colour foreground>>;\n}\n\n<<if-background-attachment \"\"\"\n\nbody.tc-body {\n\tbackground-color: transparent;\n}\n\n\"\"\">>\n\n/**\n * Correct the font size and margin on `h1` elements within `section` and\n * `article` contexts in Chrome, Firefox, and Safari.\n */\n\nh1 {\n\tfont-size: 2em;\n}\n\nh1, h2, h3, h4, h5, h6 {\n\tline-height: 1.2;\n\tfont-weight: normal;\n}\n\npre {\n\tdisplay: block;\n\tmargin-top: 1em;\n\tmargin-bottom: 1em;\n\tword-break: normal;\n\tword-wrap: break-word;\n\twhite-space: {{$:/themes/tiddlywiki/vanilla/options/codewrapping}};\n\tbackground-color: <<colour pre-background>>;\n\tborder: 1px solid <<colour pre-border>>;\n\tpadding: 0 3px 2px;\n\tborder-radius: 3px;\n\tfont-family: {{$:/themes/tiddlywiki/vanilla/settings/codefontfamily}};\n}\n\ncode {\n\tcolor: <<colour code-foreground>>;\n\tbackground-color: <<colour code-background>>;\n\tborder: 1px solid <<colour code-border>>;\n\twhite-space: pre-wrap;\n\tpadding: 0 3px 2px;\n\tborder-radius: 3px;\n\tfont-family: {{$:/themes/tiddlywiki/vanilla/settings/codefontfamily}};\n}\n\nblockquote {\n\tborder-left: 5px solid <<colour blockquote-bar>>;\n\tmargin-left: 25px;\n\tpadding-left: 10px;\n\tquotes: \"\\201C\"\"\\201D\"\"\\2018\"\"\\2019\";\n}\n\nblockquote > div {\n\tmargin-top: 1em;\n\tmargin-bottom: 1em;\n}\n\nblockquote.tc-big-quote {\n\tfont-family: Georgia, serif;\n\tposition: relative;\n\tbackground: <<colour pre-background>>;\n\tborder-left: none;\n\tmargin-left: 50px;\n\tmargin-right: 50px;\n\tpadding: 10px;\n\tborder-radius: 8px;\n}\n\nblockquote.tc-big-quote cite:before {\n\tcontent: \"\\2014 \\2009\";\n}\n\nblockquote.tc-big-quote:before {\n\tfont-family: Georgia, serif;\n\tcolor: <<colour blockquote-bar>>;\n\tcontent: open-quote;\n\tfont-size: 8em;\n\tline-height: 0.1em;\n\tmargin-right: 0.25em;\n\tvertical-align: -0.4em;\n\tposition: absolute;\n\tleft: -50px;\n\ttop: 42px;\n}\n\nblockquote.tc-big-quote:after {\n\tfont-family: Georgia, serif;\n\tcolor: <<colour blockquote-bar>>;\n\tcontent: close-quote;\n\tfont-size: 8em;\n\tline-height: 0.1em;\n\tmargin-right: 0.25em;\n\tvertical-align: -0.4em;\n\tposition: absolute;\n\tright: -80px;\n\tbottom: -20px;\n}\n\ndl dt {\n\tfont-weight: bold;\n\tmargin-top: 6px;\n}\n\ntextarea,\ninput[type=text],\ninput[type=search],\ninput[type=number],\ninput[type=password],\ninput[type=email],\ninput[type=tel],\ninput[type=url],\ninput[type=\"\"],\ninput:not([type]) {\n\tcolor: <<colour foreground>>;\n\tbackground: <<colour background>>;\n}\n\ninput[type=\"checkbox\"] {\n\tvertical-align: middle;\n}\n\ninput[type=\"search\"]::-webkit-search-decoration,\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-results-button,\ninput[type=\"search\"]::-webkit-search-results-decoration {\n\t-webkit-appearance:none;\n}\n\n.tc-muted {\n\tcolor: <<colour muted-foreground>>;\n}\n\nsvg.tc-image-button {\n\tpadding: 0px 1px 1px 0px;\n}\n\n.tc-icon-wrapper > svg {\n\twidth: 1em;\n\theight: 1em;\n}\n\nkbd {\n\tdisplay: inline-block;\n\tpadding: 3px 5px;\n\tfont-size: 0.8em;\n\tline-height: 1.2;\n\tcolor: <<colour foreground>>;\n\tvertical-align: middle;\n\tbackground-color: <<colour background>>;\n\tborder: solid 1px <<colour muted-foreground>>;\n\tborder-bottom-color: <<colour muted-foreground>>;\n\tborder-radius: 3px;\n\tbox-shadow: inset 0 -1px 0 <<colour muted-foreground>>;\n}\n\n::selection {\n\tbackground-color: Highlight;\n\tcolor: HighlightText;\n\tbackground-color: <<colour selection-background>>;\n\tcolor: <<colour selection-foreground>>;\n}\n\n.tc-inline-style {\n\tbackground: <<colour highlight-background>>;\n\tcolor: <<colour highlight-foreground>>;\n}\n\n/* Markdown uses mark element to highlight */\n\nmark {\n\tbackground: <<colour highlight-background>>;\n\tcolor: <<colour highlight-foreground>>;\n}\n\nform.tc-form-inline {\n\tdisplay: inline;\n}\n\n/*\nMarkdown likes putting code elements inside pre elements\n*/\npre > code {\n\tdisplay: block;\n\tpadding: 0.5em;\n\tborder: none;\n\twhite-space: {{$:/themes/tiddlywiki/vanilla/options/codewrapping}};\n\tbackground-color: inherit;\n\tcolor: inherit;\n\toverflow-x: auto;\n}\n\n/*\nTable defaults\n*/\n\ntable {\n\tborder: 1px solid <<colour table-border>>;\n\twidth: auto;\n\tmax-width: 100%;\n\tcaption-side: bottom;\n\tmargin-top: 1em;\n\tmargin-bottom: 1em;\n\t/* next 2 elements needed, since normalize 8.0.1 */\n\tborder-collapse: collapse;\n\tborder-spacing: 0;\n}\n\ntable th, table td {\n\tpadding: 0 7px 0 7px;\n\tborder-top: 1px solid <<colour table-border>>;\n\tborder-left: 1px solid <<colour table-border>>;\n}\n\ntable thead tr td, table th {\n\tbackground-color: <<colour table-header-background>>;\n\tfont-weight: bold;\n}\n\ntable tfoot tr td {\n\tbackground-color: <<colour table-footer-background>>;\n}\n\n/*\nTable utility classes\n*/\n\n/* Remove borders from table as used in eg: GettingStarted*/\n.tc-table-no-border,\n.tc-table-no-border th,\n.tc-table-no-border td {\n\tborder: initial;\n}\n\n/* First column in table width will fit to text.*/\n/* This rule makes most sense with tc-first-link-nowrap*/\n.tc-first-col-min-width td:nth-child(1) {\n\twidth: 1%;\n}\n\n/*\n** Utility classes work well with tables but also for other containers\n*/\n\n/* First link A element will not wrap */\n.tc-first-link-nowrap:first-of-type a {\n\twhite-space: nowrap;\n}\n\n/* Move the table to the center of the container */\n.tc-center {\n\tmargin-left: auto;\n\tmargin-right: auto;\n}\n\n.tc-max-width {\n\twidth: 100%;\n}\n\n.tc-max-width-80 {\n\tmax-width: 80%;\n}\n\n/* Allow input and textarea to look like the ControlPanel inputs */\n.tc-edit-max-width input,\n.tc-edit-max-width textarea {\n\twidth: 100%;\n\tpadding: 3px;\n}\n\n/*\nCSV parser plugin\n*/\n\n.tc-csv-table {\n\twhite-space: nowrap;\n}\n\n.tc-csv-table th,\n.tc-csv-table td {\n\twhite-space: pre-line;\n}\n\n/*\nTiddler frame in story river\n*/\n\n.tc-tiddler-frame img,\n.tc-tiddler-frame svg,\n.tc-tiddler-frame canvas,\n.tc-tiddler-frame embed,\n.tc-tiddler-frame iframe {\n\tmax-width: 100%;\n}\n\n.tc-tiddler-body > embed,\n.tc-tiddler-body > iframe {\n\twidth: 100%;\n\theight: 600px;\n}\n\n:root {\n\tcolor-scheme: {{{ [{$:/palette}get[color-scheme]] ~light }}};\n}\n\n/*\n** Links\n*/\n\nbutton.tc-tiddlylink,\na.tc-tiddlylink {\n\ttext-decoration: none;\n\tfont-weight: 500;\n\tcolor: <<colour tiddler-link-foreground>>;\n\t-webkit-user-select: inherit; /* Otherwise the draggable attribute makes links impossible to select */\n\t-webkit-touch-callout: none; /* Prevents long presses from bringing up a link preview */\n}\n\n.tc-sidebar-lists a.tc-tiddlylink {\n\tcolor: <<colour sidebar-tiddler-link-foreground>>;\n}\n\n.tc-sidebar-lists a.tc-tiddlylink:hover {\n\tcolor: <<colour sidebar-tiddler-link-foreground-hover>>;\n}\n\nbutton.tc-tiddlylink:hover,\na.tc-tiddlylink:hover {\n\ttext-decoration: underline;\n}\n\na.tc-tiddlylink-resolves {\n}\n\na.tc-tiddlylink-shadow {\n\tfont-weight: bold;\n}\n\na.tc-tiddlylink-shadow.tc-tiddlylink-resolves {\n\tfont-weight: normal;\n}\n\na.tc-tiddlylink-missing {\n\tfont-style: italic;\n}\n\na.tc-tiddlylink-external {\n\ttext-decoration: underline;\n\tcolor: <<colour external-link-foreground>>;\n\tbackground-color: <<colour external-link-background>>;\n}\n\na.tc-tiddlylink-external:visited {\n\tcolor: <<colour external-link-foreground-visited>>;\n\tbackground-color: <<colour external-link-background-visited>>;\n}\n\na.tc-tiddlylink-external:hover {\n\tcolor: <<colour external-link-foreground-hover>>;\n\tbackground-color: <<colour external-link-background-hover>>;\n}\n\n.tc-drop-down a.tc-tiddlylink:hover {\n\tcolor: <<colour tiddler-link-background>>;\n}\n\n/*\n** Drag and drop styles\n*/\n\n.tc-tiddler-dragger {\n\tposition: relative;\n\tz-index: -10000;\n}\n\n.tc-tiddler-dragger-inner {\n\tposition: absolute;\n\ttop: -1000px;\n\tleft: -1000px;\n\tdisplay: inline-block;\n\tpadding: 8px 20px;\n\tfont-size: 16.9px;\n\tfont-weight: bold;\n\tline-height: 20px;\n\tcolor: <<colour dragger-foreground>>;\n\ttext-shadow: 0 1px 0 rgba(0, 0, 0, 1);\n\twhite-space: nowrap;\n\tvertical-align: baseline;\n\tbackground-color: <<colour dragger-background>>;\n\tborder-radius: 20px;\n}\n\n.tc-tiddler-dragger-cover {\n\tposition: absolute;\n\tbackground-color: <<colour page-background>>;\n}\n\n.tc-page-container > .tc-dropzone {\n\tmin-height: 100vh;\n}\n\n.tc-dropzone {\n\tposition: relative;\n}\n\n.tc-dropzone.tc-dragover:before {\n\tz-index: 10000;\n\tdisplay: block;\n\tposition: fixed;\n\ttop: 0;\n\tleft: 0;\n\tright: 0;\n\tbackground: <<colour dropzone-background>>;\n\ttext-align: center;\n\tcontent: \"<<lingo DropMessage>>\";\n}\n\n.tc-droppable > .tc-droppable-placeholder {\n\tdisplay: none;\n}\n\n.tc-droppable.tc-dragover > .tc-droppable-placeholder {\n\tdisplay: block;\n\tborder: 2px dashed <<colour dropzone-background>>;\n}\n\n.tc-draggable {\n\tcursor: move;\n}\n\n.tc-sidebar-tab-open .tc-droppable-placeholder, .tc-tagged-draggable-list .tc-droppable-placeholder,\n.tc-links-draggable-list .tc-droppable-placeholder {\n\tline-height: 2em;\n\theight: 2em;\n}\n\n.tc-sidebar-tab-open-item {\n\tposition: relative;\n}\n\n.tc-sidebar-tab-open .tc-btn-invisible.tc-btn-mini svg {\n\tfont-size: 0.7em;\n\tfill: <<colour muted-foreground>>;\n}\n\n/*\n** Plugin reload warning\n*/\n\n.tc-plugin-reload-warning {\n\tz-index: 1000;\n\tdisplay: block;\n\tposition: fixed;\n\ttop: 0;\n\tleft: 0;\n\tright: 0;\n\tbackground: <<colour alert-background>>;\n\ttext-align: center;\n}\n\n/*\n** Buttons\n*/\n\nbutton svg, button img, label svg, label img {\n\tvertical-align: middle;\n}\n\n.tc-btn-invisible {\n\tpadding: 0;\n\tmargin: 0;\n\tbackground: none;\n\tborder: none;\n\tcursor: pointer;\n\tcolor: <<colour foreground>>;\n\tfill: <<colour foreground>>;\n}\n\nbutton:disabled.tc-btn-invisible  {\n\tcursor: default;\n\tcolor: <<colour muted-foreground>>;\n}\n\n.tc-btn-boxed {\n\tfont-size: 0.6em;\n\tpadding: 0.2em;\n\tmargin: 1px;\n\tbackground: none;\n\tborder: 1px solid <<colour tiddler-controls-foreground>>;\n\tborder-radius: 0.25em;\n}\n\nhtml body.tc-body .tc-btn-boxed svg {\n\tfont-size: 1.6666em;\n}\n\n.tc-btn-boxed:hover {\n\tbackground: <<colour muted-foreground>>;\n\tcolor: <<colour background>>;\n}\n\nhtml body.tc-body .tc-btn-boxed:hover svg {\n\tfill: <<colour background>>;\n}\n\n.tc-btn-rounded {\n\tfont-size: 0.5em;\n\tline-height: 2;\n\tpadding: 0em 0.3em 0.2em 0.4em;\n\tmargin: 1px;\n\tborder: 1px solid <<colour muted-foreground>>;\n\tbackground: <<colour muted-foreground>>;\n\tcolor: <<colour background>>;\n\tborder-radius: 2em;\n}\n\nhtml body.tc-body .tc-btn-rounded svg {\n\tfont-size: 1.6666em;\n\tfill: <<colour background>>;\n}\n\n.tc-btn-rounded:hover {\n\tborder: 1px solid <<colour muted-foreground>>;\n\tbackground: <<colour background>>;\n\tcolor: <<colour muted-foreground>>;\n}\n\nhtml body.tc-body .tc-btn-rounded:hover svg {\n\tfill: <<colour muted-foreground>>;\n}\n\n.tc-btn-icon svg {\n\theight: 1em;\n\twidth: 1em;\n\tfill: <<colour muted-foreground>>;\n}\n\n\n.tc-btn-text {\n\tmargin-left: 7px;\n}\n\n/* used for documentation \"fake\" buttons */\n.tc-btn-standard {\n\tline-height: 1.8;\n\tcolor: #667;\n\tbackground-color: #e0e0e0;\n\tborder: 1px solid #888;\n\tpadding: 2px 1px 2px 1px;\n\tmargin: 1px 4px 1px 4px;\n}\n\n.tc-btn-big-green {\n\tdisplay: inline-block;\n\tpadding: 8px;\n\tmargin: 4px 8px 4px 8px;\n\tbackground: <<colour download-background>>;\n\tcolor: <<colour download-foreground>>;\n\tfill: <<colour download-foreground>>;\n\tborder: none;\n\tborder-radius: 2px;\n\tfont-size: 1.2em;\n\tline-height: 1.4em;\n\ttext-decoration: none;\n}\n\n.tc-btn-big-green svg,\n.tc-btn-big-green img {\n\theight: 2em;\n\twidth: 2em;\n\tvertical-align: middle;\n\tfill: <<colour download-foreground>>;\n}\n\n.tc-primary-btn {\n\tbackground: <<colour primary>>;\n}\n\n.tc-sidebar-lists input {\n\tcolor: <<colour foreground>>;\n}\n\n.tc-sidebar-lists button {\n\tcolor: <<colour sidebar-button-foreground>>;\n\tfill: <<colour sidebar-button-foreground>>;\n}\n\n.tc-sidebar-lists button.tc-btn-mini {\n\tcolor: <<colour sidebar-muted-foreground>>;\n}\n\n.tc-sidebar-lists button.tc-btn-mini:hover {\n\tcolor: <<colour sidebar-muted-foreground-hover>>;\n}\n\n.tc-sidebar-lists button small {\n\tcolor: <<colour foreground>>;\n}\n\nbutton svg.tc-image-button, button .tc-image-button img {\n\theight: 1em;\n\twidth: 1em;\n}\n\n.tc-unfold-banner {\n\tposition: absolute;\n\tpadding: 0;\n\tmargin: 0;\n\tbackground: none;\n\tborder: none;\n\twidth: 100%;\n\twidth: calc(100% + 2px);\n\tmargin-left: -43px;\n\ttext-align: center;\n\tborder-top: 2px solid <<colour tiddler-info-background>>;\n\tmargin-top: 4px;\n}\n\n.tc-unfold-banner:hover {\n\tbackground: <<colour tiddler-info-background>>;\n\tborder-top: 2px solid <<colour tiddler-info-border>>;\n}\n\n.tc-unfold-banner svg, .tc-fold-banner svg {\n\theight: 0.75em;\n\tfill: <<colour tiddler-controls-foreground>>;\n}\n\n.tc-unfold-banner:hover svg, .tc-fold-banner:hover svg {\n\tfill: <<colour tiddler-controls-foreground-hover>>;\n}\n\n.tc-fold-banner {\n\tposition: absolute;\n\tpadding: 0;\n\tmargin: 0;\n\tbackground: none;\n\tborder: none;\n\twidth: 23px;\n\ttext-align: center;\n\tmargin-left: -35px;\n\ttop: 6px;\n\tbottom: 6px;\n}\n\n.tc-fold-banner:hover {\n\tbackground: <<colour tiddler-info-background>>;\n}\n\n@media (max-width: <<sidebarbreakpoint-minus-one>>) {\n\n\t.tc-unfold-banner {\n\t\tposition: static;\n\t\twidth: calc(100% + 59px);\n\t}\n\n\t.tc-fold-banner {\n\t\twidth: 16px;\n\t\tmargin-left: -16px;\n\t\tfont-size: 0.75em;\n\t}\n\n}\n\n/*\n** Tags and missing tiddlers\n*/\n\n.tc-tag-list-item {\n\tposition: relative;\n\tdisplay: inline-block;\n}\n\n.tc-tags-wrapper {\n\tmargin: 4px 0 14px 0;\n}\n\n.tc-tags-wrapper .tc-tag-list-item {\n\tmargin-right: 7px;\n}\n\n.tc-missing-tiddler-label {\n\tfont-style: italic;\n\tfont-weight: normal;\n\tdisplay: inline-block;\n\tfont-size: 11.844px;\n\tline-height: 14px;\n\twhite-space: nowrap;\n\tvertical-align: baseline;\n}\n\n.tc-block-tags-dropdown > .tc-btn-invisible:hover {\n\tbackground-color: <<colour primary>>;\n}\n\nbutton.tc-tag-label, span.tc-tag-label {\n\tdisplay: inline-block;\n\tpadding: 0.16em 0.7em;\n\tfont-size: 0.9em;\n\tfont-weight: normal;\n\tline-height: 1.2em;\n\tcolor: <<colour tag-foreground>>;\n\twhite-space: break-spaces;\n\tvertical-align: baseline;\n\tbackground-color: <<colour tag-background>>;\n\tborder-radius: 1em;\n}\n\n.tc-sidebar-scrollable .tc-tag-label {\n\ttext-shadow: none;\n}\n\n.tc-untagged-separator {\n\tborder: 0;\n\theight: 1px;\n\tbackground: <<colour tab-divider>>;\n}\n\nbutton.tc-untagged-label {\n\tbackground-color: <<colour untagged-background>>;\n}\n\n.tc-tag-label svg, .tc-tag-label img {\n\theight: 1em;\n\twidth: 1em;\n\tmargin-right: 3px;\n\tmargin-bottom: 1px;\n\tvertical-align: bottom;\n}\n\n.tc-edit-tags button.tc-remove-tag-button svg {\n\tfont-size: 0.7em;\n\tvertical-align: middle;\n}\n\n.tc-tag-manager-table .tc-tag-label {\n}\n\n.tc-tag-manager-tag {\n\twidth: 100%;\n}\n\nbutton.tc-btn-invisible.tc-remove-tag-button {\n\toutline: none;\n}\n\n.tc-tag-button-selected,\n.tc-list-item-selected a.tc-tiddlylink, a.tc-list-item-selected {\n\tbackground-color: <<colour primary>>;\n\tcolor: <<colour tiddler-background>>;\n}\n\n/*\n** Page layout\n*/\n\n.tc-topbar {\n\tposition: fixed;\n\tz-index: 1200;\n}\n\n.tc-topbar-left {\n\tleft: 29px;\n\ttop: 5px;\n}\n\n.tc-topbar-right {\n\ttop: 5px;\n\tright: 29px;\n}\n\n@media (max-width: <<sidebarbreakpoint-minus-one>>) {\n\n\t.tc-topbar-right {\n\t\tright: 10px;\n\t}\n\n}\n\n.tc-topbar button {\n\tpadding: 8px;\n}\n\n.tc-topbar svg {\n\tfill: <<colour muted-foreground>>;\n}\n\n.tc-topbar button:hover svg {\n\tfill: <<colour foreground>>;\n}\n\n@media (max-width: <<sidebarbreakpoint-minus-one>>) {\n\n\t.tc-show-sidebar-btn svg.tc-image-chevron-left, .tc-hide-sidebar-btn svg.tc-image-chevron-right {\n\t\ttransform: rotate(-90deg);\n\t}\n\n}\n\n.tc-sidebar-header {\n\tcolor: <<colour sidebar-foreground>>;\n\tfill: <<colour sidebar-foreground>>;\n}\n\n.tc-sidebar-header .tc-title a.tc-tiddlylink-resolves {\n\tfont-weight: normal;\n}\n\n.tc-sidebar-header .tc-sidebar-lists p {\n\tmargin-top: 3px;\n\tmargin-bottom: 3px;\n}\n\n.tc-sidebar-header .tc-missing-tiddler-label {\n\tcolor: <<colour sidebar-foreground>>;\n}\n\n.tc-advanced-search input {\n\twidth: 60%;\n}\n\n.tc-search a svg {\n\twidth: 1.2em;\n\theight: 1.2em;\n\tvertical-align: middle;\n}\n\n.tc-page-controls {\n\tmargin-top: 14px;\n\tmargin-bottom: 14px;\n\tfont-size: 1.5em;\n}\n\n.tc-page-controls .tc-drop-down {\n\tfont-size: 1rem;\n}\n\n.tc-page-controls button {\n\tmargin-right: 0.5em;\n}\n\n.tc-page-controls a.tc-tiddlylink:hover {\n\ttext-decoration: none;\n}\n\n.tc-page-controls img {\n\twidth: 1em;\n}\n\n.tc-page-controls svg {\n\tfill: <<colour sidebar-controls-foreground>>;\n}\n\n.tc-page-controls button:hover svg, .tc-page-controls a:hover svg {\n\tfill: <<colour sidebar-controls-foreground-hover>>;\n}\n\n.tc-sidebar-lists .tc-menu-list-item {\n\twhite-space: nowrap;\n}\n\n.tc-menu-list-count {\n\tfont-weight: bold;\n}\n\n.tc-menu-list-subitem {\n\tpadding-left: 7px;\n}\n\n.tc-story-river {\n\tposition: relative;\n}\n\n@media (max-width: <<sidebarbreakpoint-minus-one>>) {\n\n\t.tc-sidebar-header {\n\t\tpadding: 14px;\n\t\tmin-height: 32px;\n\t\tmargin-top: {{$:/themes/tiddlywiki/vanilla/metrics/storytop}};\n\t\ttransition:  min-height {{$:/config/AnimationDuration}}ms ease-in-out, padding-top {{$:/config/AnimationDuration}}ms ease-in-out, padding-bottom {{$:/config/AnimationDuration}}ms ease-in-out;\n\t}\n\n\t<<if-no-sidebar \"\"\"\n\n\t\t.tc-sidebar-header {\n\t\t\tmin-height: 0;\n\t\t\tpadding-top: 0;\n\t\t\tpadding-bottom: 0;\n\t\t}\n\n\t\"\"\">>\n\n\t.tc-story-river {\n\t\tposition: relative;\n\t\tpadding: 0;\n\t}\n}\n\n@media (min-width: <<sidebarbreakpoint>>) {\n\n\t.tc-message-box {\n\t\tmargin: 21px -21px 21px -21px;\n\t}\n\n\t.tc-sidebar-scrollable {\n\t\tposition: fixed;\n\t\ttop: {{$:/themes/tiddlywiki/vanilla/metrics/storytop}};\n\t\tleft: {{$:/themes/tiddlywiki/vanilla/metrics/storyright}};\n\t\tbottom: 0;\n\t\tright: 0;\n\t\toverflow-y: auto;\n\t\toverflow-x: auto;\n\t\t-webkit-overflow-scrolling: touch;\n\t\tmargin: 0 0 0 -42px;\n\t\tpadding: 71px 0 28px 42px;\n\t}\n\n\thtml[dir=\"rtl\"] .tc-sidebar-scrollable {\n\t\tleft: auto;\n\t\tright: {{$:/themes/tiddlywiki/vanilla/metrics/storyright}};\n\t}\n\n\t.tc-story-river {\n\t\tposition: relative;\n\t\tleft: {{$:/themes/tiddlywiki/vanilla/metrics/storyleft}};\n\t\ttop: {{$:/themes/tiddlywiki/vanilla/metrics/storytop}};\n\t\twidth: {{$:/themes/tiddlywiki/vanilla/metrics/storywidth}};\n\t\tpadding: 42px 42px 42px 42px;\n\t}\n\n<<if-no-sidebar \"\n\n\t.tc-story-river {\n\t\twidth: calc(100% - {{$:/themes/tiddlywiki/vanilla/metrics/storyleft}});\n\t}\n\n\">>\n\n\t.tc-story-river.tc-static-story-river {\n\t\tmargin-right: 0;\n\t\tpadding-right: 42px;\n\t}\n\n}\n\n@media print {\n\n\tbody.tc-body {\n\t\tbackground-color: transparent;\n\t}\n\n\t.tc-sidebar-header, .tc-topbar {\n\t\tdisplay: none;\n\t}\n\n\t.tc-story-river {\n\t\tmargin: 0;\n\t\tpadding: 0;\n\t}\n\n\t.tc-story-river .tc-tiddler-frame {\n\t\tmargin: 0;\n\t\tborder: none;\n\t\tpadding: 0;\n\t}\n}\n\n/*\n** Tiddler styles\n*/\n\n.tc-tiddler-frame {\n\tposition: relative;\n\tmargin-bottom: 28px;\n\tbackground-color: <<colour tiddler-background>>;\n\tborder: 1px solid <<colour tiddler-border>>;\n}\n\n{{$:/themes/tiddlywiki/vanilla/sticky}}\n\n.tc-tiddler-info {\n\toverflow: hidden;\n\tpadding: 14px 42px 14px 42px;\n\tbackground-color: <<colour tiddler-info-background>>;\n\tborder-top: 1px solid <<colour tiddler-info-border>>;\n\tborder-bottom: 1px solid <<colour tiddler-info-border>>;\n}\n\n.tc-tiddler-info p {\n\tmargin-top: 3px;\n\tmargin-bottom: 3px;\n}\n\n.tc-tiddler-info .tc-tab-buttons button.tc-tab-selected {\n\tbackground-color: <<colour tiddler-info-tab-background>>;\n\tborder-bottom: 1px solid <<colour tiddler-info-tab-background>>;\n}\n\n@media (max-width: <<sidebarbreakpoint-minus-one>>) {\n\n\t.tc-tiddler-info {\n\t\tpadding: 14px 14px 14px 14px;\n\t}\n\n}\n\n.tc-view-field-table {\n\twidth: 100%;\n}\n\n.tc-view-field-name {\n\twidth: 1%; /* Makes this column be as narrow as possible */\n\twhite-space: nowrap;\n\tvertical-align: top;\n\ttext-align: right;\n\tfont-style: italic;\n\tfont-weight: normal;\n}\n\n.tc-view-field-value {\n\tword-break: break-all;\n}\n\n@media (max-width: <<sidebarbreakpoint-minus-one>>) {\n\t.tc-tiddler-frame {\n\t\tpadding: 14px 14px 14px 14px;\n\t\tmargin-bottom: .5em;\n\t}\n\n\t.tc-tiddler-info {\n\t\tmargin: 0 -14px 0 -14px;\n\t}\n}\n\n@media (min-width: <<sidebarbreakpoint>>) {\n\t.tc-tiddler-frame {\n\t\tpadding: 28px 42px 42px 42px;\n\t\twidth: {{$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth}};\n\t\tborder-radius: 2px;\n\t}\n\n<<if-no-sidebar \"\n\n\t.tc-tiddler-frame {\n\t\twidth: 100%;\n\t}\n\n\">>\n\n\t.tc-tiddler-info {\n\t\tmargin: 0 -42px 0 -42px;\n\t}\n}\n\n.tc-site-title,\n.tc-titlebar {\n\tfont-weight: normal;\n\tfont-size: 2.35em;\n\tline-height: 1.35em;\n\tcolor: <<colour tiddler-title-foreground>>;\n\tmargin: 0;\n}\n\n.tc-site-title {\n\tcolor: <<colour site-title-foreground>>;\n}\n\n.tc-tiddler-title-icon {\n\tvertical-align: middle;\n\tmargin-right: .1em;\n}\n\n.tc-tiddler-title-icon svg {\n\twidth: 0.9em;\n\theight: 0.9em;\n}\n\n.tc-system-title-prefix {\n\tcolor: <<colour muted-foreground>>;\n}\n\n.tc-tiddler-lazy-loading {\n\theight: 4px;\n\twidth: 100%;\n\tbackground: no-repeat linear-gradient(<<colour background>> 0 0),no-repeat linear-gradient(<<colour background>> 0 0),<<colour primary>>;\n\tbackground-size: 60% 100%;\n\tanimation: animation-loading-progress 3s infinite;\n}\n\n@keyframes animation-loading-progress {\n\t0%   {background-position:-150% 0,-150% 0}\n\t66%  {background-position: 250% 0,-150% 0}\n\t100% {background-position: 250% 0, 250% 0}\n}\n\n.tc-titlebar h2 {\n\tfont-size: 1em;\n\tdisplay: inline;\n}\n\n.tc-titlebar img {\n\theight: 1em;\n}\n\n.tc-subtitle {\n\tfont-size: 0.9em;\n\tcolor: <<colour tiddler-subtitle-foreground>>;\n\tfont-weight: normal;\n}\n\n.tc-subtitle .tc-tiddlylink {\n\tmargin-right: .3em;\n}\n\n.tc-tiddler-missing .tc-title {\n\tfont-style: italic;\n\tfont-weight: normal;\n}\n\n.tc-tiddler-frame .tc-tiddler-controls {\n\tfloat: right;\n\tpadding: 3px; /* make space for outline */\n}\n\n.tc-tiddler-controls .tc-drop-down {\n\tfont-size: 0.6em;\n}\n\n.tc-tiddler-controls .tc-drop-down .tc-drop-down {\n\tfont-size: 1em;\n}\n\n.tc-tiddler-controls > span > button,\n.tc-tiddler-controls > span > span > button,\n.tc-tiddler-controls > span > span > span > button {\n\tvertical-align: baseline;\n\tmargin-left:5px;\n}\n\n.tc-tiddler-controls button svg, .tc-tiddler-controls button img,\n.tc-search button svg, .tc-search a svg {\n\tfill: <<colour tiddler-controls-foreground>>;\n}\n\n.tc-tiddler-controls button svg, .tc-tiddler-controls button img {\n\theight: 0.75em;\n}\n\n.tc-search button svg, .tc-search a svg {\n\theight: 1.2em;\n\twidth: 1.2em;\n\tmargin: 0 0.25em;\n}\n\n.tc-tiddler-controls button.tc-selected svg,\n.tc-page-controls button.tc-selected svg  {\n\tfill: <<colour tiddler-controls-foreground-selected>>;\n}\n\n.tc-tiddler-controls button.tc-btn-invisible:hover svg,\n.tc-search button:hover svg, .tc-search a:hover svg {\n\tfill: <<colour tiddler-controls-foreground-hover>>;\n}\n\n@media print {\n\t.tc-tiddler-controls {\n\t\tdisplay: none;\n\t}\n}\n\n.tc-tiddler-help { /* Help prompts within tiddler template */\n\tcolor: <<colour muted-foreground>>;\n\tmargin-top: 14px;\n}\n\n.tc-tiddler-help a.tc-tiddlylink {\n\tcolor: <<colour very-muted-foreground>>;\n}\n\n.tc-tiddler-frame .tc-edit-texteditor {\n\twidth: 100%;\n\tmargin: 4px 0 4px 0;\n}\n\n.tc-tiddler-frame input.tc-edit-texteditor,\n.tc-tiddler-frame textarea.tc-edit-texteditor,\n.tc-tiddler-frame iframe.tc-edit-texteditor,\n.tc-tiddler-frame select.tc-edit-texteditor {\n\tpadding: 3px 3px 3px 3px;\n\tborder: 1px solid <<colour tiddler-editor-border>>;\n\tline-height: 1.3em;\n\tfont-family: {{$:/themes/tiddlywiki/vanilla/settings/editorfontfamily}};\n}\n\n.tc-tiddler-frame input.tc-edit-texteditor,\n.tc-tiddler-frame textarea.tc-edit-texteditor,\n.tc-tiddler-frame iframe.tc-edit-texteditor {\n\t-webkit-appearance: none;\n}\n\n.tc-tiddler-frame input.tc-edit-texteditor,\n.tc-tiddler-frame select.tc-edit-texteditor,\n.tc-tiddler-frame textarea.tc-edit-texteditor {\n\tbackground-color: <<colour tiddler-editor-background>>;\n}\n\n.tc-tiddler-frame iframe.tc-edit-texteditor {\n\tbackground-color: <<colour tiddler-background>>;\n}\n\n.tc-tiddler-frame .tc-edit-fields input.tc-edit-fieldeditor,\n.tc-tiddler-frame .tc-edit-fields select.tc-edit-fieldeditor,\n.tc-tiddler-frame .tc-edit-fields textarea.tc-edit-fieldeditor {\n\tmargin: 0;\n\tpadding: 2px 3px;\n}\n\n.tc-tiddler-frame .tc-binary-warning {\n\twidth: 100%;\n\theight: 5em;\n\ttext-align: center;\n\tpadding: 3em 3em 6em 3em;\n\tbackground: <<colour alert-background>>;\n\tborder: 1px solid <<colour alert-border>>;\n}\n\ncanvas.tc-edit-bitmapeditor  {\n\tborder: 6px solid <<colour tiddler-editor-border-image>>;\n\tcursor: crosshair;\n\t-moz-user-select: none;\n\t-webkit-user-select: none;\n\t-ms-user-select: none;\n\tmargin-top: 6px;\n\tmargin-bottom: 6px;\n}\n\n.tc-edit-bitmapeditor-width {\n\tdisplay: block;\n}\n\n.tc-edit-bitmapeditor-height {\n\tdisplay: block;\n}\n\n.tc-single-tiddler-window .tc-tiddler-body,\n.tc-tiddler-frame .tc-tiddler-body {\n\tfont-size: {{$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize}};\n\tline-height: {{$:/themes/tiddlywiki/vanilla/metrics/bodylineheight}};\n}\n\n.tc-titlebar, .tc-tiddler-edit-title {\n\toverflow: hidden; /* https://github.com/TiddlyWiki/TiddlyWiki5/issues/282 */\n}\n\n/*\n* Tiddler in a new window.\n* Also see: .tc-single-tiddler-window .tc-tiddler-body, above\n*/\n\nhtml body.tc-body.tc-single-tiddler-window {\n\tmargin: 1em;\n\tbackground: <<colour tiddler-background>>;\n}\n\n.tc-single-tiddler-window img,\n.tc-single-tiddler-window svg,\n.tc-single-tiddler-window canvas,\n.tc-single-tiddler-window embed,\n.tc-single-tiddler-window iframe {\n\tmax-width: 100%;\n}\n\n/*\n** Editor\n*/\n\n.tc-editor-toolbar {\n\tmargin-top: 8px;\n}\n\n.tc-tiddler-frame .tc-tiddler-editor.tc-tiddler-preview .tc-editor-toolbar,\n.tc-tiddler-frame .tc-tiddler-editor.tc-tiddler-preview-hidden .tc-editor-toolbar {\n\tgrid-area: toolbar;\n}\n\n.tc-editor-toolbar button {\n\tvertical-align: middle;\n\tbackground-color: <<colour tiddler-controls-foreground>>;\n\tcolor: <<colour tiddler-controls-foreground-selected>>;\n\tfill: <<colour tiddler-controls-foreground-selected>>;\n\tborder-radius: 4px;\n\tpadding: 3px;\n\tmargin: 2px 0 2px 4px;\n}\n\n.tc-editor-toolbar button.tc-text-editor-toolbar-item-adjunct {\n\tmargin-left: 1px;\n\twidth: 1em;\n\tborder-radius: 8px;\n}\n\n.tc-editor-toolbar button.tc-text-editor-toolbar-item-start-group {\n\tmargin-left: 11px;\n}\n\n.tc-editor-toolbar button.tc-selected {\n\tbackground-color: <<colour primary>>;\n}\n\n.tc-editor-toolbar button svg {\n\twidth: 1.6em;\n\theight: 1.2em;\n}\n\n.tc-editor-toolbar .tc-drop-down button.tc-btn-mini {\n\tpadding: 2px 4px;\n}\n\n.tc-editor-toolbar button:hover {\n\tbackground-color: <<colour tiddler-controls-foreground-selected>>;\n\tfill: <<colour background>>;\n\tcolor: <<colour background>>;\n}\n\n.tc-editor-toolbar .tc-text-editor-toolbar-more {\n\twhite-space: normal;\n}\n\n.tc-editor-toolbar .tc-text-editor-toolbar-more button {\n\tdisplay: inline-block;\n\tpadding: 3px;\n\twidth: auto;\n}\n\n.tc-editor-toolbar .tc-search-results {\n\tpadding: 0;\n}\n\n.tc-editor-toolbar button.tc-editortoolbar-stamp-button + .tc-popup .tc-drop-down > p {\n\tmargin: 0;\n\tpadding: 0;\n}\n\n.tc-editor-toolbar button.tc-editortoolbar-stamp-button + .tc-popup .tc-drop-down a.tc-tiddlylink {\n\tfont-weight: normal;\n}\n\n/*\n** Adjustments for fluid-fixed mode\n*/\n\n@media (min-width: <<sidebarbreakpoint>>) {\n\n<<if-fluid-fixed text:\"\"\"\n\n\t.tc-story-river {\n\t\tpadding-right: 0;\n\t\tposition: relative;\n\t\twidth: auto;\n\t\tleft: 0;\n\t\tmargin-left: {{$:/themes/tiddlywiki/vanilla/metrics/storyleft}};\n\t\tmargin-right: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth}};\n\t}\n\n\t.tc-tiddler-frame {\n\t\twidth: 100%;\n\t}\n\n\t.tc-sidebar-scrollable {\n\t\tleft: auto;\n\t\tbottom: 0;\n\t\tright: 0;\n\t\twidth: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth}};\n\t}\n\n\tbody.tc-body .tc-page-container.tc-page-view-zoomin .tc-tiddler-frame {\n\t\twidth: 100%;\n\t\twidth: calc(100% - 42px);\n\t}\n\n\"\"\" hiddenSidebarText:\"\"\"\n\n\t.tc-story-river {\n\t\tpadding-right: 3em;\n\t\tmargin-right: 0;\n\t}\n\n\tbody.tc-body .tc-page-container.tc-page-view-zoomin .tc-tiddler-frame {\n\t\twidth: 100%;\n\t\twidth: calc(100% - 84px);\n\t}\n\n\"\"\">>\n\n}\n\n/*\n** Toolbar buttons\n*/\n\n.tc-page-controls svg.tc-image-new-button {\n\tfill: <<colour toolbar-new-button>>;\n}\n\n.tc-page-controls svg.tc-image-options-button {\n\tfill: <<colour toolbar-options-button>>;\n}\n\n.tc-page-controls svg.tc-image-save-button {\n\tfill: <<colour toolbar-save-button>>;\n}\n\n.tc-tiddler-controls button svg.tc-image-info-button {\n\tfill: <<colour toolbar-info-button>>;\n}\n\n.tc-tiddler-controls button svg.tc-image-edit-button {\n\tfill: <<colour toolbar-edit-button>>;\n}\n\n.tc-tiddler-controls button svg.tc-image-close-button {\n\tfill: <<colour toolbar-close-button>>;\n}\n\n.tc-tiddler-controls button svg.tc-image-delete-button {\n\tfill: <<colour toolbar-delete-button>>;\n}\n\n.tc-tiddler-controls button svg.tc-image-cancel-button {\n\tfill: <<colour toolbar-cancel-button>>;\n}\n\n.tc-tiddler-controls button svg.tc-image-done-button {\n\tfill: <<colour toolbar-done-button>>;\n}\n\n.tc-page-controls svg.tc-image-layout-button {\n\tfill: <<colour toolbar-options-button>>;\n}\n\n/*\n** Tiddler edit mode\n*/\n\n.tc-tiddler-edit-frame em.tc-edit {\n\tcolor: <<colour muted-foreground>>;\n\tfont-style: normal;\n}\n\n.tc-edit-type-dropdown a.tc-tiddlylink-missing {\n\tfont-style: normal;\n}\n\n.tc-type-selector .tc-edit-typeeditor {\n\twidth: auto;\n}\n\n.tc-type-selector-dropdown-wrapper {\n\tdisplay: inline-block;\n}\n\n<<set-type-selector-min-width>>\n\n.tc-edit-tags {\n\tborder: 1px solid <<colour tiddler-editor-border>>;\n\tpadding: 4px 8px 4px 8px;\n}\n\n.tc-edit-add-tag {\n\tdisplay: inline-block;\n}\n\n.tc-edit-add-tag .tc-add-tag-name input {\n\twidth: 50%;\n}\n\n.tc-edit-add-tag .tc-keyboard {\n\tdisplay:inline;\n}\n\n.tc-edit-tags .tc-tag-label {\n\tdisplay: inline-block;\n}\n\n.tc-edit-tags-list {\n\tmargin: 14px 0 14px 0;\n}\n\n.tc-remove-tag-button {\n\tpadding-left: 4px;\n}\n\n.tc-tiddler-editor {\n\tdisplay: grid;\n}\n\n.tc-tiddler-frame .tc-tiddler-editor.tc-tiddler-preview {\n\tgrid-template-areas:\n\t\t\"toolbar toolbar\"\n\t\t\"editor preview\";\n\tgrid-template-columns: repeat(2, minmax(0px, 1fr));\n\tgrid-template-rows: auto 1fr;\n}\n\n.tc-tiddler-frame .tc-tiddler-editor.tc-tiddler-preview-hidden {\n\tgrid-template-areas:\n\t\t\"toolbar\"\n\t\t\"editor\";\n\tgrid-template-columns: 1fr;\n\tgrid-template-rows: auto 1fr;\n}\n\n.tc-tiddler-frame .tc-tiddler-editor.tc-tiddler-preview .tc-tiddler-preview-preview {\n\tgrid-area: preview;\n\toverflow-wrap: anywhere;\n\tword-break: normal;\n\tborder: 1px solid <<colour tiddler-editor-border>>;\n\tmargin: 4px 0 3px 3px;\n\tpadding: 3px 3px 3px 3px;\n}\n\n<<if-editor-height-fixed then:\"\"\"\n\n.tc-tiddler-preview-preview {\n\toverflow-y: scroll;\n\theight: {{$:/config/TextEditor/EditorHeight/Height}};\n}\n\n\"\"\">>\n\n.tc-tiddler-frame .tc-tiddler-editor.tc-tiddler-preview .tc-edit-texteditor,\n.tc-tiddler-frame .tc-tiddler-editor.tc-tiddler-preview-hidden .tc-edit-texteditor {\n\tgrid-area: editor;\n}\n\n.tc-tiddler-frame .tc-tiddler-editor.tc-tiddler-preview canvas.tc-edit-bitmapeditor,\n.tc-tiddler-frame .tc-tiddler-editor.tc-tiddler-preview-hidden canvas.tc-edit-bitmapeditor {\n\tgrid-area: editor;\n\tmax-width: 100%;\n}\n\n.tc-edit-fields {\n\twidth: 100%;\n}\n\n.tc-edit-fields.tc-edit-fields-small {\n\tmargin-top: 0;\n\tmargin-bottom: 0;\n}\n\n.tc-edit-fields table, .tc-edit-fields tr, .tc-edit-fields td {\n\tborder: none;\n\tpadding: 4px;\n}\n\n.tc-edit-fields > tbody > .tc-edit-field:nth-child(odd) {\n\tbackground-color: <<colour tiddler-editor-fields-odd>>;\n}\n\n.tc-edit-fields > tbody > .tc-edit-field:nth-child(even) {\n\tbackground-color: <<colour tiddler-editor-fields-even>>;\n}\n\n.tc-edit-field-name {\n\ttext-align: right;\n}\n\n.tc-edit-field-value input {\n\twidth: 100%;\n}\n\n.tc-edit-field-remove {\n}\n\n.tc-edit-field-remove svg {\n\theight: 1em;\n\twidth: 1em;\n\tfill: <<colour muted-foreground>>;\n\tvertical-align: middle;\n}\n\n.tc-edit-field-add-name-wrapper input.tc-edit-texteditor {\n\twidth: auto;\n}\n\n.tc-edit-field-add-name-wrapper {\n\tdisplay: inline-block;\n}\n\n.tc-edit-field-add-value {\n\tdisplay: inline-block;\n}\n\n@media (min-width: <<sidebarbreakpoint>>) {\n\n\t.tc-edit-field-add-value {\n\t\twidth: 35%;\n\t}\n\n}\n\n.tc-edit-field-add-button {\n\tdisplay: inline-block;\n\twidth: 10%;\n}\n\n\n/*\n** Tiddler editor dropzone\n*/\n\n.tc-dropzone-editor {\n\tposition:relative;\n}\n\n.tc-dropzone-editor.tc-dragover .tc-editor-toolbar::after{\n\tz-index: 10000;\n\ttop:0;\n\tleft:0;\n\tright:0;\n\theight: 100%;\n\tbackground: <<colour dropzone-background>>;\n\tcontent: \"<<lingo DropMessage>>\";\n\tpointer-events: none;\n\tposition: absolute;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tbackground-color: <<color background>>;\n\tborder: 4px dashed <<color modal-border>>;\n\tfont-weight: bold;\n\tfont-size: 150%;\n\topacity: 0.8;\n\tcolor: <<color foreground>>;\n}\n\n.tc-editor-importpopup {\n\twidth: 100%;\n\theight: 100%;\n}\n\n.tc-editor-import {\n\tposition: absolute;\n\ttop: 50%;\n\tleft: 50%;\n\ttransform: translate(-50%, -50%);\n\tbackground: <<color pre-background>>;\n\tbox-shadow: 2px 2px 10px <<colour foreground>>;\n\tpadding: 10px;\n\twidth: 96%;\n\tborder: 1px solid <<color tiddler-controls-foreground>>;\n\ttext-align:center;\n}\n\n.tc-editor-import img {\n\tmax-height: 500px;\n}\n\n/*\n** Storyview Classes\n*/\n\n.tc-viewswitcher .tc-image-button {\n\tmargin-right: .3em;\n}\n\n.tc-page-container.tc-page-view-zoomin .tc-tiddler-frame {\n\tposition: absolute;\n\tdisplay: block;\n\twidth: 100%;\n}\n\n@media (min-width: <<sidebarbreakpoint>>) {\n\n\t.tc-page-container.tc-page-view-zoomin .tc-tiddler-frame {\n\t\twidth: calc(100% - 84px);\n\t}\n\n}\n\n/*\n** Dropdowns\n*/\n\n.tc-btn-dropdown {\n\ttext-align: left;\n}\n\n.tc-btn-dropdown svg, .tc-btn-dropdown img {\n\theight: 1em;\n\twidth: 1em;\n\tfill: <<colour muted-foreground>>;\n}\n\n.tc-drop-down-wrapper {\n\tposition: relative;\n}\n\n.tc-drop-down {\n\tmin-width: 380px;\n\tborder: 1px solid <<colour dropdown-border>>;\n\tbackground-color: <<colour dropdown-background>>;\n\tpadding: 7px 0 7px 0;\n\tmargin: 4px 0 0 0;\n\twhite-space: nowrap;\n\ttext-shadow: none;\n\tline-height: 1.4;\n}\n\n.tc-drop-down .tc-drop-down {\n\tmargin-left: 14px;\n}\n\n.tc-drop-down button svg, .tc-drop-down a svg  {\n\tfill: <<colour foreground>>;\n}\n\n.tc-drop-down button:disabled svg {\n\tfill: <<colour muted-foreground>>;\n}\n\n.tc-drop-down button.tc-btn-invisible:hover svg {\n\tfill: <<colour background>>;\n}\n\n.tc-drop-down .tc-drop-down-info {\n\tpadding-left: 14px;\n}\n\n.tc-drop-down p {\n\tpadding: 0 14px 0 14px;\n}\n\n.tc-drop-down svg {\n\twidth: 1em;\n\theight: 1em;\n}\n\n.tc-drop-down img {\n\twidth: 1em;\n}\n\n.tc-drop-down a, .tc-drop-down button {\n\tdisplay: block;\n\tpadding: 0 14px 0 14px;\n\twidth: 100%;\n\ttext-align: left;\n\tcolor: <<colour foreground>>;\n\tline-height: 1.4;\n}\n\n.tc-drop-down .tc-tab-set .tc-tab-buttons button {\n\tdisplay: inline-block;\n\twidth: auto;\n\tmargin-bottom: 0px;\n\tborder-bottom-left-radius: 0;\n\tborder-bottom-right-radius: 0;\n}\n\n.tc-drop-down .tc-prompt {\n\tpadding: 0 14px;\n}\n\n.tc-drop-down .tc-chooser {\n\tborder: none;\n}\n\n.tc-drop-down .tc-chooser .tc-swatches-horiz {\n\tfont-size: 0.4em;\n\tpadding-left: 1.2em;\n}\n\n.tc-drop-down .tc-file-input-wrapper {\n\twidth: 100%;\n}\n\n.tc-drop-down .tc-file-input-wrapper button {\n\tcolor: <<colour foreground>>;\n}\n\n.tc-drop-down a:hover, .tc-drop-down button:hover, .tc-drop-down .tc-file-input-wrapper:hover button {\n\tcolor: <<colour tiddler-link-background>>;\n\tbackground-color: <<colour tiddler-link-foreground>>;\n\ttext-decoration: none;\n}\n\n.tc-drop-down .tc-tab-buttons button {\n\tbackground-color: <<colour dropdown-tab-background>>;\n}\n\n.tc-drop-down .tc-tab-buttons button.tc-tab-selected {\n\tbackground-color: <<colour dropdown-tab-background-selected>>;\n\tborder-bottom: 1px solid <<colour dropdown-tab-background-selected>>;\n}\n\n.tc-drop-down-bullet {\n\tdisplay: inline-block;\n\twidth: 0.5em;\n}\n\n.tc-drop-down .tc-tab-contents a {\n\tpadding: 0 0.5em 0 0.5em;\n}\n\n.tc-block-dropdown-wrapper {\n\tposition: relative;\n}\n\n.tc-block-dropdown {\n\tposition: absolute;\n\tmin-width: 220px;\n\tborder: 1px solid <<colour dropdown-border>>;\n\tbackground-color: <<colour dropdown-background>>;\n\tpadding: 7px 0;\n\tmargin: 4px 0 0 0;\n\twhite-space: nowrap;\n\tz-index: 1000;\n\ttext-shadow: none;\n}\n\n.tc-block-dropdown.tc-search-drop-down {\n\tmargin-left: -12px;\n}\n\n.tc-block-dropdown a {\n\tdisplay: block;\n\tpadding: 4px 14px 4px 14px;\n}\n\n.tc-block-dropdown.tc-search-drop-down a {\n\tdisplay: block;\n\tpadding: 0px 10px 0px 10px;\n}\n\n.tc-drop-down .tc-dropdown-item-plain,\n.tc-block-dropdown .tc-dropdown-item-plain {\n\tpadding: 4px 14px 4px 7px;\n}\n\n.tc-drop-down .tc-dropdown-item,\n.tc-block-dropdown .tc-dropdown-item {\n\tpadding: 4px 14px 4px 7px;\n\tcolor: <<colour muted-foreground>>;\n}\n\n.tc-block-dropdown a.tc-tiddlylink:hover {\n\tcolor: <<colour tiddler-link-background>>;\n\tbackground-color: <<colour tiddler-link-foreground>>;\n\ttext-decoration: none;\n}\n\n.tc-search-results {\n\tpadding: 0 7px 0 7px;\n}\n\n.tc-image-chooser, .tc-colour-chooser {\n\twhite-space: normal;\n}\n\n.tc-image-chooser a,\n.tc-colour-chooser a {\n\tdisplay: inline-block;\n\tvertical-align: top;\n\ttext-align: center;\n\tposition: relative;\n}\n\n.tc-image-chooser a {\n\tborder: 1px solid <<colour muted-foreground>>;\n\tpadding: 2px;\n\tmargin: 2px;\n\twidth: 4em;\n\theight: 4em;\n}\n\n.tc-colour-chooser a {\n\tpadding: 3px;\n\twidth: 2em;\n\theight: 2em;\n\tvertical-align: middle;\n}\n\n.tc-image-chooser a:hover,\n.tc-colour-chooser a:hover {\n\tbackground: <<colour primary>>;\n\tpadding: 0px;\n\tborder: 3px solid <<colour primary>>;\n}\n\n.tc-image-chooser a svg,\n.tc-image-chooser a img {\n\tdisplay: inline-block;\n\twidth: auto;\n\theight: auto;\n\tmax-width: 3.5em;\n\tmax-height: 3.5em;\n\tposition: absolute;\n\ttop: 0;\n\tbottom: 0;\n\tleft: 0;\n\tright: 0;\n\tmargin: auto;\n}\n\n/* Make search dropdown visible on small screens. issue #7003 */\n@media (max-width: <<sidebarbreakpoint>>) {\n\n\t.tc-sidebar-search .tc-block-dropdown-wrapper {\n\t\tposition: initial;\n\t}\n\n}\n\n/*\n** Modals\n*/\n\n.tc-modal-wrapper {\n\tposition: fixed;\n\toverflow: auto;\n\toverflow-y: scroll;\n\ttop: 0;\n\tright: 0;\n\tbottom: 0;\n\tleft: 0;\n\tz-index: 900;\n}\n\n.tc-modal-backdrop {\n\tposition: fixed;\n\ttop: 0;\n\tright: 0;\n\tbottom: 0;\n\tleft: 0;\n\tz-index: 1000;\n\tbackground-color: <<colour modal-backdrop>>;\n}\n\n.tc-modal {\n\tz-index: 1100;\n\tbackground-color: <<colour modal-background>>;\n\tborder: 1px solid <<colour modal-border>>;\n}\n\n@media (max-width: 55em) {\n\t.tc-modal {\n\t\tposition: fixed;\n\t\ttop: 1em;\n\t\tleft: 1em;\n\t\tright: 1em;\n\t}\n\n\t.tc-modal-body {\n\t\toverflow-y: auto;\n\t\tmax-height: 400px;\n\t\tmax-height: 60vh;\n\t}\n}\n\n@media (min-width: 55em) {\n\t.tc-modal {\n\t\tposition: fixed;\n\t\ttop: 2em;\n\t\tleft: 25%;\n\t\twidth: 50%;\n\t}\n\n\t.tc-modal-body {\n\t\toverflow-y: auto;\n\t\tmax-height: 400px;\n\t\tmax-height: 60vh;\n\t}\n}\n\n.tc-modal-header {\n\tpadding: 9px 15px;\n\tborder-bottom: 1px solid <<colour modal-header-border>>;\n}\n\n.tc-modal-header h3 {\n\tmargin: 0;\n\tline-height: 30px;\n}\n\n.tc-modal-header img, .tc-modal-header svg {\n\twidth: 1em;\n\theight: 1em;\n}\n\n.tc-modal-body {\n\tpadding: 15px;\n}\n\n.tc-modal-footer {\n\tpadding: 14px 15px 15px;\n\tmargin-bottom: 0;\n\ttext-align: right;\n\tbackground-color: <<colour modal-footer-background>>;\n\tborder-top: 1px solid <<colour modal-footer-border>>;\n}\n\n.tc-modal-prevent-scroll {\n\toverflow: hidden;\n}\n\n/*\n** Centered modals\n*/\n.tc-modal-centered .tc-modal {\n\twidth: auto;\n\ttop: 50%;\n\tleft: 50%;\n\ttransform: translate(-50%, -50%) !important;\n}\n\n/*\n** Notifications\n*/\n\n.tc-notification {\n\tposition: fixed;\n\ttop: 14px;\n\tright: 42px;\n\tz-index: 1300;\n\tmax-width: 280px;\n\tpadding: 0 14px 0 14px;\n\tbackground-color: <<colour notification-background>>;\n\tborder: 1px solid <<colour notification-border>>;\n}\n\n/*\n** Tabs\n*/\n\n.tc-tab-set.tc-vertical {\n\tdisplay: -webkit-flex;\n\tdisplay: flex;\n}\n\n.tc-tab-buttons {\n\tfont-size: 0.85em;\n\tpadding-top: 1em;\n\tmargin-bottom: -2px;\n}\n\n.tc-tab-buttons.tc-vertical  {\n\tz-index: 100;\n\tdisplay: block;\n\tpadding-top: 14px;\n\tvertical-align: top;\n\ttext-align: right;\n\tmargin-bottom: inherit;\n\tmargin-right: -1px;\n\tmax-width: 33%;\n\t-webkit-flex: 0 0 auto;\n\tflex: 0 0 auto;\n}\n\n.tc-tab-buttons button.tc-tab-selected {\n\tcolor: <<colour tab-foreground-selected>>;\n\tbackground-color: <<colour tab-background-selected>>;\n\tborder-left: 1px solid <<colour tab-border-selected>>;\n\tborder-top: 1px solid <<colour tab-border-selected>>;\n\tborder-right: 1px solid <<colour tab-border-selected>>;\n}\n\n.tc-tab-buttons button {\n\tcolor: <<colour tab-foreground>>;\n\tpadding: 3px 5px 3px 5px;\n\tmargin-right: 0.3em;\n\tfont-weight: normal;\n\tborder: none;\n\tbackground: inherit;\n\tbackground-color: <<colour tab-background>>;\n\tborder-left: 1px solid <<colour tab-border>>;\n\tborder-top: 1px solid <<colour tab-border>>;\n\tborder-right: 1px solid <<colour tab-border>>;\n\tborder-top-left-radius: 2px;\n\tborder-top-right-radius: 2px;\n\tborder-bottom-left-radius: 0;\n\tborder-bottom-right-radius: 0;\n}\n\n.tc-tab-buttons.tc-vertical button {\n\tdisplay: block;\n\twidth: 100%;\n\tmargin-top: 3px;\n\tmargin-right: 0;\n\ttext-align: right;\n\tbackground-color: <<colour tab-background>>;\n\tborder-left: 1px solid <<colour tab-border>>;\n\tborder-bottom: 1px solid <<colour tab-border>>;\n\tborder-right: none;\n\tborder-top-left-radius: 2px;\n\tborder-bottom-left-radius: 2px;\n\tborder-top-right-radius: 0;\n\tborder-bottom-right-radius: 0;\n}\n\n.tc-tab-buttons.tc-vertical button.tc-tab-selected {\n\tbackground-color: <<colour tab-background-selected>>;\n\tborder-right: 1px solid <<colour tab-background-selected>>;\n}\n\n.tc-tab-divider {\n\tborder-top: 1px solid <<colour tab-divider>>;\n}\n\n.tc-tab-divider.tc-vertical  {\n\tdisplay: none;\n}\n\n.tc-tab-content {\n\tmargin-top: 14px;\n}\n\n.tc-tab-content.tc-vertical  {\n\tdisplay: inline-block;\n\tvertical-align: top;\n\tpadding-top: 0;\n\tpadding-left: 14px;\n\tborder-left: 1px solid <<colour tab-border>>;\n\t-webkit-flex: 1 0 70%;\n\tflex: 1 0 70%;\n\toverflow: auto;\n}\n\n.tc-sidebar-lists .tc-tab-buttons {\n\tmargin-bottom: -1px;\n}\n\n.tc-sidebar-lists .tc-tab-buttons button.tc-tab-selected {\n\tbackground-color: <<colour sidebar-tab-background-selected>>;\n\tcolor: <<colour sidebar-tab-foreground-selected>>;\n\tborder-left: 1px solid <<colour sidebar-tab-border-selected>>;\n\tborder-top: 1px solid <<colour sidebar-tab-border-selected>>;\n\tborder-right: 1px solid <<colour sidebar-tab-border-selected>>;\n}\n\n.tc-sidebar-lists .tc-tab-buttons button {\n\tbackground-color: <<colour sidebar-tab-background>>;\n\tcolor: <<colour sidebar-tab-foreground>>;\n\tborder-left: 1px solid <<colour sidebar-tab-border>>;\n\tborder-top: 1px solid <<colour sidebar-tab-border>>;\n\tborder-right: 1px solid <<colour sidebar-tab-border>>;\n}\n\n.tc-sidebar-lists .tc-tab-divider {\n\tborder-top: 1px solid <<colour sidebar-tab-divider>>;\n}\n\n.tc-more-sidebar > .tc-tab-set > .tc-tab-buttons > button {\n\tdisplay: block;\n\twidth: 100%;\n\tbackground-color: <<colour sidebar-tab-background>>;\n\tborder-top: none;\n\tborder-left: none;\n\tborder-bottom: none;\n\tborder-right: 1px solid #ccc;\n\tmargin-bottom: inherit;\n}\n\n.tc-more-sidebar > .tc-tab-set > .tc-tab-buttons > button.tc-tab-selected {\n\tbackground-color: <<colour sidebar-tab-background-selected>>;\n\tborder: none;\n}\n\n/*\n** Manager\n*/\n\n.tc-manager-wrapper {\n\n}\n\n.tc-manager-controls {\n\n}\n\n.tc-manager-control {\n\tmargin: 0.5em 0;\n}\n\n.tc-manager-control select {\n\tmax-width: 100%;\n}\n\n.tc-manager-list {\n\twidth: 100%;\n\tborder-top: 1px solid <<colour muted-foreground>>;\n\tborder-left: 1px solid <<colour muted-foreground>>;\n\tborder-right: 1px solid <<colour muted-foreground>>;\n}\n\n.tc-manager-list-item {\n\n}\n\n.tc-manager-list-item-heading {\n\tdisplay: block;\n\twidth: 100%;\n\ttext-align: left;\n\tborder-bottom: 1px solid <<colour muted-foreground>>;\n\tpadding: 3px;\n}\n\n.tc-manager-list-item-heading-selected {\n\tfont-weight: bold;\n\tcolor: <<colour background>>;\n\tfill: <<colour background>>;\n\tbackground-color: <<colour foreground>>;\n}\n\n.tc-manager-list-item-heading:hover {\n\tbackground: <<colour primary>>;\n\tcolor: <<colour background>>;\n}\n\n.tc-manager-list-item-content {\n\tdisplay: flex;\n}\n\n.tc-manager-list-item-content-sidebar {\n\tflex: 1 0;\n\tbackground: <<colour tiddler-editor-background>>;\n\tborder-right: 0.5em solid <<colour muted-foreground>>;\n\tborder-bottom: 0.5em solid <<colour muted-foreground>>;\n\twhite-space: nowrap;\n}\n\n.tc-manager-list-item-content-item-heading {\n\tdisplay: block;\n\twidth: 100%;\n\ttext-align: left;\n\tbackground: <<colour muted-foreground>>;\n\ttext-transform: uppercase;\n\tfont-size: 0.6em;\n\tfont-weight: bold;\n\tpadding: 0.5em 0 0.5em 0;\n}\n\n.tc-manager-list-item-content-item-body {\n\tpadding: 0 0.5em 0 0.5em;\n}\n\n.tc-manager-list-item-content-item-body > pre {\n\tmargin: 0.5em 0 0.5em 0;\n\tborder: none;\n\tbackground: inherit;\n}\n\n.tc-manager-list-item-content-tiddler {\n\tflex: 3 1;\n\tborder-left: 0.5em solid <<colour muted-foreground>>;\n\tborder-right: 0.5em solid <<colour muted-foreground>>;\n\tborder-bottom: 0.5em solid <<colour muted-foreground>>;\n}\n\n.tc-manager-list-item-content-item-body > table {\n\tborder: none;\n\tpadding: 0;\n\tmargin: 0;\n}\n\n.tc-manager-list-item-content-item-body > table td {\n\tborder: none;\n}\n\n.tc-manager-icon-editor > button {\n\twidth: 100%;\n}\n\n.tc-manager-icon-editor > button > svg,\n.tc-manager-icon-editor > button > button {\n\twidth: 100%;\n\theight: auto;\n}\n\n/*\n** Import table\n*/\n\n.tc-import-table {\n\twidth: 100%;\n}\n\n.tc-import-table svg.tc-image-edit-button {\n\tmax-width: unset;\n}\n\n.tc-import-table th:first-of-type {\n\twidth: 10%;\n}\n\n.tc-import-table th:last-of-type {\n\twidth: 30%;\n}\n\n.tc-import-table .tc-row-disabled {\n\tbackground: <<colour very-muted-foreground>>10;\n\topacity: 0.8;\n}\n\n.tc-import-table .tc-row-warning {\n\tbackground: <<colour diff-delete-background>>50;\n}\n\n/*\n** Alerts\n*/\n\n.tc-alerts {\n\tposition: fixed;\n\ttop: 28px;\n\tleft: 0;\n\tright: 0;\n\tmax-width: 50%;\n\tz-index: 20000;\n}\n\n.tc-alert {\n\tposition: relative;\n\tmargin: 14px;\n\tpadding: 7px;\n\tborder: 1px solid <<colour alert-border>>;\n\tbackground-color: <<colour alert-background>>;\n}\n\n.tc-alert-toolbar {\n\tposition: absolute;\n\ttop: 7px;\n\tright: 7px;\n\tline-height: 0;\n}\n\n.tc-alert-toolbar svg {\n\tfill: <<colour alert-muted-foreground>>;\n}\n\n.tc-alert-subtitle {\n\tcolor: <<colour alert-muted-foreground>>;\n\tfont-weight: bold;\n\tfont-size: 0.8em;\n\tmargin-bottom: 0.5em;\n}\n\n.tc-alert-body > p {\n\tmargin: 0;\n}\n\n.tc-alert-highlight {\n\tcolor: <<colour alert-highlight>>;\n}\n\n@media (min-width: <<sidebarbreakpoint>>) {\n\n\t.tc-static-alert {\n\t\tposition: relative;\n\t}\n\n\t.tc-static-alert-inner {\n\t\tposition: absolute;\n\t\tz-index: 100;\n\t}\n\n}\n\n.tc-static-alert-inner {\n\tpadding: 0 2px 2px 42px;\n\tcolor: <<colour static-alert-foreground>>;\n}\n\n/*\n** Floating drafts list\n*/\n\n.tc-drafts-list {\n\tz-index: 2000;\n\tposition: fixed;\n\tfont-size: 0.8em;\n\tleft: 0;\n\tbottom: 0;\n}\n\n.tc-drafts-list a {\n\tmargin: 0 0.5em;\n\tpadding: 4px 4px;\n\tborder-top-left-radius: 4px;\n\tborder-top-right-radius: 4px;\n\tborder: 1px solid <<colour background>>;\n\tborder-bottom: none;\n\tbackground: <<colour dirty-indicator>>;\n\tcolor: <<colour background>>;\n\tfill: <<colour background>>;\n}\n\n.tc-drafts-list a:hover {\n\ttext-decoration: none;\n\tbackground: <<colour foreground>>;\n\tcolor: <<colour background>>;\n\tfill: <<colour background>>;\n}\n\n.tc-drafts-list a svg {\n\twidth: 1em;\n\theight: 1em;\n\tvertical-align: text-bottom;\n}\n\n/*\n** Control panel\n*/\n\n.tc-control-panel td {\n\tpadding: 4px;\n}\n\n.tc-control-panel table, .tc-control-panel table input, .tc-control-panel table textarea {\n\twidth: 100%;\n}\n\n.tc-control-panel-setting {\n\tborder-top: 1px solid <<colour blockquote-bar>>;\n}\n\n.tc-plugin-info {\n\tdisplay: flex;\n\ttext-shadow: none;\n\tborder: 1px solid <<colour muted-foreground>>;\n\tfill: <<colour muted-foreground>>;\n\tbackground-color: <<colour background>>;\n\tmargin: 0.5em 0 0.5em 0;\n\tpadding: 4px;\n\talign-items: center;\n}\n\n.tc-sidebar-lists a.tc-tiddlylink.tc-plugin-info {\n\tcolor: <<colour tiddler-link-foreground>>;\n}\n\n\n.tc-plugin-info-sub-plugins .tc-plugin-info {\n\tmargin: 0.5em;\n\tbackground: <<colour background>>;\n}\n\n.tc-plugin-info-sub-plugin-indicator {\n\tmargin: -16px 1em 0 2em;\n}\n\n.tc-plugin-info-sub-plugin-indicator button {\n\tcolor: <<colour background>>;\n\tbackground: <<colour foreground>>;\n\tborder-radius: 8px;\n\tpadding: 2px 7px;\n\tfont-size: 0.75em;\n}\n\n.tc-plugin-info-sub-plugins .tc-plugin-info-dropdown {\n\tmargin-left: 1em;\n\tmargin-right: 1em;\n}\n\n.tc-plugin-info-disabled {\n\tbackground: -webkit-repeating-linear-gradient(45deg, #ff0, #ff0 10px, #eee 10px, #eee 20px);\n\tbackground: repeating-linear-gradient(45deg, #ff0, #ff0 10px, #eee 10px, #eee 20px);\n}\n\n.tc-plugin-info-disabled:hover {\n\tbackground: -webkit-repeating-linear-gradient(45deg, #aa0, #aa0 10px, #888 10px, #888 20px);\n\tbackground: repeating-linear-gradient(45deg, #aa0, #aa0 10px, #888 10px, #888 20px);\n}\n\na.tc-tiddlylink.tc-plugin-info:hover {\n\ttext-decoration: none;\n\tbackground-color: <<colour primary>>;\n\tcolor: <<colour background>>;\n\tfill: <<colour foreground>>;\n}\n\na.tc-tiddlylink.tc-plugin-info:hover > .tc-plugin-info-chunk > svg {\n\tfill: <<colour background>>;\n}\n\na.tc-tiddlylink.tc-plugin-info:hover > .tc-plugin-info-chunk .tc-plugin-info-stability {\n\tborder: 1px solid <<colour background>>;\n\tcolor: <<colour background>>;\n}\n\n.tc-plugin-info-chunk {\n\tmargin: 2px;\n}\n\n.tc-plugin-info-chunk.tc-plugin-info-toggle {\n\tflex-grow: 0;\n\tflex-shrink: 0;\n\tline-height: 1;\n}\n\n.tc-plugin-info-chunk.tc-plugin-info-icon {\n\tflex-grow: 0;\n\tflex-shrink: 0;\n\tline-height: 1;\n\theight: 2em;\n\twidth: 2em;\n\tdisplay: grid;\n}\n\n.tc-plugin-info-chunk.tc-plugin-info-description {\n\tflex-grow: 1;\n}\n\n.tc-plugin-info-chunk .tc-plugin-info-stability {\n\tmargin-right: 4px;\n\tpadding: 1px 3px;\n\tfont-size: 0.8em;\n\tborder-radius: 4px;\n\tfont-weight: bold;\n}\n\n.tc-plugin-info-chunk .tc-plugin-info-stability-stable {\n\tborder: 1px solid <<colour stability-stable>>;\n\tcolor: <<colour stability-stable>>;\n}\n\n.tc-plugin-info-chunk .tc-plugin-info-stability-experimental {\n\tborder: 1px solid <<colour stability-experimental>>;\n\tcolor: <<colour stability-experimental>>;\n}\n\n.tc-plugin-info-chunk .tc-plugin-info-stability-deprecated {\n\tborder: 1px solid <<colour stability-deprecated>>;\n\tcolor: <<colour stability-deprecated>>;\n}\n\n.tc-plugin-info-chunk .tc-plugin-info-stability-legacy {\n\tborder: 1px solid <<colour stability-legacy>>;\n\tcolor: <<colour stability-legacy>>;\n}\n\n.tc-plugin-info-chunk.tc-plugin-info-buttons {\n\tfont-size: 0.8em;\n\tline-height: 1.2;\n\tflex-grow: 0;\n\tflex-shrink: 0;\n\ttext-align: right;\n}\n\n.tc-plugin-info-chunk.tc-plugin-info-description h1 {\n\tfont-size: 1em;\n\tline-height: 1.2;\n\tmargin: 2px 0 2px 0;\n}\n\n.tc-plugin-info-chunk.tc-plugin-info-description h2 {\n\tfont-size: 0.8em;\n\tline-height: 1.2;\n\tmargin: 2px 0 2px 0;\n}\n\n.tc-plugin-info-chunk.tc-plugin-info-description div {\n\tfont-size: 0.8em;\n\tline-height: 1.2;\n\tmargin: 2px 0 2px 0;\n}\n\n.tc-plugin-info-chunk.tc-plugin-info-toggle img, .tc-plugin-info-chunk.tc-plugin-info-toggle svg {\n\twidth: 1em;\n\theight: 1em;\n}\n\n.tc-plugin-info-chunk.tc-plugin-info-icon img, .tc-plugin-info-chunk.tc-plugin-info-icon svg {\n\tmax-width: 2em;\n\tmax-height: 2em;\n\tmargin: auto;\n}\n\n.tc-plugin-info-dropdown {\n\tborder: 1px solid <<colour muted-foreground>>;\n\tbackground: <<colour background>>;\n\tmargin-top: -8px;\n}\n\n.tc-plugin-info-dropdown-message {\n\tbackground: <<colour message-background>>;\n\tpadding: 0.5em 1em 0.5em 1em;\n\tfont-weight: bold;\n\tfont-size: 0.8em;\n}\n\n.tc-plugin-info-dropdown-body {\n\tpadding: 1em 1em 0 1em;\n\tbackground: <<colour background>>;\n}\n\n.tc-plugin-info-sub-plugins {\n\tpadding: 0.5em;\n\tmargin: 0 1em 1em 1em;\n\tbackground: <<colour notification-background>>;\n}\n\n.tc-install-plugin {\n\tfont-weight: bold;\n\tbackground: green;\n\tcolor: white;\n\tfill: white;\n\tborder-radius: 4px;\n\tpadding: 3px;\n}\n\n.tc-install-plugin.tc-reinstall-downgrade {\n\tbackground: red;\n}\n\n.tc-install-plugin.tc-reinstall {\n\tbackground: blue;\n}\n\n.tc-install-plugin.tc-reinstall-upgrade {\n\tbackground: orange;\n}\n\n.tc-check-list {\n\tline-height: 2em;\n}\n\n.tc-check-list .tc-image-button {\n\theight: 1.5em;\n}\n\n/*\n** Message boxes\n*/\n\n.tc-message-box {\n\tborder: 1px solid <<colour message-border>>;\n\tbackground: <<colour message-background>>;\n\tpadding: 0px 21px 0px 21px;\n\tfont-size: 12px;\n\tline-height: 18px;\n\tcolor: <<colour message-foreground>>;\n}\n\n.tc-message-box svg {\n\twidth: 1em;\n\theight: 1em;\n\tvertical-align: text-bottom;\n}\n\n/*\n** Pictures\n*/\n\n.tc-bordered-image {\n\tborder: 1px solid <<colour muted-foreground>>;\n\tpadding: 5px;\n\tmargin: 5px;\n}\n\n/*\n** Floats\n*/\n\n.tc-float-right {\n\tfloat: right;\n}\n\n/* Float tc-clearfix. Needs to be used by elements that allow float:right in their content.\n** So the floating element does not overflow\n*/\n\n.tc-clearfix:after {\n\tcontent: \"\";\n\tclear: both;\n\tdisplay: table;\n}\n\n/* Fix overflow toc, manager and testcase output */\n.tc-tiddler-body .tc-tabbed-table-of-contents, .tc-manager-list-item-content, .tc-test-case-output {\n\toverflow-x: auto;\n}\n\n/* A wrapper to fix table overflow */\n\n.tc-table-wrapper {\n\toverflow-x: auto;\n}\n\n/*\n** Chooser\n*/\n\n.tc-chooser {\n\tborder-right: 1px solid <<colour table-header-background>>;\n\tborder-left: 1px solid <<colour table-header-background>>;\n}\n\n\n.tc-chooser-item {\n\tborder-bottom: 1px solid <<colour table-header-background>>;\n\tborder-top: 1px solid <<colour table-header-background>>;\n\tpadding: 2px 4px 2px 14px;\n}\n\n.tc-drop-down .tc-chooser-item {\n\tpadding: 2px;\n}\n\n.tc-chosen,\n.tc-chooser-item:hover {\n\tbackground-color: <<colour table-header-background>>;\n\tborder-color: <<colour table-footer-background>>;\n}\n\n.tc-chosen .tc-tiddlylink {\n\tcursor:default;\n}\n\n.tc-chooser-item .tc-tiddlylink {\n\tdisplay: block;\n\ttext-decoration: none;\n\tbackground-color: transparent;\n}\n\n.tc-chooser-item:hover .tc-tiddlylink:hover {\n\ttext-decoration: none;\n}\n\n.tc-drop-down .tc-chosen .tc-tiddlylink,\n.tc-drop-down .tc-chooser-item .tc-tiddlylink:hover {\n\tcolor: <<colour foreground>>;\n}\n\n.tc-chosen > .tc-tiddlylink:before {\n\tmargin-left: -10px;\n\tposition: relative;\n\tcontent: \"» \";\n}\n\n.tc-chooser-item svg,\n.tc-chooser-item img{\n\tmax-width: 1em;\n\tmax-height: 1em;\n\tvertical-align: middle;\n}\n\n.tc-language-chooser .tc-image-button img {\n\tmax-width: 2em;\n\tmax-height: 1em;\n\twidth: auto;\n\theight: auto;\n\tvertical-align: -0.15em;\n}\n\n/*\n** Palette swatches\n*/\n\n.tc-swatches-horiz {\n}\n\n.tc-swatches-horiz .tc-swatch {\n\tdisplay: inline-block;\n}\n\n.tc-swatch {\n\twidth: 2em;\n\theight: 2em;\n\tmargin: 0.4em;\n\tborder: 1px solid #888;\n}\n\ninput.tc-palette-manager-colour-input {\n\twidth: 100%;\n\tpadding: 0;\n}\n\n/*\n** Table of contents\n*/\n\n.tc-sidebar-lists .tc-table-of-contents {\n\twhite-space: nowrap;\n}\n\n.tc-table-of-contents button,\n.tc-table-of-contents .toc-item-muted {\n\tcolor: <<colour sidebar-foreground>>;\n}\n\n.tc-table-of-contents svg {\n\twidth: 0.7em;\n\theight: 0.7em;\n\tvertical-align: middle;\n\tfill: <<colour sidebar-foreground>>;\n}\n\n.tc-table-of-contents ol {\n\tlist-style-type: none;\n\tpadding-left: 0;\n}\n\n.tc-table-of-contents ol ol {\n\tpadding-left: 1em;\n}\n\n.tc-table-of-contents li {\n\tfont-size: 1.0em;\n\tfont-weight: bold;\n}\n\n.tc-table-of-contents li a {\n\tfont-weight: bold;\n}\n\n.tc-table-of-contents li li {\n\tfont-size: 0.95em;\n\tfont-weight: normal;\n\tline-height: 1.4;\n}\n\n.tc-table-of-contents li li a {\n\tfont-weight: normal;\n}\n\n.tc-table-of-contents li li li {\n\tfont-size: 0.95em;\n\tfont-weight: normal;\n\tline-height: 1.5;\n}\n\n.tc-table-of-contents li li li li {\n\tfont-size: 0.95em;\n\tfont-weight: normal;\n}\n\n.tc-tabbed-table-of-contents {\n\tdisplay: -webkit-flex;\n\tdisplay: flex;\n}\n\n.tc-tabbed-table-of-contents .tc-table-of-contents {\n\tz-index: 100;\n\tdisplay: inline-block;\n\tpadding-left: 1em;\n\tmax-width: 50%;\n\t-webkit-flex: 0 0 auto;\n\tflex: 0 0 auto;\n\tbackground: <<colour tab-background>>;\n\tborder-left: 1px solid <<colour tab-border>>;\n\tborder-top: 1px solid <<colour tab-border>>;\n\tborder-bottom: 1px solid <<colour tab-border>>;\n}\n\n.tc-tabbed-table-of-contents .tc-table-of-contents .toc-item > a,\n.tc-tabbed-table-of-contents .tc-table-of-contents .toc-item-selected > a {\n\tdisplay: block;\n\tpadding: 0.12em 1em 0.12em 0.25em;\n}\n\n.tc-tabbed-table-of-contents .tc-table-of-contents .toc-item > a {\n\tborder-top: 1px solid <<colour tab-background>>;\n\tborder-left: 1px solid <<colour tab-background>>;\n\tborder-bottom: 1px solid <<colour tab-background>>;\n}\n\n.tc-tabbed-table-of-contents .tc-table-of-contents .toc-item > a:hover {\n\ttext-decoration: none;\n\tborder-top: 1px solid <<colour tab-border>>;\n\tborder-left: 1px solid <<colour tab-border>>;\n\tborder-bottom: 1px solid <<colour tab-border>>;\n\tbackground: <<colour tab-border>>;\n}\n\n.tc-tabbed-table-of-contents .tc-table-of-contents .toc-item-selected > a {\n\tborder-top: 1px solid <<colour tab-border>>;\n\tborder-left: 1px solid <<colour tab-border>>;\n\tborder-bottom: 1px solid <<colour tab-border>>;\n\tbackground: <<colour background>>;\n\tmargin-right: -1px;\n}\n\n.tc-tabbed-table-of-contents .tc-table-of-contents .toc-item-selected > a:hover {\n\ttext-decoration: none;\n}\n\n.tc-tabbed-table-of-contents .tc-tabbed-table-of-contents-content {\n\tdisplay: inline-block;\n\tvertical-align: top;\n\tpadding-left: 1.5em;\n\tpadding-right: 1.5em;\n\tborder: 1px solid <<colour tab-border>>;\n\t-webkit-flex: 1 0 50%;\n\tflex: 1 0 50%;\n}\n\n/*\n** Dirty indicator\n*/\n\nhtml body svg.tc-image-save-button-dynamic .tc-image-save-button-dynamic-clean {\n\tvisibility: visible;\n}\n\nhtml body svg.tc-image-save-button-dynamic .tc-image-save-button-dynamic-dirty {\n\tvisibility: hidden;\n}\n\nhtml body.tc-dirty svg.tc-image-save-button-dynamic .tc-image-save-button-dynamic-clean {\n\tvisibility: hidden;\n}\n\nhtml body.tc-dirty svg.tc-image-save-button-dynamic .tc-image-save-button-dynamic-dirty {\n\tvisibility: visible;\n}\n\nhtml body.tc-dirty span.tc-dirty-indicator, html body.tc-dirty span.tc-dirty-indicator svg {\n\tfill: <<colour dirty-indicator>>;\n\tcolor: <<colour dirty-indicator>>;\n}\n\n/*\n** File inputs\n*/\n\n.tc-file-input-wrapper {\n\tposition: relative;\n\toverflow: hidden;\n\tdisplay: inline-block;\n\tvertical-align: middle;\n}\n\n.tc-file-input-wrapper input[type=file] {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tright: 0;\n\tbottom: 0;\n\tfont-size: 999px;\n\tmax-width: 100%;\n\tmax-height: 100%;\n\tfilter: alpha(opacity=0);\n\topacity: 0;\n\toutline: none;\n\tbackground: white;\n\tcursor: pointer;\n\tdisplay: inline-block;\n}\n\n::-webkit-file-upload-button {\n\tcursor:pointer;\n}\n\n/*\n** Thumbnail macros\n*/\n\n.tc-thumbnail-wrapper {\n\tposition: relative;\n\tdisplay: inline-block;\n\tmargin: 6px;\n\tvertical-align: top;\n}\n\n.tc-thumbnail-right-wrapper {\n\tfloat:right;\n\tmargin: 0.5em 0 0.5em 0.5em;\n}\n\n.tc-thumbnail-image {\n\ttext-align: center;\n\toverflow: hidden;\n\tborder-radius: 3px;\n}\n\n.tc-thumbnail-image svg,\n.tc-thumbnail-image img {\n\tfilter: alpha(opacity=1);\n\topacity: 1;\n\tmin-width: 100%;\n\tmin-height: 100%;\n\tmax-width: 100%;\n}\n\n.tc-thumbnail-wrapper:hover .tc-thumbnail-image svg,\n.tc-thumbnail-wrapper:hover .tc-thumbnail-image img {\n\tfilter: alpha(opacity=0.8);\n\topacity: 0.8;\n}\n\n.tc-thumbnail-background {\n\tposition: absolute;\n\tborder-radius: 3px;\n}\n\n.tc-thumbnail-icon svg,\n.tc-thumbnail-icon img {\n\twidth: 3em;\n\theight: 3em;\n\t<<filter \"drop-shadow(2px 2px 4px rgba(0,0,0,0.3))\">>\n}\n\n.tc-thumbnail-wrapper:hover .tc-thumbnail-icon svg,\n.tc-thumbnail-wrapper:hover .tc-thumbnail-icon img {\n\tfill: #fff;\n\t<<filter \"drop-shadow(3px 3px 4px rgba(0,0,0,0.6))\">>\n}\n\n.tc-thumbnail-icon {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tright: 0;\n\tbottom: 0;\n\tdisplay: -webkit-flex;\n\t-webkit-align-items: center;\n\t-webkit-justify-content: center;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n}\n\n.tc-thumbnail-caption {\n\tposition: absolute;\n\tbackground-color: #777;\n\tcolor: #fff;\n\ttext-align: center;\n\tbottom: 0;\n\twidth: 100%;\n\tfilter: alpha(opacity=0.9);\n\topacity: 0.9;\n\tline-height: 1.4;\n\tborder-bottom-left-radius: 3px;\n\tborder-bottom-right-radius: 3px;\n}\n\n.tc-thumbnail-wrapper:hover .tc-thumbnail-caption {\n\tfilter: alpha(opacity=1);\n\topacity: 1;\n}\n\n/*\n** Diffs\n*/\n\n.tc-diff-equal {\n\tbackground-color: <<colour diff-equal-background>>;\n\tcolor: <<colour diff-equal-foreground>>;\n}\n\n.tc-diff-insert {\n\tbackground-color: <<colour diff-insert-background>>;\n\tcolor: <<colour diff-insert-foreground>>;\n}\n\n.tc-diff-delete {\n\tbackground-color: <<colour diff-delete-background>>;\n\tcolor: <<colour diff-delete-foreground>>;\n}\n\n.tc-diff-invisible {\n\tbackground-color: <<colour diff-invisible-background>>;\n\tcolor: <<colour diff-invisible-foreground>>;\n}\n\n.tc-diff-tiddlers th {\n\ttext-align: right;\n\tbackground: <<colour background>>;\n\tfont-weight: normal;\n\tfont-style: italic;\n}\n\n.tc-diff-tiddlers pre {\n\tmargin: 0;\n\tpadding: 0;\n\tborder: none;\n\tbackground: none;\n}\n\n/*\n** Errors\n*/\n\n.tc-error {\n\tbackground: #f00;\n\tcolor: #fff;\n}\n\n/*\n** Tree macro\n*/\n\n.tc-tree div {\n\tpadding-left: 14px;\n}\n\n.tc-tree ol {\n\tlist-style-type: none;\n\tpadding-left: 0;\n\tmargin-top: 0;\n}\n\n.tc-tree ol ol {\n\tpadding-left: 1em;\n}\n\n.tc-tree button {\n\tcolor: #acacac;\n}\n\n.tc-tree svg {\n\tfill: #acacac;\n}\n\n.tc-tree span svg {\n\twidth: 1em;\n\theight: 1em;\n\tvertical-align: baseline;\n}\n\n.tc-tree li span {\n\tcolor: lightgray;\n}\n\nselect {\n\tcolor: <<colour select-tag-foreground>>;\n\tbackground: <<colour select-tag-background>>;\n}\n\n/*\n** Translink macro\n*/\n\n.tc-translink {\n\tbackground-color: <<colour pre-background>>;\n\tborder: 1px solid <<colour pre-border>>;\n\tpadding: 0 3px;\n\tborder-radius: 3px;\n}\n\ndiv.tc-translink > div {\n\tmargin: 1em;\n}\n\ndiv.tc-translink > div > a:first-child > h1 {\n\tfont-size: 1.2em;\n\tfont-weight: bold;\n}\n\nspan.tc-translink > a:first-child {\n\tfont-weight: bold;\n}\n\n/*\n** Classes for displaying globals\n*/\n\n.tc-global-tiddler-body {\n\tpadding: 0.25em;\n\tborder: 1px solid <<colour foreground>>;\n\tbackground-color: <<colour muted-foreground>>;\n\tborder-radius: 3px;\n}\n\n.tc-global-tiddler-body-heading {\n\tmargin: 0 0 0.25em 0;\n\tfont-weight: normal;\n}\n\n.tc-global-tiddler-body-type {\n\tmargin: 0 0 0.25em 0;\n\tborder-bottom: 1px solid <<colour foreground>>;\n}\n\n.tc-global-tiddler-body-details {\n\tbackground-color: <<colour background>>;\n}\n\n.tc-global-tiddler-body pre {\n\tmargin: 0;\n\tborder: 1px solid <<colour foreground>>;\n}\n\n/*\n** Utility classes for SVG icons\n*/\n\n.tc-fill-background {\n\tfill: <<colour background>>;\n}\n\n.tc-network-activity-background {\n\tfill: <<colour network-activity-foreground>>;\n}\n\n/*\n** Test Cases\n*/\n\n.tc-test-case-wrapper {\n\tborder: 1px solid <<colour foreground>>;\n\tbackground-color: <<colour muted-foreground>>;\n\tborder-radius: 6px;\n}\n\n.tc-test-case-wrapper {\n\tbackground-color: <<colour testcase-accent-level-1>>;\n}\n\n.tc-test-case-wrapper .tc-test-case-wrapper {\n\tbackground-color: <<colour testcase-accent-level-2>>;\n}\n\n.tc-test-case-wrapper .tc-test-case-wrapper .tc-test-case-wrapper {\n\tbackground-color: <<colour testcase-accent-level-3>>;\n}\n\n.tc-test-case-header {\n\tfont-weight: normal;\n\tmargin: 0.5em 0;\n\tpadding: 0 0.5em;\n}\n\n.tc-test-case-divider {\n\tx-background-color: <<colour muted-foreground>>;\n}\n\n.tc-test-case-result-icon {\n\tfill: #fff;\n\tpadding: 0.25em;\n\tdisplay: inline-block;\n\tline-height: 0;\n\tborder-radius: 1em;\n\tvertical-align: text-bottom;\n\tmargin-right: 0.25em;\n}\n\n.tc-test-case-result-icon-pass {\n\tbackground-color: green;\n}\n\n.tc-test-case-result-icon-fail {\n\tbackground-color: red;\n}\n\n.tc-test-case-result-icon svg {\n\twidth: 0.5em;\n\theight: 0.5em;\n}\n\n.tc-test-case-header > h2 {\n\tbackground: <<colour background>>;\n\tborder-radius: 4px;\n\tpadding: 0.25em;\n}\n\n.tc-test-case-header > h2,\n.tc-test-case-source > pre {\n\tmargin: 0;\n}\n\n.tc-test-case-header > h2 a.tc-tiddlylink-missing {\n\tfont-style: normal;\n}\n\n.tc-test-case-toolbar {\n\tfloat: right;\n}\n\n.tc-test-case-toolbar svg {\n\tfill: <<colour tiddler-controls-foreground>>;\n}\n\n.tc-test-case-toolbar .tc-drop-down {\n\tfont-size: 0.8em;\n}\n\n.tc-test-case-result-fail {\n\tborder: 1px solid <<colour foreground>>;\n\tbackground-color: <<colour background>>;\n\tborder-radius: 4px;\n\tmargin: 0 0.5em;\n\tpadding: 0;\n}\n\n.tc-test-case-result-fail-header {\n\tbackground: <<colour diff-delete-background>>;\n\tcolor: <<colour diff-delete-foreground>>;\n\tborder-top-left-radius: 4px;\n\tborder-top-right-radius: 4px;\n\tpadding: 4px;\n}\n\n.tc-test-case-result-fail-body {\n\tpadding: 4px;\n}\n\n.tc-test-case-source > pre {\n\theight: 100%;\n}\n\n.tc-test-case-narrative {\n\tpadding: 0.5em;\n}\n\n.tc-test-case-panes {\n\tdisplay: flex;\n\talign-items: stretch;\n\tflex-wrap: wrap;\n\tpadding: 0.5em;\n\tborder-bottom-left-radius: 6px;\n\tborder-bottom-right-radius: 6px;\n}\n\n.tc-test-case-source {\n\tflex: 1 0 49%;\n\tmin-width: 250px;\n}\n\n.tc-test-case-source .tc-tab-content {\n\tbackground: inherit;\n\tmargin: 0;\n}\n\n.tc-test-case-source .tc-tab-content .tc-field-table {\n\tbackground: <<colour background>>;\n}\n\n.tc-test-case-source .tc-field-table {\n\twidth: 100%;\n}\n\n.tc-test-case-source table.tc-field-table {\n\tmargin: 0;\n}\n\n.tc-test-case-source .tc-tiddler-frame .tc-edit-texteditor {\n\tmargin: 0;\n}\n\n.tc-test-case-divider {\n\tflex: 0 0 1.5%;\n}\n\n.tc-test-case-source .tc-tab-buttons {\n\tpadding-top: 0;\n}\n\n.tc-test-case-footer-toolbar {\n\tdisplay: flex;\n\tjustify-content: flex-end;\n}\n\n.tc-test-case-output {\n\tbox-shadow: inset 2px 2px 10px 0px <<colour muted-foreground>>;\n\tbackground: <<colour background>>;\n\tborder-radius: 4px;\n\tborder: 1px solid <<colour muted-foreground>>;\n\tflex: 1 0 49%;\n\tmin-width: 250px;\n\tpadding: 0.25em 1em;\n}\n\n/*\n** Flexbox utility classes\n*/\n\n.tc-flex {\n\tdisplay: -webkit-flex;\n\tdisplay: flex;\n}\n\n.tc-flex-column {\n\tflex-direction: column;\n}\n\n.tc-flex-row {\n\tflex-direction: row;\n}\n\n.tc-flex-grow-1 {\n\tflex-grow: 1;\n}\n\n.tc-flex-grow-2 {\n\tflex-grow: 2;\n}\n\n/*\n** Other utility classes\n*/\n\n/* Horizontal gaps */\n\n.tc-tiny-gap {\n\tmargin-left: .25em;\n\tmargin-right: .25em;\n}\n\n.tc-tiny-gap-left {\n\tmargin-left: .25em;\n}\n\n.tc-tiny-gap-right {\n\tmargin-right: .25em;\n}\n\n.tc-small-gap {\n\tmargin-left: .5em;\n\tmargin-right: .5em;\n}\n\n.tc-small-gap-left {\n\tmargin-left: .5em;\n}\n\n.tc-small-gap-right {\n\tmargin-right: .5em;\n}\n\n.tc-big-gap {\n\tmargin-left: 1em;\n\tmargin-right: 1em;\n}\n\n.tc-big-gap-left {\n\tmargin-left: 1em;\n}\n\n.tc-big-gap-right {\n\tmargin-right: 1em;\n}\n\n.tc-word-break {\n\tword-break: break-all;\n}\n\n/* Vertical gaps */\n\n.tc-tiny-v-gap-bottom {\n\tmargin-bottom: 3px;\n}\n\n"},"$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize":{"title":"$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize","text":"15px"},"$:/themes/tiddlywiki/vanilla/metrics/bodylineheight":{"title":"$:/themes/tiddlywiki/vanilla/metrics/bodylineheight","text":"22px"},"$:/themes/tiddlywiki/vanilla/metrics/fontsize":{"title":"$:/themes/tiddlywiki/vanilla/metrics/fontsize","text":"14px"},"$:/themes/tiddlywiki/vanilla/metrics/lineheight":{"title":"$:/themes/tiddlywiki/vanilla/metrics/lineheight","text":"20px"},"$:/themes/tiddlywiki/vanilla/metrics/storyleft":{"title":"$:/themes/tiddlywiki/vanilla/metrics/storyleft","text":"0px"},"$:/themes/tiddlywiki/vanilla/metrics/storytop":{"title":"$:/themes/tiddlywiki/vanilla/metrics/storytop","text":"0px"},"$:/themes/tiddlywiki/vanilla/metrics/storyright":{"title":"$:/themes/tiddlywiki/vanilla/metrics/storyright","text":"770px"},"$:/themes/tiddlywiki/vanilla/metrics/storywidth":{"title":"$:/themes/tiddlywiki/vanilla/metrics/storywidth","text":"770px"},"$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth":{"title":"$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth","text":"686px"},"$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint":{"title":"$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint","text":"960px"},"$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth":{"title":"$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth","text":"350px"},"$:/themes/tiddlywiki/vanilla/options/stickytitles":{"title":"$:/themes/tiddlywiki/vanilla/options/stickytitles","text":"no"},"$:/themes/tiddlywiki/vanilla/options/sidebarlayout":{"title":"$:/themes/tiddlywiki/vanilla/options/sidebarlayout","text":"fixed-fluid"},"$:/themes/tiddlywiki/vanilla/options/codewrapping":{"title":"$:/themes/tiddlywiki/vanilla/options/codewrapping","text":"pre-wrap"},"$:/themes/tiddlywiki/vanilla/reset":{"title":"$:/themes/tiddlywiki/vanilla/reset","type":"text/css","text":"/*! modern-normalize v2.0.0 | MIT License | https://github.com/sindresorhus/modern-normalize */\n\n/*\nDocument\n========\n*/\n\n/**\nUse a better box model (opinionated).\n*/\n\n*,\n::before,\n::after {\n\tbox-sizing: border-box;\n}\n\nhtml {\n\t/* Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3) */\n\tfont-family:\n\t\tsystem-ui,\n\t\t'Segoe UI',\n\t\tRoboto,\n\t\tHelvetica,\n\t\tArial,\n\t\tsans-serif,\n\t\t'Apple Color Emoji',\n\t\t'Segoe UI Emoji';\n\tline-height: 1.15; /* 1. Correct the line height in all browsers. */\n\t-webkit-text-size-adjust: 100%; /* 2. Prevent adjustments of font size after orientation changes in iOS. */\n\t-moz-tab-size: 4; /* 3. Use a more readable tab size (opinionated). */\n\ttab-size: 4; /* 3 */\n}\n\n/*\nSections\n========\n*/\n\nbody {\n\tmargin: 0; /* Remove the margin in all browsers. */\n}\n\n/*\nGrouping content\n================\n*/\n\n/**\n1. Add the correct height in Firefox.\n2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)\n*/\n\nhr {\n\theight: 0; /* 1 */\n\tcolor: inherit; /* 2 */\n}\n\n/*\nText-level semantics\n====================\n*/\n\n/**\nAdd the correct text decoration in Chrome, Edge, and Safari.\n*/\n\nabbr[title] {\n\ttext-decoration: underline dotted;\n}\n\n/**\nAdd the correct font weight in Edge and Safari.\n*/\n\nb,\nstrong {\n\tfont-weight: bolder;\n}\n\n/**\n1. Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3)\n2. Correct the odd 'em' font sizing in all browsers.\n*/\n\ncode,\nkbd,\nsamp,\npre {\n\tfont-family:\n\t\tui-monospace,\n\t\tSFMono-Regular,\n\t\tConsolas,\n\t\t'Liberation Mono',\n\t\tMenlo,\n\t\tmonospace; /* 1 */\n\tfont-size: 1em; /* 2 */\n}\n\n/**\nAdd the correct font size in all browsers.\n*/\n\nsmall {\n\tfont-size: 80%;\n}\n\n/**\nPrevent 'sub' and 'sup' elements from affecting the line height in all browsers.\n*/\n\nsub,\nsup {\n\tfont-size: 75%;\n\tline-height: 0;\n\tposition: relative;\n\tvertical-align: baseline;\n}\n\nsub {\n\tbottom: -0.25em;\n}\n\nsup {\n\ttop: -0.5em;\n}\n\n/*\nTabular data\n============\n*/\n\n/**\n1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)\n2. Correct table border color inheritance in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)\n*/\n\ntable {\n\ttext-indent: 0; /* 1 */\n\tborder-color: inherit; /* 2 */\n}\n\n/*\nForms\n=====\n*/\n\n/**\n1. Change the font styles in all browsers.\n2. Remove the margin in Firefox and Safari.\n*/\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n\tfont-family: inherit; /* 1 */\n\tfont-size: 100%; /* 1 */\n\tline-height: 1.15; /* 1 */\n\tmargin: 0; /* 2 */\n}\n\n/**\nRemove the inheritance of text transform in Edge and Firefox.\n*/\n\nbutton,\nselect {\n\ttext-transform: none;\n}\n\n/**\nCorrect the inability to style clickable types in iOS and Safari.\n*/\n\nbutton,\n[type='button'],\n[type='reset'],\n[type='submit'] {\n\t-webkit-appearance: button;\n}\n\n/**\nRemove the inner border and padding in Firefox.\n*/\n\n::-moz-focus-inner {\n\tborder-style: none;\n\tpadding: 0;\n}\n\n/**\nRestore the focus styles unset by the previous rule.\n*/\n\n:-moz-focusring {\n\toutline: 1px dotted ButtonText;\n}\n\n/**\nRemove the additional ':invalid' styles in Firefox.\nSee: https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737\n*/\n\n:-moz-ui-invalid {\n\tbox-shadow: none;\n}\n\n/**\nRemove the padding so developers are not caught out when they zero out 'fieldset' elements in all browsers.\n*/\n\nlegend {\n\tpadding: 0;\n}\n\n/**\nAdd the correct vertical alignment in Chrome and Firefox.\n*/\n\nprogress {\n\tvertical-align: baseline;\n}\n\n/**\nCorrect the cursor style of increment and decrement buttons in Safari.\n*/\n\n::-webkit-inner-spin-button,\n::-webkit-outer-spin-button {\n\theight: auto;\n}\n\n/**\n1. Correct the odd appearance in Chrome and Safari.\n2. Correct the outline style in Safari.\n*/\n\n[type='search'] {\n\t-webkit-appearance: textfield; /* 1 */\n\toutline-offset: -2px; /* 2 */\n}\n\n/**\nRemove the inner padding in Chrome and Safari on macOS.\n*/\n\n::-webkit-search-decoration {\n\t-webkit-appearance: none;\n}\n\n/**\n1. Correct the inability to style clickable types in iOS and Safari.\n2. Change font properties to 'inherit' in Safari.\n*/\n\n::-webkit-file-upload-button {\n\t-webkit-appearance: button; /* 1 */\n\tfont: inherit; /* 2 */\n}\n\n/*\nInteractive\n===========\n*/\n\n/*\nAdd the correct display in Chrome and Safari.\n*/\n\nsummary {\n\tdisplay: list-item;\n}\n"},"$:/themes/tiddlywiki/vanilla/settings/fontfamily":{"title":"$:/themes/tiddlywiki/vanilla/settings/fontfamily","text":"-apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Noto Sans\", Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\""},"$:/themes/tiddlywiki/vanilla/settings/codefontfamily":{"title":"$:/themes/tiddlywiki/vanilla/settings/codefontfamily","text":"ui-monospace, \"SFMono-Regular\", \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace"},"$:/themes/tiddlywiki/vanilla/settings/backgroundimageattachment":{"title":"$:/themes/tiddlywiki/vanilla/settings/backgroundimageattachment","text":"fixed"},"$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize":{"title":"$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize","text":"auto"},"$:/themes/tiddlywiki/vanilla/sticky":{"title":"$:/themes/tiddlywiki/vanilla/sticky","code-body":"yes","text":"<$reveal state=\"$:/themes/tiddlywiki/vanilla/options/stickytitles\" type=\"match\" text=\"yes\">\n``\n.tc-tiddler-title {\n\tposition: -webkit-sticky;\n\tposition: -moz-sticky;\n\tposition: -o-sticky;\n\tposition: -ms-sticky;\n\tposition: sticky;\n\ttop: 0px;\n\tbackground: ``<<colour tiddler-background>>``;\n\tz-index: 500;\n}\n\n``\n<$list filter=\"[range[100]]\">\n`.tc-story-river .tc-tiddler-frame:nth-child(100n+`<$text text=<<currentTiddler>>/>`) {\nz-index: `<$text text={{{ [[200]subtract<currentTiddler>] }}}/>`;\n}\n`\n</$list>\n</$reveal>\n"}}}