├── .gitignore ├── package.json ├── assets ├── facebook.svg ├── telegram.svg ├── blogger.svg ├── twitter.svg ├── skype.svg ├── linkedin.svg ├── behance.svg ├── whatsapp.svg ├── pinterest.svg ├── youtube.svg └── instagram.svg ├── index.js ├── main.js ├── line-helper.js ├── index.html ├── readme.md └── libs ├── numberAnimate.js └── leader-line.min.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | out 3 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "social-media-automation", 3 | "version": "0.1.0", 4 | "description": "", 5 | "main": "main.js", 6 | "scripts": { 7 | "start": "electron ." 8 | }, 9 | "author": "Arpit Vasani, Parshwa Kapadia", 10 | "license": "MIT", 11 | "devDependencies": { 12 | "electron": "^6.0.1" 13 | }, 14 | "dependencies": { 15 | "puppeteer-core": "^1.19.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /assets/facebook.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var lineHelper = new LineHelper(); 2 | lineHelper.drawLine("#left-instagram", ".dashboard"); 3 | lineHelper.drawLine("#left-facebook", ".dashboard"); 4 | lineHelper.drawLine("#left-linkedin", ".dashboard"); 5 | lineHelper.drawLine("#left-twitter", ".dashboard"); 6 | lineHelper.drawLine("#left-skype", ".dashboard"); 7 | lineHelper.drawLine(".dashboard", "#right-instagram"); 8 | lineHelper.drawLine(".dashboard", "#right-twitter"); 9 | lineHelper.drawLine(".dashboard", "#right-facebook"); 10 | lineHelper.drawLine(".dashboard", "#right-skype"); 11 | $("p.center.white").numberAnimate(); 12 | //lineHelper.highlightLine("#left-twitter", ".dashboard","New post received"); 13 | //$("p.center.white").numberAnimate("set",400); 14 | 15 | //For demo purpose 16 | // setTimeout(() => { lineHelper.highlightLine("#left-twitter", ".dashboard", "New post received"); }, 1000) 17 | // //increase number 18 | // setTimeout(() => { $("p.center.white").eq(0).numberAnimate("set", 267); }, 6000); 19 | // setTimeout(() => { lineHelper.highlightLine(".dashboard", "#right-instagram", "Publishing a post as scheduled"); }, 11000); 20 | 21 | // //descrese number 22 | // setTimeout(() => { $("p.center.white").eq(1).numberAnimate("set", 246); }, 13000); 23 | // setTimeout(() => { $("p.center.white").eq(2).numberAnimate("set", 277); }, 13000); -------------------------------------------------------------------------------- /assets/telegram.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /assets/blogger.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /assets/twitter.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | const { app, BrowserWindow } = require('electron') 2 | const path = require('path') 3 | 4 | function createWindow() { 5 | // Create the browser window. 6 | mainWindow = new BrowserWindow({ 7 | width: 1300, 8 | height: 700 9 | }) 10 | 11 | // and load the index.html of the app. 12 | mainWindow.loadFile(__dirname + '/index.html') 13 | 14 | // Open the DevTools. 15 | mainWindow.webContents.openDevTools() 16 | 17 | // Emitted when the window is closed. 18 | mainWindow.on('closed', function () { 19 | // Dereference the window object, usually you would store windows 20 | // in an array if your app supports multi windows, this is the time 21 | // when you should delete the corresponding element. 22 | mainWindow = null 23 | }) 24 | } 25 | 26 | // This method will be called when Electron has finished 27 | // initialization and is ready to create browser windows. 28 | // Some APIs can only be used after this event occurs. 29 | app.on('ready', createWindow) 30 | 31 | // Quit when all windows are closed. 32 | app.on('window-all-closed', function () { 33 | // On macOS it is common for applications and their menu bar 34 | // to stay active until the user quits explicitly with Cmd + Q 35 | if (process.platform !== 'darwin') app.quit() 36 | }) 37 | 38 | app.on('activate', function () { 39 | // On macOS it's common to re-create a window in the app when the 40 | // dock icon is clicked and there are no other windows open. 41 | if (mainWindow === null) createWindow() 42 | }) 43 | 44 | // In this file you can include the rest of your app's specific main process 45 | // code. You can also put them in separate files and require them here. -------------------------------------------------------------------------------- /assets/skype.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /assets/linkedin.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 11 | 14 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /assets/behance.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 16 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /assets/whatsapp.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 14 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /assets/pinterest.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /line-helper.js: -------------------------------------------------------------------------------- 1 | // This JS will help draw the animated likens between the Elements 2 | 3 | function LineHelper() { 4 | var normalLineConfigs = { 5 | dash: { len: 10, gap: 25, animation: { duration: 200 } }, 6 | endPlug: "arrow2", 7 | hide:true 8 | }; 9 | var highlightLineConfigs = { 10 | dash: { len: 500, gap: 900, animation: { duration: 2000 } }, 11 | endPlug: "arrow2", 12 | hide:true 13 | }; 14 | 15 | this.allLines = []; 16 | this.drawLine = function (startElement, EndElement) { 17 | 18 | //draw line from start element to element 19 | console.log(checkOrGetElement(startElement)); 20 | 21 | var line = new LeaderLine( 22 | checkOrGetElement(startElement), 23 | LeaderLine.pointAnchor({ element: checkOrGetElement(EndElement), x: -5, y: '50%' }), 24 | normalLineConfigs 25 | ); 26 | 27 | var LineObject = {}; 28 | LineObject.from = startElement; 29 | LineObject.to = EndElement; 30 | LineObject.line = line; 31 | this.allLines.push(LineObject); 32 | line.show("fade"); 33 | } 34 | 35 | this.highlightLine = function (startElement, EndElement, message) { 36 | //find the line 37 | var line = this.allLines.find(line => line.from === startElement && line.to === EndElement); 38 | //remove the line 39 | line.line.remove(); 40 | this.allLines.splice(this.allLines.indexOf(line), 1); 41 | highlightLineConfigs.middleLabel = LeaderLine.pathLabel({ text: message || `New post received` }); 42 | var highlightLine = new LeaderLine( 43 | checkOrGetElement(startElement), 44 | LeaderLine.pointAnchor({ element: checkOrGetElement(EndElement), x: -5, y: '50%' }), 45 | highlightLineConfigs, 46 | ); 47 | highlightLine.show("draw"); 48 | //create a new for a 1500ms 49 | setTimeout(() => { 50 | highlightLine.remove(); 51 | this.drawLine(startElement, EndElement); 52 | }, 5000) 53 | //create the normal line again 54 | } 55 | 56 | function checkOrGetElement(element) { 57 | //returning element if it is a HTML element already 58 | if (element instanceof Element || element instanceof HTMLDocument) { 59 | return element; 60 | } else if (typeof element === 'string') { 61 | if (document.querySelector(element) !== null) { 62 | return document.querySelector(element); 63 | } else { 64 | throw Error("Invalid element selector"); 65 | } 66 | } else { 67 | throw Error("Invalid element selector"); 68 | } 69 | } 70 | 71 | return this; 72 | } 73 | 74 | -------------------------------------------------------------------------------- /assets/youtube.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 34 | 38 | 41 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /assets/instagram.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Social Media Automation 8 | 9 | 11 | 13 | 14 | 17 | 18 | 97 | 98 | 99 |
100 |
101 | istagram 102 | istagram 103 | istagram 104 | istagram 105 | istagram 106 | istagram 107 | istagram 108 | istagram 109 | istagram 110 | istagram 111 | istagram 112 |
113 |
114 | 115 |
116 |

Social Media Automation

117 |
118 |
119 | 120 |
121 |
122 |

Pending for approval

123 |

256

124 |
125 |
126 | 127 |
128 |
129 |

Posts Scheduled for future

130 |

256

131 |
132 | 133 |
134 |

Posts sent to social media

135 |

256

136 |
137 |
138 |
139 |
140 |
141 |
142 | istagram 143 | istagram 144 | istagram 145 | istagram 146 | istagram 147 | istagram 148 | istagram 149 | istagram 150 | istagram 151 | istagram 152 | istagram 153 |
154 | 155 | 156 | 157 | 158 | 159 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | 2 | # Social Media Automation 3 | An automated solution to a social media problem. 4 | 5 | ## 🔍 Preview 6 | ![Social media Automation gif Preview](https://user-images.githubusercontent.com/6497827/63050003-aa027c80-bef7-11e9-95a7-5cdbace131dc.gif) 7 | *Sorry for sluggish graphics rendering. My PC can't handle chrome and screen recording software both at the same time. 8 | 9 | 10 | ## ❓ What is this? 11 | 12 | This is a desktop app for all platforms (Mac, Windows, and Linux) which can automate all of your social media activity. As you can see in the preview, you can create scenarios like when you post something on one social media, it will be re-posted to another one (or same one but on a different account). 13 | 14 | This app also lets you schedule posts for any social media. For example when you don't want to be online at a certain time or maybe your audience is in a different timezone than you. 15 | 16 | Just imagine you are a big corporate like Marvel and you want to post certain news on all social media accounts at the same time. 17 | 18 | Maybe, you are a social media influencer and you want to like/retweet all the posts which show up with a certain #️⃣hashtag on twitter or Instagram. 19 | 20 | This app does that. 21 | 22 | ### 🤔 Problem 23 | 24 | I like being on social media but if you want to grow your audience they really make it hard to do so. First, you have to manage so many of them. Twitter, Facebook, Instagram, LinkedIn, Reddit, Youtube, and the list goes on and on. Second, you have to be active on them. Now one person can be active on 1 or two of them but being active on all of them daily is a cumbersome task. But they won't take you seriously if you are not active and not engaging them with posts (or putting one) which results in you not having enough audience or exposure on that platform. 25 | 26 | They are doing this because they want to promote their paid products. In Facebook they ask the person who posted for money to make this post reachable to all of his/her followers while LinkedIn offers paid membership based on how active you are on their platform. 27 | 28 | Ultimately, they track who is active and who is not and order other's feed based on that. If you are active then you will get audience automatically which is organic to your content and which will make you use (or be active) on that platform more than other platforms. 29 | 30 | So, this is their way to attract you by giving you incentives every once in a while. It's a common psychology practice. 31 | 32 | But I don't have 1 hour a day for each one (and how could I? there are dozens of them) and I want to be active for that shiny incentive which I am lured into. 33 | 34 | ### 💡 Solution 35 | 36 | The solution to this problem is a bot. It will act as a logged in user and do the same activities as the user. So that platform thinks that the user is active and automatically helps the user to gain more followers and bigger audience reach. 37 | 38 | ## 🤨 How will it work? 39 | 40 | We will use libraries like Google Puppeteer, ElectronJS and official API's to automate. It will mimic the same steps you would do on the web but it will do it automatically without human interaction. You can always see what it's doing and intervene/stop it at any point in time. 41 | 42 | ## ⚙ How to run 43 | 44 | - Clone the repo using `git clone` 45 | - Enter into the dir `cd Social-Media-Automation` 46 | - Install required packages `npm install` 47 | - Start the server `npm start` 48 | 49 | 50 | ## ⚡ Features 51 | 52 | - 💯 Totally Free for personal use 53 | - 🔒 Complete Privacy (we don't even have servers to store your data) 54 | - 🚀 Fast and effective !!! 55 | - 🤯 Numerous use case and possibilities 56 | 57 | If you think this is a good idea then let me know by putting a star ⭐ on this project 🙂 58 | 59 | 60 | 61 | ## 🤨 When it will be ready? 62 | That's where we need you. 63 | 64 | ![we-want-you-to-contribute](https://user-images.githubusercontent.com/6497827/63040885-1d9a8e80-bee4-11e9-900e-ff4920762e52.jpg) 65 | 66 | #### Yeah, I can help. I am a highly experienced developer 67 | We need someone like you to create a coding architecture so that code can be scalable to any use case. Also, as this is open source, there will be lots of PRs with junky code which will need to be refactored. We need you to use your expertise in that area. 68 | 69 | #### Yes, I am learning programming and I think I can help 70 | Well, you are at the right location. Have a look at the issues and take one which you think you can fix. Also just looking and understanding the code will help you learn a few tricks. You can also add comments to existing code. Even small comments can speed up the developing process for others. 71 | 72 | #### okay, but I am not a developer 73 | That's fine. Not everyone has to be one. You can think of tasks which is troubling you and which you think can be automated. Raise an issue here. Maybe some developer might have the same problem and decide to work on it which will benefit us all. 74 | 75 | #### oh yeah, I am a social media influencer and I have a use case in mind 76 | 77 | That's exactly why these technologies has been invented - to solve the problems we are facing in our day-to-day lives. Please write/explain your use case in the issues section and we will incorporate it into our codebase soon. 78 | 79 | #### I am a social media manager and I can explain how each social media works 80 | 81 | Well, we have been waiting for you. Pick up an issue which suits you and comment on it. 82 | 83 | 84 | 85 | ## FAQ 86 | 87 | * **Is this app built with NodeJS?** 88 | 89 | Yes, it is built with [NodeJS](https://nodejs.org/en/). 90 | 91 | * **What boilerplate did you use?** 92 | 93 | None. The idea was to get a better understanding of how things work together, but I did take clues from other projects. 94 | 95 | * **Are you available for hire?** 96 | 97 | I have a full-time job as a software developer at technobrains.net and mindtechconsultancy.com. I am available as a freelance consultant during my spare time. Please let me know what you have in mind. 98 | 99 | * **How do I contact you?** 100 | 101 | If you find an issue, please report it here. For everything else, please drop me a line at vasani.arpit@gmail.com 102 | 103 | * **Do you have any other projects?** 104 | 105 | I thought you'd never ask. Yes, I do. [Wbot](https://github.com/vasani-arpit/WBOT) is one of them. 106 | 107 | ## 📄 Legal 108 | 109 | This code is in no way affiliated with, authorized, maintained, sponsored or endorsed by any social media platforms or any of its affiliates or subsidiaries for which it provides its services. This is an independent and unofficial software. Use at your own risk. **Commercial use of this code/repo is strictly prohibited.** 110 | 111 | 112 | ## 👋 Contact Me 👋 113 | 114 | [![Contact me on twitter][twitter_logo]][twitter] 115 | [![Contact me on telegram][telegram_logo]][telegram] 116 | [![Mail me][gmail_logo]][gmail] 117 | 118 | [twitter_logo]: https://user-images.githubusercontent.com/6497827/57843958-c30e6b00-77ec-11e9-97bd-dfbc800f96a9.png 119 | [telegram_logo]: https://user-images.githubusercontent.com/6497827/57844175-2ac4b600-77ed-11e9-8488-f2d45efa7497.png 120 | [gmail_logo]: https://user-images.githubusercontent.com/6497827/62424751-c1b85480-b6f0-11e9-97de-096c0a980829.png 121 | [twitter]: https://twitter.com/ArpitVasani 122 | [telegram]: http://t.me/Arpit_Vasani 123 | [gmail]: mailto:vasani.arpit@gmail.com?subject=Regarding%20Wbot&body=Hi 124 | -------------------------------------------------------------------------------- /libs/numberAnimate.js: -------------------------------------------------------------------------------- 1 | /*global define:false, WebKitCSSMatrix:false */ 2 | /*jshint forin:true, noarg:true, noempty:true, eqeqeq:true, evil:true, 3 | laxbreak:true, bitwise:true, strict:true, undef:true, unused:true, browser:true, 4 | jquery:true, indent:4, curly:false, maxerr:50 */ 5 | 6 | //Set the plugin up so that it'll work as a AMD module or regular import 7 | //See: https://github.com/umdjs/umd/blob/master/jqueryPlugin.js.. 8 | (function (factory) { 9 | "use strict"; 10 | if (typeof define === 'function' && define.amd) { 11 | define(['jquery'], factory); 12 | } else { 13 | factory(jQuery); 14 | } 15 | }(function ($) { 16 | "use strict"; 17 | 18 | //first figure out which CSS3 properties to set.. 19 | var prefixes = ["", "O", "ms", "Webkit", "Moz"]; 20 | 21 | //using same idea as jquery transform plugin.. 22 | var testDivStyle = document.createElement('div').style; 23 | var css3Prefix = null; 24 | for (var i = 0, len = prefixes.length; i < len; i++) { 25 | if (prefixes[i] + "Transition" in testDivStyle && 26 | prefixes[i] + "Transform" in testDivStyle) { 27 | css3Prefix = prefixes[i]; 28 | break; 29 | } 30 | } 31 | var animationSupported = css3Prefix !== null; 32 | 33 | //get the transition ended event name for the css3Prefix.. 34 | var transitionEndEvent; 35 | switch (css3Prefix) { 36 | case "O": 37 | transitionEndEvent = "otransitionend"; 38 | break; 39 | case "ms": 40 | transitionEndEvent = "msTransitionEnd"; 41 | break; 42 | case "Webkit": 43 | transitionEndEvent = "webkitTransitionEnd"; 44 | break; 45 | default: 46 | transitionEndEvent = "transitionend"; 47 | } 48 | 49 | //allow the use of hardware accellerated transforms for older webkit browsers, adapted from: 50 | //http://www.appmobi.com/documentation/content/Articles/Article_UsingBestPractices/index.html?r=8684 51 | var translateOpen = window.WebKitCSSMatrix 52 | && 'm11' in new WebKitCSSMatrix() ? "translate3d(0, " : "translate(0, "; 53 | var translateClose = window.WebKitCSSMatrix 54 | && 'm11' in new WebKitCSSMatrix() ? "px ,0)" : "px)"; 55 | 56 | /** 57 | * Binds the given function onto the given jQuery array $el on the transitionEndEvent and unbinds it after execution. 58 | * Also handles the case where the event doesn't fire, in which case a timeout is used to ensure execution, which runs 59 | * after the given number of milliseconds plus an additional 100ms grace period. 60 | */ 61 | var bindToTransitionEndForSingleRun = function ($el, funcToExec, maxMSTillTransitionEnd) { 62 | var firedFunc = false; 63 | var wrappedFunc = function () { 64 | funcToExec(); 65 | firedFunc = true; 66 | $el.unbind(transitionEndEvent, wrappedFunc); 67 | }; 68 | $el.bind(transitionEndEvent, wrappedFunc); 69 | setTimeout(function () { 70 | if (!firedFunc) wrappedFunc(); 71 | }, maxMSTillTransitionEnd + 100); 72 | }; 73 | 74 | //all allowed characters (note: you get a bizzare error in Opera and IE 75 | //if the non-digit characters are at the end for some reason).. 76 | var allChars = ', . - + 0 1 2 3 4 5 6 7 8 9'; 77 | 78 | //checks that the given value makes sense to use.. 79 | var checkValue = function (str) { 80 | //check there are no odd chars first.. 81 | for (var i = 0, len = str.length; i < len; i++) { 82 | if (allChars.indexOf(str.charAt(i)) < 0) { 83 | $.error("numberAnimate plugin requires that value used " + 84 | "only contain character in: \"" + allChars + "\""); 85 | return false; 86 | } 87 | } 88 | return true; 89 | }; 90 | 91 | //Given a div which holder a character, it shift it to the required character, 92 | //note, the givenholder div should be attached prior to calling this for the animation 93 | //to take effect.. 94 | var shiftToChar = function ($holderDiv, character, shiftTime) { 95 | var innerStyle = $holderDiv.children()[0].style; 96 | innerStyle[css3Prefix + 'Transition'] = "all " + shiftTime + "ms ease-in-out"; 97 | 98 | var indexOfChar = allChars.indexOf(character); 99 | var transformY; 100 | if (indexOfChar < 0 || /\s/.test(character)) { 101 | transformY = $holderDiv.height(); 102 | } else { 103 | transformY = 0 - (indexOfChar / 2) * $holderDiv.height(); 104 | } 105 | innerStyle[css3Prefix + 'Transform'] = translateOpen + transformY + translateClose; 106 | }; 107 | 108 | //Function to create a new character wrapper div to wrap the given character 109 | //setting the holding div to have the given dimension and given "position". 110 | //You should attach the element returned by this function to the DOM straight 111 | //away in order for the animation to take effect.. 112 | //The animationTimes is an array of milliseconds which defines: creation, 113 | //shift and remove times.. 114 | var createDivForChar = function (character, height, width, position, animationTimes) { 115 | var creationTime = animationTimes[0]; 116 | var shiftTime = animationTimes[1]; 117 | 118 | var holderDiv = $(document.createElement('div')).css({ 119 | width: (creationTime ? 0 : width) + 'px', 120 | height: height + 'px', 121 | overflow: 'hidden', 122 | display: 'inline-block' 123 | }).attr("data-numberAnimate-pos", position); 124 | 125 | var innerDiv = $(document.createElement('div')).html(allChars); 126 | //fix annoying flickering for older webkit browsers.. 127 | if (css3Prefix === 'Webkit') 128 | innerDiv[0].style['-webkit-backface-visibility'] = 'hidden'; 129 | 130 | //initially show blank.. 131 | innerDiv[0].style[css3Prefix + 'Transform'] = translateOpen + height + translateClose; 132 | holderDiv.append(innerDiv); 133 | 134 | //animate to the correct character when finished animating creation if necessary.. 135 | var shiftToCorrectChar = function () { 136 | shiftToChar(holderDiv, character, shiftTime); 137 | }; 138 | 139 | //shift if after creation and after attachment if animating.. 140 | if (creationTime) { 141 | //bit of a hack - transition will only work if the element is attached to the DOM 142 | //so use a timeout to make this possible (no onattached event).. 143 | setTimeout(function () { 144 | bindToTransitionEndForSingleRun(holderDiv, shiftToCorrectChar, creationTime); 145 | var holderStyle = holderDiv[0].style; 146 | holderStyle[css3Prefix + 'Transition'] = "all " + creationTime + "ms ease-in-out"; 147 | holderStyle.width = width + "px"; 148 | }, 20); 149 | } else if (shiftTime) { 150 | setTimeout(shiftToCorrectChar, 20); 151 | } else { 152 | shiftToCorrectChar(); 153 | } 154 | 155 | return holderDiv[0]; 156 | }; 157 | 158 | //Removes the elements in thegiven jQuery collection using animation.. 159 | var removeDivsForChars = function ($divs, animationTimes) { 160 | var shiftTime = animationTimes[1]; 161 | var removeTime = animationTimes[2]; 162 | 163 | $divs.removeAttr("data-numberAnimate-pos"); 164 | $divs.each(function (i, div) { 165 | var $div = $(div); 166 | var style = div.style; 167 | 168 | //then remove it.. 169 | var animateRemoval = function () { 170 | style[css3Prefix + 'Transition'] = "all " + removeTime + "ms ease-in-out"; 171 | style.width = "1px"; 172 | 173 | bindToTransitionEndForSingleRun($div, function () { 174 | $div.remove(); 175 | }, removeTime); 176 | }; 177 | if (shiftTime) { 178 | bindToTransitionEndForSingleRun($div, animateRemoval, shiftTime); 179 | } else { 180 | animateRemoval(); 181 | } 182 | 183 | //first move it so that the no break space is showing.. 184 | shiftToChar($div, 'not there', shiftTime); 185 | }); 186 | }; 187 | 188 | var methods = { 189 | init: function (options) { 190 | var settings = $.extend({}, { 191 | animationTimes: [500, 500, 500] //creation, animation, removal ms 192 | }, options); 193 | 194 | this.css('display', 'inline-block'); //otherwise height/width calculated incorrectly.. 195 | 196 | $.each(this, function () { 197 | var $this = $(this); 198 | 199 | //get initial value and set it as data.. 200 | var valueStr = this.innerHTML; 201 | if (!checkValue(valueStr)) return; 202 | 203 | $this.attr("data-numberAnimate-value", valueStr); 204 | 205 | if (!animationSupported) return; //do nothing.. 206 | 207 | //get width of a single character (assume mono-spaced font).. 208 | $this.html("1"); 209 | var characterWidth = $this.width(); 210 | var characterHeight = $this.height(); 211 | $this.attr("data-numberAnimate-characterHeight", characterHeight); 212 | $this.attr("data-numberAnimate-characterWidth", characterWidth); 213 | $this.html(""); 214 | 215 | //required to get things to line up.. 216 | $this.css({ 217 | "vertical-align": "top", 218 | "display": "inline-block", 219 | "height": characterHeight + "px" 220 | }); 221 | 222 | $this.attr("data-numberAnimate-animationTimes", "[" + settings.animationTimes + "]"); 223 | 224 | //we positionthings relative to the dot, so store it's position.. 225 | var indexOfPoint = valueStr.indexOf("."); 226 | if (indexOfPoint < 0) indexOfPoint = valueStr.length; 227 | 228 | //add divs representing each character.. 229 | var docFrag = document.createDocumentFragment(); 230 | for (var i = 0, len = valueStr.length; i < len; i++) { 231 | var character = valueStr.charAt(i); 232 | //create the divs with zero animation time.. 233 | docFrag.appendChild( 234 | createDivForChar(character, characterHeight, 235 | characterWidth, indexOfPoint - i, [0, 0, 0]) 236 | ); 237 | } 238 | $this.append(docFrag); //add in one go. 239 | }); 240 | 241 | return this; 242 | }, 243 | 244 | /** 245 | * Obtains the string value that is being animating for the first matched element. 246 | */ 247 | val: function () { 248 | return this.attr("data-numberAnimate-value"); 249 | }, 250 | 251 | /** 252 | * Sets the value to the new given one, using the given animationTimes if provided. 253 | * If animationTimes are not provided the ones associated with this object are used. 254 | */ 255 | set: function (newValue, animationTimes) { 256 | if (typeof newValue === 'number') //normalize to a string.. 257 | newValue = "" + newValue; 258 | if (!animationTimes) 259 | animationTimes = $.parseJSON(this.attr('data-numberAnimate-animationTimes')); 260 | 261 | //get the number value and update the stored value.. 262 | if (!checkValue(newValue)) return; 263 | this.attr("data-numberAnimate-value", newValue); 264 | 265 | //if not animating just change the value.. 266 | if (!animationSupported) { 267 | this.html(newValue); 268 | return; 269 | } 270 | 271 | //work out which characters are required relative to the dot.. 272 | var indexOfPoint = newValue.indexOf("."); 273 | if (indexOfPoint < 0) indexOfPoint = newValue.length; 274 | 275 | $.each(this, function () { 276 | var $this = $(this); 277 | 278 | var numberHolderDivs = $this.find("[data-numberAnimate-pos]"); 279 | var characterHeight = $this.attr('data-numberAnimate-characterHeight') * 1; 280 | var characterWidth = $this.attr('data-numberAnimate-characterWidth') * 1; 281 | 282 | //if new characters are required, this will be set to one of the newly created ones.. 283 | var newlyCreatedHoldingDiv; 284 | 285 | //add/remove those at the start.. 286 | var largestCurrentPos = numberHolderDivs.attr('data-numberAnimate-pos') * 1; 287 | if (isNaN(largestCurrentPos)) largestCurrentPos = 0; 288 | var largestRequiredPos = indexOfPoint; 289 | var docFragment, pos, character, index; 290 | if (largestCurrentPos < largestRequiredPos) { 291 | docFragment = document.createDocumentFragment(); 292 | for (pos = largestRequiredPos, index = 0; 293 | pos >= largestCurrentPos + 1; pos--, index++) { 294 | character = newValue.charAt(index); 295 | docFragment.appendChild( 296 | createDivForChar(character, characterHeight, 297 | characterWidth, pos, animationTimes) 298 | ); 299 | } 300 | newlyCreatedHoldingDiv = docFragment.firstChild; 301 | $this.prepend(docFragment); 302 | } else if (largestCurrentPos > largestRequiredPos) { 303 | removeDivsForChars( 304 | numberHolderDivs.slice(0, largestCurrentPos - largestRequiredPos), 305 | animationTimes 306 | ); 307 | } 308 | 309 | //add/remove at the end of the list.. 310 | var smallestCurrentPos = numberHolderDivs.last() 311 | .attr('data-numberAnimate-pos') * 1; 312 | if (isNaN(smallestCurrentPos)) smallestCurrentPos = 1; 313 | var smallestRequiredPos = indexOfPoint - newValue.length + 1; 314 | if (smallestRequiredPos < smallestCurrentPos) { 315 | docFragment = document.createDocumentFragment(); 316 | for (pos = smallestCurrentPos - 1, 317 | index = newValue.length - (smallestCurrentPos - smallestRequiredPos); 318 | pos >= smallestRequiredPos; pos--, index++) { 319 | character = newValue.charAt(index); 320 | docFragment.appendChild( 321 | createDivForChar(character, characterHeight, 322 | characterWidth, pos, animationTimes) 323 | ); 324 | } 325 | newlyCreatedHoldingDiv = docFragment.firstChild; 326 | $this.append(docFragment); 327 | } else if (smallestRequiredPos > smallestCurrentPos) { 328 | removeDivsForChars( 329 | numberHolderDivs.slice( 330 | numberHolderDivs.length - (smallestRequiredPos - smallestCurrentPos) 331 | ), 332 | animationTimes 333 | ); 334 | } 335 | 336 | //performs the animation of the characters that are already there.. 337 | var shiftPresentCharacters = function () { 338 | var shiftTime = animationTimes[1]; 339 | pos = Math.min(largestRequiredPos, largestCurrentPos); 340 | var endPos = Math.max(smallestRequiredPos, smallestCurrentPos); 341 | index = indexOfPoint - pos; 342 | for (; pos >= endPos; pos--, index++) { 343 | character = newValue.charAt(index); 344 | var holdingDiv = $this.find("[data-numberAnimate-pos=" + pos + "]"); 345 | shiftToChar(holdingDiv, character, shiftTime); 346 | } 347 | }; 348 | 349 | //execute above function straight away or once the newly created holding div has finished animating.. 350 | if (newlyCreatedHoldingDiv) { 351 | bindToTransitionEndForSingleRun( 352 | $(newlyCreatedHoldingDiv), shiftPresentCharacters, animationTimes[0] + 100); 353 | } else { 354 | shiftPresentCharacters(); 355 | } 356 | }); 357 | 358 | return this; 359 | }, 360 | 361 | /** 362 | * Undoes the changes made by this plugin to the selected elements. 363 | */ 364 | destroy: function () { 365 | $.each(this, function () { 366 | var $this = $(this); 367 | 368 | var value = $this.numberAnimate('val'); 369 | if (value === null) return; //continue 370 | 371 | $this.html(value); 372 | //remove attributes that may have been added - code adapted from: 373 | //cletus's answer for: http://stackoverflow.com/questions/1870441/remove-all-attributes 374 | var attributesToRemove = $.map(this.attributes, function (attr) { 375 | var name = attr.name; 376 | return name.indexOf('data-numberanimate') === 0 ? name : null; 377 | }); 378 | $this.removeAttr(attributesToRemove.join(' ')); 379 | }); 380 | 381 | return this; 382 | } 383 | }; 384 | 385 | $.fn.numberAnimate = function (method) { 386 | // Method calling logic (adapted from http://docs.jquery.com/Plugins/Authoring).. 387 | if (methods[method]) { 388 | return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); 389 | } else if (typeof method === 'object' || !method) { 390 | return methods.init.apply(this, arguments); 391 | } else { 392 | $.error('Method ' + method + ' does not exist on jQuery.numberAnimate'); 393 | } 394 | }; 395 | 396 | })); -------------------------------------------------------------------------------- /libs/leader-line.min.js: -------------------------------------------------------------------------------- 1 | /*! LeaderLine v1.0.5 (c) anseki https://anseki.github.io/leader-line/ */ 2 | var LeaderLine=function(){"use strict";var te,g,y,S,_,o,t,h,f,p,a,i,l,v="leader-line",M=1,I=2,C=3,L=4,n={top:M,right:I,bottom:C,left:L},A=1,V=2,P=3,N=4,T=5,m={straight:A,arc:V,fluid:P,magnet:N,grid:T},ne="behind",r=v+"-defs",s='',ae={disc:{elmId:"leader-line-disc",noRotate:!0,bBox:{left:-5,top:-5,width:10,height:10,right:5,bottom:5},widthR:2.5,heightR:2.5,bCircle:5,sideLen:5,backLen:5,overhead:0,outlineBase:1,outlineMax:4},square:{elmId:"leader-line-square",noRotate:!0,bBox:{left:-5,top:-5,width:10,height:10,right:5,bottom:5},widthR:2.5,heightR:2.5,bCircle:5,sideLen:5,backLen:5,overhead:0,outlineBase:1,outlineMax:4},arrow1:{elmId:"leader-line-arrow1",bBox:{left:-8,top:-8,width:16,height:16,right:8,bottom:8},widthR:4,heightR:4,bCircle:8,sideLen:8,backLen:8,overhead:8,outlineBase:2,outlineMax:1.5},arrow2:{elmId:"leader-line-arrow2",bBox:{left:-7,top:-8,width:11,height:16,right:4,bottom:8},widthR:2.75,heightR:4,bCircle:8,sideLen:8,backLen:7,overhead:4,outlineBase:1,outlineMax:1.75},arrow3:{elmId:"leader-line-arrow3",bBox:{left:-4,top:-5,width:12,height:10,right:8,bottom:5},widthR:3,heightR:2.5,bCircle:8,sideLen:5,backLen:4,overhead:8,outlineBase:1,outlineMax:2.5},hand:{elmId:"leader-line-hand",bBox:{left:-3,top:-12,width:40,height:24,right:37,bottom:12},widthR:10,heightR:6,bCircle:37,sideLen:12,backLen:3,overhead:37},crosshair:{elmId:"leader-line-crosshair",noRotate:!0,bBox:{left:-96,top:-96,width:192,height:192,right:96,bottom:96},widthR:48,heightR:48,bCircle:96,sideLen:96,backLen:96,overhead:0}},E={behind:ne,disc:"disc",square:"square",arrow1:"arrow1",arrow2:"arrow2",arrow3:"arrow3",hand:"hand",crosshair:"crosshair"},ie={disc:"disc",square:"square",arrow1:"arrow1",arrow2:"arrow2",arrow3:"arrow3",hand:"hand",crosshair:"crosshair"},W=[M,I,C,L],x="auto",oe={x:"left",y:"top",width:"width",height:"height"},B=80,R=4,F=5,G=120,D=8,z=3.75,j=10,H=30,U=.5522847,Z=.25*Math.PI,u=/^\s*(\-?[\d\.]+)\s*(\%)?\s*$/,b="http://www.w3.org/2000/svg",e="-ms-scroll-limit"in document.documentElement.style&&"-ms-ime-align"in document.documentElement.style&&!window.navigator.msPointerEnabled,le=!e&&!!document.uniqueID,re="MozAppearance"in document.documentElement.style,se=!(e||re||!window.chrome||!window.CSS),ue=!e&&!le&&!re&&!se&&!window.chrome&&"WebkitAppearance"in document.documentElement.style,he=le||e?.2:.1,pe={path:P,lineColor:"coral",lineSize:4,plugSE:[ne,"arrow1"],plugSizeSE:[1,1],lineOutlineEnabled:!1,lineOutlineColor:"indianred",lineOutlineSize:.25,plugOutlineEnabledSE:[!1,!1],plugOutlineSizeSE:[1,1]},k=(a={}.toString,i={}.hasOwnProperty.toString,l=i.call(Object),function(e){var t,n;return e&&"[object Object]"===a.call(e)&&(!(t=Object.getPrototypeOf(e))||(n=t.hasOwnProperty("constructor")&&t.constructor)&&"function"==typeof n&&i.call(n)===l)}),w=Number.isFinite||function(e){return"number"==typeof e&&window.isFinite(e)},c=function(){var e,x={ease:[.25,.1,.25,1],linear:[0,0,1,1],"ease-in":[.42,0,1,1],"ease-out":[0,0,.58,1],"ease-in-out":[.42,0,.58,1]},b=1e3/60/2,t=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame||function(e){setTimeout(e,b)},n=window.cancelAnimationFrame||window.mozCancelAnimationFrame||window.webkitCancelAnimationFrame||window.msCancelAnimationFrame||function(e){clearTimeout(e)},a=Number.isFinite||function(e){return"number"==typeof e&&window.isFinite(e)},k=[],w=0;function l(){var i=Date.now(),o=!1;e&&(n.call(window,e),e=null),k.forEach(function(e){var t,n,a;if(e.framesStart){if((t=i-e.framesStart)>=e.duration&&e.count&&e.loopsLeft<=1)return a=e.frames[e.lastFrame=e.reverse?0:e.frames.length-1],e.frameCallback(a.value,!0,a.timeRatio,a.outputRatio),void(e.framesStart=null);if(t>e.duration){if(n=Math.floor(t/e.duration),e.count){if(n>=e.loopsLeft)return a=e.frames[e.lastFrame=e.reverse?0:e.frames.length-1],e.frameCallback(a.value,!0,a.timeRatio,a.outputRatio),void(e.framesStart=null);e.loopsLeft-=n}e.framesStart+=e.duration*n,t=i-e.framesStart}e.reverse&&(t=e.duration-t),a=e.frames[e.lastFrame=Math.round(t/b)],!1!==e.frameCallback(a.value,!1,a.timeRatio,a.outputRatio)?o=!0:e.framesStart=null}}),o&&(e=t.call(window,l))}function O(e,t){e.framesStart=Date.now(),null!=t&&(e.framesStart-=e.duration*(e.reverse?1-t:t)),e.loopsLeft=e.count,e.lastFrame=null,l()}return{add:function(n,e,t,a,i,o,l){var r,s,u,h,p,c,d,f,y,S,m,g,_,v=++w;function E(e,t){return{value:n(t),timeRatio:e,outputRatio:t}}if("string"==typeof i&&(i=x[i]),n=n||function(){},t=this._endIndex||this._string[this._currentIndex]<"0"||"9"=this._endIndex||this._string[this._currentIndex]<"0"||"9"=this._endIndex)return null;var e=null,t=this._string[this._currentIndex];if(this._currentIndex+=1,"0"===t)e=0;else{if("1"!==t)return null;e=1}return this._skipOptionalSpacesOrDelimiter(),e}};var a=function(e){if(!e||0===e.length)return[];var t=new o(e),n=[];if(t.initialCommandIsMoveTo())for(;t.hasMoreData();){var a=t.parseSegment();if(null===a)break;n.push(a)}return n},n=e.SVGPathElement.prototype.setAttribute,r=e.SVGPathElement.prototype.removeAttribute,d=e.Symbol?e.Symbol():"__cachedPathData",f=e.Symbol?e.Symbol():"__cachedNormalizedPathData",U=function(e,t,n,a,i,o,l,r,s,u){var h,p,c,d,f,y=function(e,t,n){return{x:e*Math.cos(n)-t*Math.sin(n),y:e*Math.sin(n)+t*Math.cos(n)}},S=(h=l,Math.PI*h/180),m=[];if(u)p=u[0],c=u[1],d=u[2],f=u[3];else{var g=y(e,t,-S);e=g.x,t=g.y;var _=y(n,a,-S),v=(e-(n=_.x))/2,E=(t-(a=_.y))/2,x=v*v/(i*i)+E*E/(o*o);1120*Math.PI/180){var C=c,L=n,A=a;c=s&&p=Math.abs(n)?0<=t?I:L:0<=n?C:M))})),E.position_path!==x.position_path||E.position_lineStrokeWidth!==x.position_lineStrokeWidth||[0,1].some(function(e){return E.position_plugOverheadSE[e]!==x.position_plugOverheadSE[e]||(i=b[e],o=x.position_socketXYSE[e],i.x!==o.x||i.y!==o.y||i.socketId!==o.socketId)||(t=_[e],n=x.position_socketGravitySE[e],(a=null==t?"auto":Array.isArray(t)?"array":"number")!==(null==n?"auto":Array.isArray(n)?"array":"number")||("array"===a?t[0]!==n[0]||t[1]!==n[1]:t!==n));var t,n,a,i,o})){switch(u.pathList.baseVal=v=[],u.pathList.animVal=null,E.position_path){case A:v.push([O(b[0]),O(b[1])]);break;case V:t="number"==typeof _[0]&&0<_[0]||"number"==typeof _[1]&&0<_[1],o=Z*(t?-1:1),l=Math.atan2(b[1].y-b[0].y,b[1].x-b[0].x),r=-l+o,c=Math.PI-l-o,d=_e(b[0],b[1])/Math.sqrt(2)*U,S={x:b[0].x+Math.cos(r)*d,y:b[0].y+Math.sin(r)*d*-1},m={x:b[1].x+Math.cos(c)*d,y:b[1].y+Math.sin(c)*d*-1},v.push([O(b[0]),S,m,O(b[1])]);break;case P:case N:s=[_[0],E.position_path===N?0:_[1]],h=[],p=[],b.forEach(function(e,t){var n,a,i,o,l,r=s[t];Array.isArray(r)?n={x:r[0],y:r[1]}:"number"==typeof r?n=e.socketId===M?{x:0,y:-r}:e.socketId===I?{x:r,y:0}:e.socketId===C?{x:0,y:r}:{x:-r,y:0}:(a=b[t?0:1],o=0<(i=E.position_plugOverheadSE[t])?G+(DR?(E.position_lineStrokeWidth-R)*F:0),e.socketId===M?((l=(e.y-a.y)/2)=t.x:t.dirId===r?e.y>=t.y:e.x<=t.x}function y(e,t){return t.dirId===o||t.dirId===r?e.x===t.x:e.y===t.y}function S(e){return e[0]?{contain:0,notContain:1}:{contain:1,notContain:0}}function m(e,t,n){return Math.abs(t[n]-e[n])}function g(e,t,n){return"x"===n?e.x=H?g(h[t.notContain],h[t.contain],o[t.contain]):h[t.contain].dirId)):(i=[{x:h[0].x,y:h[0].y},{x:h[1].x,y:h[1].y}],u.forEach(function(e,t){var n=0===t?1:0,a=m(i[t],i[n],o[t]);aj&&(y[a]-ej&&(y[a]-ea.outlineMax&&(t=a.outlineMax),t*=2*a.outlineBase,v=We(m,_.plugOutline_strokeWidthSE,e,t)||v,v=We(m,_.plugOutline_inStrokeWidthSE,e,_.plugOutline_colorTraSE[e]?t-he/(_.line_strokeWidth/pe.lineSize)/g.plugSizeSE[e]*2:t/2)||v)}),v)),(t.faces||ee.line||ee.plug||ee.lineOutline||ee.plugOutline)&&(ee.faces=(b=(E=e).curStats,k=E.aplStats,w=E.events,O=!1,!b.line_altColor&&We(E,k,"line_color",x=b.line_color,w.apl_line_color)&&(E.lineFace.style.stroke=x,O=!0),We(E,k,"line_strokeWidth",x=b.line_strokeWidth,w.apl_line_strokeWidth)&&(E.lineShape.style.strokeWidth=x+"px",O=!0,(re||le)&&(Ae(E,E.lineShape),le&&(Ae(E,E.lineFace),Ae(E,E.lineMaskCaps)))),We(E,k,"lineOutline_enabled",x=b.lineOutline_enabled,w.apl_lineOutline_enabled)&&(E.lineOutlineFace.style.display=x?"inline":"none",O=!0),b.lineOutline_enabled&&(We(E,k,"lineOutline_color",x=b.lineOutline_color,w.apl_lineOutline_color)&&(E.lineOutlineFace.style.stroke=x,O=!0),We(E,k,"lineOutline_strokeWidth",x=b.lineOutline_strokeWidth,w.apl_lineOutline_strokeWidth)&&(E.lineOutlineMaskShape.style.strokeWidth=x+"px",O=!0,le&&(Ae(E,E.lineOutlineMaskCaps),Ae(E,E.lineOutlineFace))),We(E,k,"lineOutline_inStrokeWidth",x=b.lineOutline_inStrokeWidth,w.apl_lineOutline_inStrokeWidth)&&(E.lineMaskShape.style.strokeWidth=x+"px",O=!0,le&&(Ae(E,E.lineOutlineMaskCaps),Ae(E,E.lineOutlineFace)))),We(E,k,"plug_enabled",x=b.plug_enabled,w.apl_plug_enabled)&&(E.plugsFace.style.display=x?"inline":"none",O=!0),b.plug_enabled&&[0,1].forEach(function(n){var e=b.plug_plugSE[n],t=e!==ne?ae[ie[e]]:null,a=Ne(n,t);We(E,k.plug_enabledSE,n,x=b.plug_enabledSE[n],w.apl_plug_enabledSE)&&(E.plugsFace.style[a.prop]=x?"url(#"+E.plugMarkerIdSE[n]+")":"none",O=!0),b.plug_enabledSE[n]&&(We(E,k.plug_plugSE,n,e,w.apl_plug_plugSE)&&(E.plugFaceSE[n].href.baseVal="#"+t.elmId,Pe(E,E.plugMarkerSE[n],a.orient,t.bBox,E.svg,E.plugMarkerShapeSE[n],E.plugsFace),O=!0,re&&Ae(E,E.plugsFace)),We(E,k.plug_colorSE,n,x=b.plug_colorSE[n],w.apl_plug_colorSE)&&(E.plugFaceSE[n].style.fill=x,O=!0,(se||ue||le)&&!b.line_colorTra&&Ae(E,le?E.lineMaskCaps:E.capsMaskLine)),["markerWidth","markerHeight"].forEach(function(e){var t="plug_"+e+"SE";We(E,k[t],n,x=b[t][n],w["apl_"+t])&&(E.plugMarkerSE[n][e].baseVal.value=x,O=!0)}),We(E,k.plugOutline_enabledSE,n,x=b.plugOutline_enabledSE[n],w.apl_plugOutline_enabledSE)&&(x?(E.plugFaceSE[n].style.mask="url(#"+E.plugMaskIdSE[n]+")",E.plugOutlineFaceSE[n].style.display="inline"):(E.plugFaceSE[n].style.mask="none",E.plugOutlineFaceSE[n].style.display="none"),O=!0),b.plugOutline_enabledSE[n]&&(We(E,k.plugOutline_plugSE,n,e,w.apl_plugOutline_plugSE)&&(E.plugOutlineFaceSE[n].href.baseVal=E.plugMaskShapeSE[n].href.baseVal=E.plugOutlineMaskShapeSE[n].href.baseVal="#"+t.elmId,[E.plugMaskSE[n],E.plugOutlineMaskSE[n]].forEach(function(e){e.x.baseVal.value=t.bBox.left,e.y.baseVal.value=t.bBox.top,e.width.baseVal.value=t.bBox.width,e.height.baseVal.value=t.bBox.height}),O=!0),We(E,k.plugOutline_colorSE,n,x=b.plugOutline_colorSE[n],w.apl_plugOutline_colorSE)&&(E.plugOutlineFaceSE[n].style.fill=x,O=!0,le&&(Ae(E,E.lineMaskCaps),Ae(E,E.lineOutlineMaskCaps))),We(E,k.plugOutline_strokeWidthSE,n,x=b.plugOutline_strokeWidthSE[n],w.apl_plugOutline_strokeWidthSE)&&(E.plugOutlineMaskShapeSE[n].style.strokeWidth=x+"px",O=!0),We(E,k.plugOutline_inStrokeWidthSE,n,x=b.plugOutline_inStrokeWidthSE[n],w.apl_plugOutline_inStrokeWidthSE)&&(E.plugMaskShapeSE[n].style.strokeWidth=x+"px",O=!0)))}),O)),(t.position||ee.line||ee.plug)&&(ee.position=Fe(e)),(t.path||ee.position)&&(ee.path=(C=(M=e).curStats,L=M.aplStats,A=M.pathList.animVal||M.pathList.baseVal,V=C.path_edge,P=!1,A&&(V.x1=V.x2=A[0][0].x,V.y1=V.y2=A[0][0].y,C.path_pathData=I=we(A,function(e){e.xV.x2&&(V.x2=e.x),e.y>V.y2&&(V.y2=e.y)}),Me(I,L.path_pathData)&&(M.linePath.setPathData(I),L.path_pathData=I,P=!0,le?(Ae(M,M.plugsFace),Ae(M,M.lineMaskCaps)):re&&Ae(M,M.linePath),M.events.apl_path&&M.events.apl_path.forEach(function(e){e(M,I)}))),P)),ee.viewBox=(B=(N=e).curStats,R=N.aplStats,F=B.path_edge,G=B.viewBox_bBox,D=R.viewBox_bBox,z=N.svg.viewBox.baseVal,j=N.svg.style,H=!1,T=Math.max(B.line_strokeWidth/2,B.viewBox_plugBCircleSE[0]||0,B.viewBox_plugBCircleSE[1]||0),W={x1:F.x1-T,y1:F.y1-T,x2:F.x2+T,y2:F.y2+T},N.events.new_edge4viewBox&&N.events.new_edge4viewBox.forEach(function(e){e(N,W)}),G.x=B.lineMask_x=B.lineOutlineMask_x=B.maskBGRect_x=W.x1,G.y=B.lineMask_y=B.lineOutlineMask_y=B.maskBGRect_y=W.y1,G.width=W.x2-W.x1,G.height=W.y2-W.y1,["x","y","width","height"].forEach(function(e){var t;(t=G[e])!==D[e]&&(z[e]=D[e]=t,j[oe[e]]=t+("x"===e||"y"===e?N.bodyOffset[e]:0)+"px",H=!0)}),H),ee.mask=(Y=(U=e).curStats,X=U.aplStats,q=!1,Y.plug_enabled?[0,1].forEach(function(e){Y.capsMaskMarker_enabledSE[e]=Y.plug_enabledSE[e]&&Y.plug_colorTraSE[e]||Y.plugOutline_enabledSE[e]&&Y.plugOutline_colorTraSE[e]}):Y.capsMaskMarker_enabledSE[0]=Y.capsMaskMarker_enabledSE[1]=!1,Y.capsMaskMarker_enabled=Y.capsMaskMarker_enabledSE[0]||Y.capsMaskMarker_enabledSE[1],Y.lineMask_outlineMode=Y.lineOutline_enabled,Y.caps_enabled=Y.capsMaskMarker_enabled||Y.capsMaskAnchor_enabledSE[0]||Y.capsMaskAnchor_enabledSE[1],Y.lineMask_enabled=Y.caps_enabled||Y.lineMask_outlineMode,(Y.lineMask_enabled&&!Y.lineMask_outlineMode||Y.lineOutline_enabled)&&["x","y"].forEach(function(e){var t="maskBGRect_"+e;We(U,X,t,Z=Y[t])&&(U.maskBGRect[e].baseVal.value=Z,q=!0)}),We(U,X,"lineMask_enabled",Z=Y.lineMask_enabled)&&(U.lineFace.style.mask=Z?"url(#"+U.lineMaskId+")":"none",q=!0,ue&&Ae(U,U.lineMask)),Y.lineMask_enabled&&(We(U,X,"lineMask_outlineMode",Z=Y.lineMask_outlineMode)&&(Z?(U.lineMaskBG.style.display="none",U.lineMaskShape.style.display="inline"):(U.lineMaskBG.style.display="inline",U.lineMaskShape.style.display="none"),q=!0),["x","y"].forEach(function(e){var t="lineMask_"+e;We(U,X,t,Z=Y[t])&&(U.lineMask[e].baseVal.value=Z,q=!0)}),We(U,X,"caps_enabled",Z=Y.caps_enabled)&&(U.lineMaskCaps.style.display=U.lineOutlineMaskCaps.style.display=Z?"inline":"none",q=!0,ue&&Ae(U,U.capsMaskLine)),Y.caps_enabled&&([0,1].forEach(function(e){var t;We(U,X.capsMaskAnchor_enabledSE,e,Z=Y.capsMaskAnchor_enabledSE[e])&&(U.capsMaskAnchorSE[e].style.display=Z?"inline":"none",q=!0,ue&&Ae(U,U.lineMask)),Y.capsMaskAnchor_enabledSE[e]&&(Me(t=Y.capsMaskAnchor_pathDataSE[e],X.capsMaskAnchor_pathDataSE[e])&&(U.capsMaskAnchorSE[e].setPathData(t),X.capsMaskAnchor_pathDataSE[e]=t,q=!0),We(U,X.capsMaskAnchor_strokeWidthSE,e,Z=Y.capsMaskAnchor_strokeWidthSE[e])&&(U.capsMaskAnchorSE[e].style.strokeWidth=Z+"px",q=!0))}),We(U,X,"capsMaskMarker_enabled",Z=Y.capsMaskMarker_enabled)&&(U.capsMaskLine.style.display=Z?"inline":"none",q=!0),Y.capsMaskMarker_enabled&&[0,1].forEach(function(n){var e=Y.capsMaskMarker_plugSE[n],t=e!==ne?ae[ie[e]]:null,a=Ne(n,t);We(U,X.capsMaskMarker_enabledSE,n,Z=Y.capsMaskMarker_enabledSE[n])&&(U.capsMaskLine.style[a.prop]=Z?"url(#"+U.lineMaskMarkerIdSE[n]+")":"none",q=!0),Y.capsMaskMarker_enabledSE[n]&&(We(U,X.capsMaskMarker_plugSE,n,e)&&(U.capsMaskMarkerShapeSE[n].href.baseVal="#"+t.elmId,Pe(U,U.capsMaskMarkerSE[n],a.orient,t.bBox,U.svg,U.capsMaskMarkerShapeSE[n],U.capsMaskLine),q=!0,re&&(Ae(U,U.capsMaskLine),Ae(U,U.lineFace))),["markerWidth","markerHeight"].forEach(function(e){var t="capsMaskMarker_"+e+"SE";We(U,X[t],n,Z=Y[t][n])&&(U.capsMaskMarkerSE[n][e].baseVal.value=Z,q=!0)}))}))),Y.lineOutline_enabled&&["x","y"].forEach(function(e){var t="lineOutlineMask_"+e;We(U,X,t,Z=Y[t])&&(U.lineOutlineMask[e].baseVal.value=Z,q=!0)}),q),t.effect&&(J=(Q=e).curStats,$=Q.aplStats,Object.keys(te).forEach(function(e){var t=te[e],n=e+"_enabled",a=e+"_options",i=J[a];We(Q,$,n,K=J[n])?(K&&($[a]=de(i)),t[K?"init":"remove"](Q)):K&&ce(i,$[a])&&(t.remove(Q),$[n]=!0,$[a]=de(i),t.init(Q))})),(se||ue)&&ee.line&&!ee.path&&Ae(e,e.lineShape),se&&ee.plug&&!ee.line&&Ae(e,e.plugsFace),Ve(e)}function ze(e,t){return{duration:w(e.duration)&&0i.x2&&(i.x2=t.x2),t.y2>i.y2&&(i.y2=t.y2),["x","y"].forEach(function(e){var t,n="dropShadow_"+e;o[n]=t=i[e+"1"],We(a,l,n,t)&&(a.efc_dropShadow_elmFilter[e].baseVal.value=t)}))}}},Object.keys(te).forEach(function(e){var t=te[e],n=t.stats;n[e+"_enabled"]={iniValue:!1},n[e+"_options"]={hasProps:!0},t.anim&&(n[e+"_animOptions"]={},n[e+"_animId"]={})}),g={none:{defaultAnimOptions:{},init:function(e,t){var n=e.curStats;n.show_animId&&(c.remove(n.show_animId),n.show_animId=null),g.none.start(e,t)},start:function(e,t){g.none.stop(e,!0)},stop:function(e,t,n){var a=e.curStats;return n=null!=n?n:e.aplStats.show_on,a.show_inAnim=!1,t&&Ge(e,n),n?1:0}},fade:{defaultAnimOptions:{duration:300,timing:"linear"},init:function(n,e){var t=n.curStats,a=n.aplStats;t.show_animId&&c.remove(t.show_animId),t.show_animId=c.add(function(e){return e},function(e,t){t?g.fade.stop(n,!0):(n.svg.style.opacity=e+"",le&&(Ae(n,n.svg),Ve(n)))},a.show_animOptions.duration,1,a.show_animOptions.timing,null,!1),g.fade.start(n,e)},start:function(e,t){var n,a=e.curStats;a.show_inAnim&&(n=c.stop(a.show_animId)),Ge(e,1),a.show_inAnim=!0,c.start(a.show_animId,!e.aplStats.show_on,null!=t?t:n)},stop:function(e,t,n){var a,i=e.curStats;return n=null!=n?n:e.aplStats.show_on,a=i.show_inAnim?c.stop(i.show_animId):n?1:0,i.show_inAnim=!1,t&&(e.svg.style.opacity=n?"":"0",Ge(e,n)),a}},draw:{defaultAnimOptions:{duration:500,timing:[.58,0,.42,1]},init:function(n,e){var t=n.curStats,a=n.aplStats,l=n.pathList.baseVal,i=Oe(l),r=i.segsLen,s=i.lenAll;t.show_animId&&c.remove(t.show_animId),t.show_animId=c.add(function(e){var t,n,a,i,o=-1;if(0===e)n=[[l[0][0],l[0][0]]];else if(1===e)n=l;else{for(t=s*e,n=[];t>=r[++o];)n.push(l[o]),t-=r[o];t&&(2===(a=l[o]).length?n.push([a[0],ve(a[0],a[1],t/r[o])]):(i=xe(a[0],a[1],a[2],a[3],ke(a[0],a[1],a[2],a[3],t)),n.push([a[0],i.fromP1,i.fromP2,i])))}return n},function(e,t){t?g.draw.stop(n,!0):(n.pathList.animVal=e,De(n,{path:!0}))},a.show_animOptions.duration,1,a.show_animOptions.timing,null,!1),g.draw.start(n,e)},start:function(e,t){var n,a=e.curStats;a.show_inAnim&&(n=c.stop(a.show_animId)),Ge(e,1),a.show_inAnim=!0,Ie(e,"apl_position",g.draw.update),c.start(a.show_animId,!e.aplStats.show_on,null!=t?t:n)},stop:function(e,t,n){var a,i=e.curStats;return n=null!=n?n:e.aplStats.show_on,a=i.show_inAnim?c.stop(i.show_animId):n?1:0,i.show_inAnim=!1,t&&(e.pathList.animVal=n?null:[[e.pathList.baseVal[0][0],e.pathList.baseVal[0][0]]],De(e,{path:!0}),Ge(e,n)),a},update:function(e){Ce(e,"apl_position",g.draw.update),e.curStats.show_inAnim?g.draw.init(e,g.draw.stop(e)):e.aplStats.show_animOptions={}}}},function(){function r(n){return function(e){var t={};t[n]=e,this.setOptions(t)}}[["start","anchorSE",0],["end","anchorSE",1],["color","lineColor"],["size","lineSize"],["startSocketGravity","socketGravitySE",0],["endSocketGravity","socketGravitySE",1],["startPlugColor","plugColorSE",0],["endPlugColor","plugColorSE",1],["startPlugSize","plugSizeSE",0],["endPlugSize","plugSizeSE",1],["outline","lineOutlineEnabled"],["outlineColor","lineOutlineColor"],["outlineSize","lineOutlineSize"],["startPlugOutline","plugOutlineEnabledSE",0],["endPlugOutline","plugOutlineEnabledSE",1],["startPlugOutlineColor","plugOutlineColorSE",0],["endPlugOutlineColor","plugOutlineColorSE",1],["startPlugOutlineSize","plugOutlineSizeSE",0],["endPlugOutlineSize","plugOutlineSizeSE",1]].forEach(function(e){var t=e[0],n=e[1],a=e[2];Object.defineProperty(Ye.prototype,t,{get:function(){var e=null!=a?K[this._id].options[n][a]:n?K[this._id].options[n]:K[this._id].options[t];return null==e?x:de(e)},set:r(t),enumerable:!0})}),[["path",m],["startSocket",n,"socketSE",0],["endSocket",n,"socketSE",1],["startPlug",E,"plugSE",0],["endPlug",E,"plugSE",1]].forEach(function(e){var a=e[0],i=e[1],o=e[2],l=e[3];Object.defineProperty(Ye.prototype,a,{get:function(){var t,n=null!=l?K[this._id].options[o][l]:o?K[this._id].options[o]:K[this._id].options[a];return n?Object.keys(i).some(function(e){return i[e]===n&&(t=e,!0)})?t:new Error("It's broken"):x},set:r(a),enumerable:!0})}),Object.keys(te).forEach(function(n){var a=te[n];Object.defineProperty(Ye.prototype,n,{get:function(){var u,e,t=K[this._id].options[n];return k(t)?(u=t,e=a.optionsConf.reduce(function(e,t){var n,a=t[0],i=t[1],o=t[2],l=t[3],r=t[4],s=null!=r?u[l][r]:l?u[l]:u[i];return e[i]="id"===a?s?Object.keys(o).some(function(e){return o[e]===s&&(n=e,!0)})?n:new Error("It's broken"):x:null==s?x:de(s),e},{}),a.anim&&(e.animation=de(u.animation)),e):t},set:r(n),enumerable:!0})}),["startLabel","endLabel","middleLabel"].forEach(function(e,n){Object.defineProperty(Ye.prototype,e,{get:function(){var e=K[this._id],t=e.options;return t.labelSEM[n]&&!e.optionIsAttach.labelSEM[n]?$[t.labelSEM[n]._id].text:t.labelSEM[n]||""},set:r(e),enumerable:!0})})}(),Ye.prototype.setOptions=function(e){return Ze(K[this._id],e),this},Ye.prototype.position=function(){return De(K[this._id],{position:!0}),this},Ye.prototype.remove=function(){var t=K[this._id],n=t.curStats;Object.keys(te).forEach(function(e){var t=e+"_animId";n[t]&&c.remove(n[t])}),n.show_animId&&c.remove(n.show_animId),t.attachments.slice().forEach(function(e){Ue(t,e)}),t.baseWindow&&t.svg&&t.baseWindow.document.body.removeChild(t.svg),delete K[this._id]},Ye.prototype.show=function(e,t){return je(K[this._id],!0,e,t),this},Ye.prototype.hide=function(e,t){return je(K[this._id],!1,e,t),this},o=function(t){t&&$[t._id]&&(t.boundTargets.slice().forEach(function(e){Ue(e.props,t,!0)}),t.conf.remove&&t.conf.remove(t),delete $[t._id])},S=function(){function e(e,t){var n,a={conf:e,curStats:{},aplStats:{},boundTargets:[]},i={};e.argOptions.every(function(e){return!(!t.length||("string"==typeof e.type?typeof t[0]!==e.type:"function"!=typeof e.type||!e.type(t[0])))&&(i[e.optionName]=t.shift(),!0)}),n=t.length&&k(t[0])?de(t[0]):{},Object.keys(i).forEach(function(e){n[e]=i[e]}),e.stats&&(Te(a.curStats,e.stats),Te(a.aplStats,e.stats)),Object.defineProperty(this,"_id",{value:++ee}),Object.defineProperty(this,"isRemoved",{get:function(){return!$[this._id]}}),a._id=this._id,e.init&&!e.init(a,n)||($[this._id]=a)}return e.prototype.remove=function(){var t=this,n=$[t._id];n&&(n.boundTargets.slice().forEach(function(e){n.conf.removeOption(n,e)}),Le(function(){var e=$[t._id];e&&(console.error("LeaderLineAttachment was not removed by removeOption"),o(e))}))},e}(),window.LeaderLineAttachment=S,_=function(e,t){return e instanceof S&&(!(e.isRemoved||t&&$[e._id].conf.type!==t)||null)},y={pointAnchor:{type:"anchor",argOptions:[{optionName:"element",type:ye}],init:function(e,t){return e.element=y.pointAnchor.checkElement(t.element),e.x=y.pointAnchor.parsePercent(t.x,!0)||[.5,!0],e.y=y.pointAnchor.parsePercent(t.y,!0)||[.5,!0],!0},removeOption:function(e,t){var n=t.props,a={},i=e.element,o=n.options.anchorSE["start"===t.optionName?1:0];i===o&&(i=o===document.body?new S(y.pointAnchor,[i]):document.body),a[t.optionName]=i,Ze(n,a)},getBBoxNest:function(e,t){var n=ge(e.element,t.baseWindow),a=n.width,i=n.height;return n.width=n.height=0,n.left=n.right=n.left+e.x[0]*(e.x[1]?a:1),n.top=n.bottom=n.top+e.y[0]*(e.y[1]?i:1),n},parsePercent:function(e,t){var n,a,i=!1;return w(e)?a=e:"string"==typeof e&&(n=u.exec(e))&&n[2]&&(i=0!==(a=parseFloat(n[1])/100)),null!=a&&(t||0<=a)?[a,i]:null},checkElement:function(e){if(null==e)e=document.body;else if(!ye(e))throw new Error("`element` must be Element");return e}},areaAnchor:{type:"anchor",argOptions:[{optionName:"element",type:ye},{optionName:"shape",type:"string"}],stats:{color:{},strokeWidth:{},elementWidth:{},elementHeight:{},elementLeft:{},elementTop:{},pathListRel:{},bBoxRel:{},pathData:{},viewBoxBBox:{hasProps:!0},dashLen:{},dashGap:{}},init:function(i,e){var t,n,a,o=[];return i.element=y.pointAnchor.checkElement(e.element),"string"==typeof e.color&&(i.color=e.color.trim()),"string"==typeof e.fillColor&&(i.fill=e.fillColor.trim()),w(e.size)&&0<=e.size&&(i.size=e.size),e.dash&&(i.dash=!0,w(e.dash.len)&&0i.right&&(i.right=t),ni.bottom&&(i.bottom=n)):i={left:t,right:t,top:n,bottom:n},o?P.pathListRel.push([o,{x:t,y:n}]):P.pathListRel=[],o={x:t,y:n}}),P.pathListRel.push([]),e=P.strokeWidth/2,l=[{x:i.left-e,y:i.top-e},{x:i.right+e,y:i.bottom+e}],P.bBoxRel={left:l[0].x,top:l[0].y,right:l[1].x,bottom:l[1].y,width:l[1].x-l[0].x,height:l[1].y-l[0].y}}W.pathListRel=W.bBoxRel=!0}return(W.pathListRel||W.elementLeft||W.elementTop)&&(P.pathData=we(P.pathListRel,function(e){e.x+=a.left,e.y+=a.top})),We(t,N,"strokeWidth",n=P.strokeWidth)&&(t.path.style.strokeWidth=n+"px"),Me(n=P.pathData,N.pathData)&&(t.path.setPathData(n),N.pathData=n,W.pathData=!0),t.dash&&(!W.pathData&&(!W.strokeWidth||t.dashLen&&t.dashGap)||(P.dashLen=t.dashLen||2*P.strokeWidth,P.dashGap=t.dashGap||P.strokeWidth),W.dash=We(t,N,"dashLen",P.dashLen)||W.dash,W.dash=We(t,N,"dashGap",P.dashGap)||W.dash,W.dash&&(t.path.style.strokeDasharray=N.dashLen+","+N.dashGap)),C=P.viewBoxBBox,L=N.viewBoxBBox,A=t.svg.viewBox.baseVal,V=t.svg.style,C.x=P.bBoxRel.left+a.left,C.y=P.bBoxRel.top+a.top,C.width=P.bBoxRel.width,C.height=P.bBoxRel.height,["x","y","width","height"].forEach(function(e){(n=C[e])!==L[e]&&(A[e]=L[e]=n,V[oe[e]]=n+("x"===e||"y"===e?t.bodyOffset[e]:0)+"px")}),W.strokeWidth||W.pathListRel||W.bBoxRel}},mouseHoverAnchor:{type:"anchor",argOptions:[{optionName:"element",type:ye},{optionName:"showEffectName",type:"string"}],style:{backgroundImage:"url('data:image/svg+xml;charset=utf-8;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0Ij48cG9seWdvbiBwb2ludHM9IjI0LDAgMCw4IDgsMTEgMCwxOSA1LDI0IDEzLDE2IDE2LDI0IiBmaWxsPSJjb3JhbCIvPjwvc3ZnPg==')",backgroundSize:"",backgroundRepeat:"no-repeat",backgroundColor:"#f8f881",cursor:"default"},hoverStyle:{backgroundImage:"none",backgroundColor:"#fadf8f"},padding:{top:1,right:15,bottom:1,left:2},minHeight:15,backgroundPosition:{right:2,top:2},backgroundSize:{width:12,height:12},dirKeys:[["top","Top"],["right","Right"],["bottom","Bottom"],["left","Left"]],init:function(a,i){var o,t,e,n,l,r,s,u,h,p,c,d=y.mouseHoverAnchor,f={};if(a.element=y.pointAnchor.checkElement(i.element),u=a.element,!((p=u.ownerDocument)&&(h=p.defaultView)&&h.HTMLElement&&u instanceof h.HTMLElement))throw new Error("`element` must be HTML element");return d.style.backgroundSize=d.backgroundSize.width+"px "+d.backgroundSize.height+"px",["style","hoverStyle"].forEach(function(e){var n=d[e];a[e]=Object.keys(n).reduce(function(e,t){return e[t]=n[t],e},{})}),"inline"===(o=a.element.ownerDocument.defaultView.getComputedStyle(a.element,"")).display?a.style.display="inline-block":"none"===o.display&&(a.style.display="block"),y.mouseHoverAnchor.dirKeys.forEach(function(e){var t=e[0],n="padding"+e[1];parseFloat(o[n])e.x2&&(e.x2=a.x2),a.y2>e.y2&&(e.y2=a.y2)},newText:function(e,t,n,a,i){var o,l,r,s,u,h;return(o=t.createElementNS(b,"text")).textContent=e,[o.x,o.y].forEach(function(e){var t=n.createSVGLength();t.newValueSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_PX,0),e.baseVal.initialize(t)}),"boolean"!=typeof f&&(f="paintOrder"in o.style),i&&!f?(r=t.createElementNS(b,"defs"),o.id=a,r.appendChild(o),(u=(l=t.createElementNS(b,"g")).appendChild(t.createElementNS(b,"use"))).href.baseVal="#"+a,(s=l.appendChild(t.createElementNS(b,"use"))).href.baseVal="#"+a,(h=u.style).strokeLinejoin="round",{elmPosition:o,styleText:o.style,styleFill:s.style,styleStroke:h,styleShow:l.style,elmsAppend:[r,l]}):(h=o.style,i&&(h.strokeLinejoin="round",h.paintOrder="stroke"),{elmPosition:o,styleText:h,styleFill:h,styleStroke:i?h:null,styleShow:h,elmsAppend:[o]})},getMidPoint:function(e,t){var n,a,i,o=Oe(e),l=o.segsLen,r=o.lenAll,s=-1;if((n=r/2+(t||0))<=0)return 2===(a=e[0]).length?ve(a[0],a[1],0):xe(a[0],a[1],a[2],a[3],0);if(r<=n)return 2===(a=e[e.length-1]).length?ve(a[0],a[1],1):xe(a[0],a[1],a[2],a[3],1);for(i=[];n>l[++s];)i.push(e[s]),n-=l[s];return 2===(a=e[s]).length?ve(a[0],a[1],n/l[s]):xe(a[0],a[1],a[2],a[3],ke(a[0],a[1],a[2],a[3],n))},initSvg:function(t,n){var e,a,i=y.captionLabel.newText(t.text,n.baseWindow.document,n.svg,v+"-captionLabel-"+t._id,t.outlineColor);["elmPosition","styleFill","styleShow","elmsAppend"].forEach(function(e){t[e]=i[e]}),t.isShown=!1,t.styleShow.visibility="hidden",y.captionLabel.textStyleProps.forEach(function(e){null!=t[e]&&(i.styleText[e]=t[e])}),i.elmsAppend.forEach(function(e){n.svg.appendChild(e)}),e=i.elmPosition.getBBox(),t.width=e.width,t.height=e.height,t.outlineColor&&(a=10<(a=e.height/9)?10:a<2?2:a,i.styleStroke.strokeWidth=a+"px",i.styleStroke.stroke=t.outlineColor),t.strokeWidth=a||0,Te(t.aplStats,y.captionLabel.stats),t.updateColor(n),t.refSocketXY?t.updateSocketXY(n):t.updatePath(n),ue&&De(n,{}),t.updateShow(n)},bind:function(e,t){var n=t.props;return e.color||Ie(n,"cur_line_color",e.updateColor),(e.refSocketXY="startLabel"===t.optionName||"endLabel"===t.optionName)?(e.socketIndex="startLabel"===t.optionName?0:1,Ie(n,"apl_position",e.updateSocketXY),e.offset||(Ie(n,"cur_attach_plugSideLenSE",e.updateSocketXY),Ie(n,"cur_line_strokeWidth",e.updateSocketXY))):Ie(n,"apl_path",e.updatePath),Ie(n,"svgShow",e.updateShow),ue&&Ie(n,"new_edge4viewBox",e.adjustEdge),y.captionLabel.initSvg(e,n),!0},unbind:function(e,t){var n=t.props;e.elmsAppend&&(e.elmsAppend.forEach(function(e){n.svg.removeChild(e)}),e.elmPosition=e.styleFill=e.styleShow=e.elmsAppend=null),Te(e.curStats,y.captionLabel.stats),Te(e.aplStats,y.captionLabel.stats),e.color||Ce(n,"cur_line_color",e.updateColor),e.refSocketXY?(Ce(n,"apl_position",e.updateSocketXY),e.offset||(Ce(n,"cur_attach_plugSideLenSE",e.updateSocketXY),Ce(n,"cur_line_strokeWidth",e.updateSocketXY))):Ce(n,"apl_path",e.updatePath),Ce(n,"svgShow",e.updateShow),ue&&(Ce(n,"new_edge4viewBox",e.adjustEdge),De(n,{}))},removeOption:function(e,t){var n=t.props,a={};a[t.optionName]="",Ze(n,a)},remove:function(t){t.boundTargets.length&&(console.error("LeaderLineAttachment was not unbound by remove"),t.boundTargets.forEach(function(e){y.captionLabel.unbind(t,e)}))}},pathLabel:{type:"label",argOptions:[{optionName:"text",type:"string"}],stats:{color:{},startOffset:{},pathData:{}},init:function(s,t){return"string"==typeof t.text&&(s.text=t.text.trim()),!!s.text&&("string"==typeof t.color&&(s.color=t.color.trim()),s.outlineColor="string"==typeof t.outlineColor?t.outlineColor.trim():"#fff",w(t.lineOffset)&&(s.lineOffset=t.lineOffset),y.captionLabel.textStyleProps.forEach(function(e){null!=t[e]&&(s[e]=t[e])}),s.updateColor=function(e){y.captionLabel.updateColor(s,e)},s.updatePath=function(e){var t,n=s.curStats,a=s.aplStats,i=e.curStats,o=e.pathList.animVal||e.pathList.baseVal;o&&(n.pathData=t=y.pathLabel.getOffsetPathData(o,i.line_strokeWidth/2+s.strokeWidth/2+s.height/4,1.25*s.height),Me(t,a.pathData)&&(s.elmPath.setPathData(t),a.pathData=t,s.bBox=s.elmPosition.getBBox(),s.updateStartOffset(e)))},s.updateStartOffset=function(e){var t,n,a,i,o=s.curStats,l=s.aplStats,r=e.curStats;o.pathData&&((2!==s.semIndex||s.lineOffset)&&(t=o.pathData.reduce(function(e,t){var n,a=t.values;switch(t.type){case"M":i={x:a[0],y:a[1]};break;case"L":n={x:a[0],y:a[1]},i&&(e+=_e(i,n)),i=n;break;case"C":n={x:a[4],y:a[5]},i&&(e+=be(i,{x:a[0],y:a[1]},{x:a[2],y:a[3]},n)),i=n}return e},0),a=0===s.semIndex?0:1===s.semIndex?t:t/2,2!==s.semIndex&&(n=Math.max(r.attach_plugBackLenSE[s.semIndex]||0,r.line_strokeWidth/2)+s.strokeWidth/2+s.height/4,a=(a+=0===s.semIndex?n:-n)<0?0:tx?((t=b.points)[1]=Ee(t[0],t[1],-x),b.len=_e(t[0],t[1])):(b.points=null,b.len=0),e.len>x+n?((t=e.points)[0]=Ee(t[1],t[0],-(x+n)),e.len=_e(t[0],t[1])):(e.points=null,e.len=0)),b=e):b=null}),k.reduce(function(t,e){var n=e.points;return n&&(a&&w(n[0],a)||t.push({type:"M",values:[n[0].x,n[0].y]}),"line"===e.type?t.push({type:"L",values:[n[1].x,n[1].y]}):(n.shift(),n.forEach(function(e){t.push({type:"L",values:[e.x,e.y]})})),a=n[n.length-1]),t},[])},newText:function(e,t,n,a){var i,o,l,r,s,u,h,p,c,d;return(r=(l=t.createElementNS(b,"defs")).appendChild(t.createElementNS(b,"path"))).id=i=n+"-path",(u=(s=t.createElementNS(b,"text")).appendChild(t.createElementNS(b,"textPath"))).href.baseVal="#"+i,u.startOffset.baseVal.newValueSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_PX,0),u.textContent=e,"boolean"!=typeof f&&(f="paintOrder"in s.style),a&&!f?(s.id=o=n+"-text",l.appendChild(s),(c=(h=t.createElementNS(b,"g")).appendChild(t.createElementNS(b,"use"))).href.baseVal="#"+o,(p=h.appendChild(t.createElementNS(b,"use"))).href.baseVal="#"+o,(d=c.style).strokeLinejoin="round",{elmPosition:s,elmPath:r,elmOffset:u,styleText:s.style,styleFill:p.style,styleStroke:d,styleShow:h.style,elmsAppend:[l,h]}):(d=s.style,a&&(d.strokeLinejoin="round",d.paintOrder="stroke"),{elmPosition:s,elmPath:r,elmOffset:u,styleText:d,styleFill:d,styleStroke:a?d:null,styleShow:d,elmsAppend:[l,s]})},initSvg:function(t,n){var e,a,i=y.pathLabel.newText(t.text,n.baseWindow.document,v+"-pathLabel-"+t._id,t.outlineColor);["elmPosition","elmPath","elmOffset","styleFill","styleShow","elmsAppend"].forEach(function(e){t[e]=i[e]}),t.isShown=!1,t.styleShow.visibility="hidden",y.captionLabel.textStyleProps.forEach(function(e){null!=t[e]&&(i.styleText[e]=t[e])}),i.elmsAppend.forEach(function(e){n.svg.appendChild(e)}),i.elmPath.setPathData([{type:"M",values:[0,100]},{type:"h",values:[100]}]),e=i.elmPosition.getBBox(),i.styleText.textAnchor=["start","end","middle"][t.semIndex],2!==t.semIndex||t.lineOffset||i.elmOffset.startOffset.baseVal.newValueSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_PERCENTAGE,50),t.height=e.height,t.outlineColor&&(a=10<(a=e.height/9)?10:a<2?2:a,i.styleStroke.strokeWidth=a+"px",i.styleStroke.stroke=t.outlineColor),t.strokeWidth=a||0,Te(t.aplStats,y.pathLabel.stats),t.updateColor(n),t.updatePath(n),t.updateStartOffset(n),ue&&De(n,{}),t.updateShow(n)},bind:function(e,t){var n=t.props;return e.color||Ie(n,"cur_line_color",e.updateColor),Ie(n,"cur_line_strokeWidth",e.updatePath),Ie(n,"apl_path",e.updatePath),e.semIndex="startLabel"===t.optionName?0:"endLabel"===t.optionName?1:2,(2!==e.semIndex||e.lineOffset)&&Ie(n,"cur_attach_plugBackLenSE",e.updateStartOffset),Ie(n,"svgShow",e.updateShow),ue&&Ie(n,"new_edge4viewBox",e.adjustEdge),y.pathLabel.initSvg(e,n),!0},unbind:function(e,t){var n=t.props;e.elmsAppend&&(e.elmsAppend.forEach(function(e){n.svg.removeChild(e)}),e.elmPosition=e.elmPath=e.elmOffset=e.styleFill=e.styleShow=e.elmsAppend=null),Te(e.curStats,y.pathLabel.stats),Te(e.aplStats,y.pathLabel.stats),e.color||Ce(n,"cur_line_color",e.updateColor),Ce(n,"cur_line_strokeWidth",e.updatePath),Ce(n,"apl_path",e.updatePath),(2!==e.semIndex||e.lineOffset)&&Ce(n,"cur_attach_plugBackLenSE",e.updateStartOffset),Ce(n,"svgShow",e.updateShow),ue&&(Ce(n,"new_edge4viewBox",e.adjustEdge),De(n,{}))},removeOption:function(e,t){var n=t.props,a={};a[t.optionName]="",Ze(n,a)},remove:function(t){t.boundTargets.length&&(console.error("LeaderLineAttachment was not unbound by remove"),t.boundTargets.forEach(function(e){y.pathLabel.unbind(t,e)}))}}},Object.keys(y).forEach(function(e){Ye[e]=function(){return new S(y[e],Array.prototype.slice.call(arguments))}}),Ye.positionByWindowResize=!0,window.addEventListener("resize",O.add(function(){Ye.positionByWindowResize&&Object.keys(K).forEach(function(e){De(K[e],{position:!0})})}),!1),Ye}(); --------------------------------------------------------------------------------