├── .npmignore ├── .gitignore ├── images └── architecture.png ├── prettier.config.js ├── example ├── pages │ ├── shared │ │ ├── imgs │ │ │ ├── top.png │ │ │ ├── contact.png │ │ │ ├── github.png │ │ │ ├── logo │ │ │ │ ├── npm.png │ │ │ │ ├── oss.png │ │ │ │ ├── s3.png │ │ │ │ ├── dropbox.png │ │ │ │ ├── github.png │ │ │ │ ├── gitlab.png │ │ │ │ ├── github_light.png │ │ │ │ └── google-driver.png │ │ │ ├── twitter.png │ │ │ └── extention.png │ │ ├── style.css │ │ ├── popper.js │ │ │ └── popper.min.js │ │ ├── bootstrap │ │ │ └── js │ │ │ │ └── bootstrap.min.js │ │ └── jquery │ │ │ └── jquery-3.4.1.slim.min.js │ ├── list_intalled.hb │ ├── setting.hb │ ├── list_extension.hb │ ├── detail_extension.hb │ └── home.html ├── .vscodeignore ├── .vscode │ ├── extensions.json │ ├── tasks.json │ ├── settings.json │ └── launch.json ├── CHANGELOG.md ├── README.md ├── .eslintrc.json ├── tsconfig.json ├── src │ ├── extension.ts │ └── home.ts ├── package.json └── vsc-extension-quickstart.md ├── tslint.json ├── .eslintrc.json ├── tsconfig.json ├── package.json ├── src └── pages.ts ├── README.md └── LICENSE /.npmignore: -------------------------------------------------------------------------------- 1 | src/ 2 | example/ 3 | tsconfig.json -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | lib 3 | out 4 | *.vsix 5 | *.tgz 6 | *.log -------------------------------------------------------------------------------- /images/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DTeam-Top/vscode-page/HEAD/images/architecture.png -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | singleQuote: true, 3 | trailingComma: 'es5', 4 | }; 5 | -------------------------------------------------------------------------------- /example/pages/shared/imgs/top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DTeam-Top/vscode-page/HEAD/example/pages/shared/imgs/top.png -------------------------------------------------------------------------------- /example/pages/shared/imgs/contact.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DTeam-Top/vscode-page/HEAD/example/pages/shared/imgs/contact.png -------------------------------------------------------------------------------- /example/pages/shared/imgs/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DTeam-Top/vscode-page/HEAD/example/pages/shared/imgs/github.png -------------------------------------------------------------------------------- /example/pages/shared/imgs/logo/npm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DTeam-Top/vscode-page/HEAD/example/pages/shared/imgs/logo/npm.png -------------------------------------------------------------------------------- /example/pages/shared/imgs/logo/oss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DTeam-Top/vscode-page/HEAD/example/pages/shared/imgs/logo/oss.png -------------------------------------------------------------------------------- /example/pages/shared/imgs/logo/s3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DTeam-Top/vscode-page/HEAD/example/pages/shared/imgs/logo/s3.png -------------------------------------------------------------------------------- /example/pages/shared/imgs/twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DTeam-Top/vscode-page/HEAD/example/pages/shared/imgs/twitter.png -------------------------------------------------------------------------------- /example/pages/shared/imgs/extention.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DTeam-Top/vscode-page/HEAD/example/pages/shared/imgs/extention.png -------------------------------------------------------------------------------- /example/pages/shared/imgs/logo/dropbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DTeam-Top/vscode-page/HEAD/example/pages/shared/imgs/logo/dropbox.png -------------------------------------------------------------------------------- /example/pages/shared/imgs/logo/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DTeam-Top/vscode-page/HEAD/example/pages/shared/imgs/logo/github.png -------------------------------------------------------------------------------- /example/pages/shared/imgs/logo/gitlab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DTeam-Top/vscode-page/HEAD/example/pages/shared/imgs/logo/gitlab.png -------------------------------------------------------------------------------- /example/pages/shared/imgs/logo/github_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DTeam-Top/vscode-page/HEAD/example/pages/shared/imgs/logo/github_light.png -------------------------------------------------------------------------------- /example/pages/shared/imgs/logo/google-driver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DTeam-Top/vscode-page/HEAD/example/pages/shared/imgs/logo/google-driver.png -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "gts/tslint.json", 3 | "linterOptions": { 4 | "exclude": ["**/*.json"] 5 | }, 6 | "rules": { 7 | "no-any": false 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /example/.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | out/test/** 4 | src/** 5 | .gitignore 6 | vsc-extension-quickstart.md 7 | **/tsconfig.json 8 | **/.eslintrc.json 9 | **/*.map 10 | **/*.ts 11 | -------------------------------------------------------------------------------- /example/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "dbaeumer.vscode-eslint" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /example/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to the "page-example" extension will be documented in this file. 4 | 5 | Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. 6 | 7 | ## [Unreleased] 8 | 9 | - Initial release -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | This is an example repository demonstrating the vscode-page extension API. 2 | 3 | # Features 4 | This example will just allow you to display pages via the vscode-page API. 5 | 6 | ## Requirements 7 | 8 | All you need is vscode 9 | 10 | Please run `npm install`, `npm install vscode-page`, and `npm install handlebars` to install all dependencies. Then run `vsce package` 11 | 12 | 13 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "parserOptions": { 5 | "ecmaVersion": 6, 6 | "sourceType": "module" 7 | }, 8 | "plugins": ["@typescript-eslint"], 9 | "rules": { 10 | "@typescript-eslint/class-name-casing": "warn", 11 | "@typescript-eslint/semi": "warn", 12 | "curly": "warn", 13 | "eqeqeq": "warn", 14 | "no-throw-literal": "warn", 15 | "semi": "off" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /example/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // See https://go.microsoft.com/fwlink/?LinkId=733558 2 | // for the documentation about the tasks.json format 3 | { 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "npm", 8 | "script": "watch", 9 | "problemMatcher": "$tsc-watch", 10 | "isBackground": true, 11 | "presentation": { 12 | "reveal": "never" 13 | }, 14 | "group": { 15 | "kind": "build", 16 | "isDefault": true 17 | } 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /example/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.exclude": { 4 | "out": false // set this to true to hide the "out" folder with the compiled JS files 5 | }, 6 | "search.exclude": { 7 | "out": true // set this to false to include "out" folder in search results 8 | }, 9 | // Turn off tsc task auto detection since we have the necessary tasks as npm scripts 10 | "typescript.tsc.autoDetect": "off" 11 | } -------------------------------------------------------------------------------- /example/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "parserOptions": { 5 | "ecmaVersion": 6, 6 | "sourceType": "module" 7 | }, 8 | "plugins": [ 9 | "@typescript-eslint" 10 | ], 11 | "rules": { 12 | "@typescript-eslint/class-name-casing": "warn", 13 | "@typescript-eslint/semi": "warn", 14 | "curly": "warn", 15 | "eqeqeq": "warn", 16 | "no-throw-literal": "warn", 17 | "semi": "off" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "outDir": "lib", 6 | "lib": ["es6"], 7 | "sourceMap": true, 8 | "rootDir": "src", 9 | "strict": true /* enable all strict type-checking options */ 10 | /* Additional Checks */ 11 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 12 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 13 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 14 | }, 15 | "exclude": ["node_modules", "example"] 16 | } 17 | -------------------------------------------------------------------------------- /example/pages/list_intalled.hb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | {{#each extensionInstalled}} 13 | 14 | 15 | 16 | 17 | 20 | 21 | 22 | {{/each}} 23 | 24 |
IdVersionDescriptionEnabledRepository
{{extId}}{{version}}{{describe}} 18 | {{#if enabled}} √ {{else}} X {{/if}} 19 | {{repository}}
25 | -------------------------------------------------------------------------------- /example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "outDir": "out", 6 | "lib": [ 7 | "es6" 8 | ], 9 | "sourceMap": true, 10 | "rootDir": "src", 11 | "strict": true /* enable all strict type-checking options */ 12 | /* Additional Checks */ 13 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 14 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 15 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 16 | }, 17 | "exclude": [ 18 | "node_modules", 19 | ".vscode-test" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /example/src/extension.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from "vscode"; 2 | import { createOrShowPage } from "vscode-page"; 3 | import { messageMappings } from "./home"; 4 | 5 | export function activate(context: vscode.ExtensionContext) { 6 | registerCommands(context); 7 | } 8 | 9 | export function deactivate() {} 10 | 11 | function registerCommands(context: vscode.ExtensionContext) { 12 | let homePage = vscode.commands.registerCommand("ext.home", async () => { 13 | createOrShowPage( 14 | "name", 15 | "ext.home", 16 | "Sample Page", 17 | "pages", 18 | "home.html", 19 | context, 20 | messageMappings 21 | ); 22 | }); 23 | 24 | context.subscriptions.push(homePage); 25 | } 26 | -------------------------------------------------------------------------------- /example/pages/setting.hb: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | Setting is a json array, and each item has following properties: 5 |
    6 |
  • name, repository name
  • 7 |
  • type, one of ["oss", "s3", "github", "gitlab", "google-driver", "dropbox", "npm"]
  • 8 |
  • options, authentication options of each repository type, please check its document for more details.
  • 9 |
10 |
11 | Here is an example: 12 |
{{example}}
13 |       
14 |
15 |
16 |
17 | 18 |
19 |
20 | 21 | 22 |
23 |
24 |
-------------------------------------------------------------------------------- /example/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that compiles the extension and then opens it inside a new window 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | { 6 | "version": "0.2.0", 7 | "configurations": [ 8 | { 9 | "name": "Run Extension", 10 | "type": "extensionHost", 11 | "request": "launch", 12 | "runtimeExecutable": "${execPath}", 13 | "args": [ 14 | "--extensionDevelopmentPath=${workspaceFolder}" 15 | ], 16 | "outFiles": [ 17 | "${workspaceFolder}/out/**/*.js" 18 | ], 19 | "preLaunchTask": "${defaultBuildTask}" 20 | }, 21 | { 22 | "name": "Extension Tests", 23 | "type": "extensionHost", 24 | "request": "launch", 25 | "runtimeExecutable": "${execPath}", 26 | "args": [ 27 | "--extensionDevelopmentPath=${workspaceFolder}", 28 | "--extensionTestsPath=${workspaceFolder}/out/test/suite/index" 29 | ], 30 | "outFiles": [ 31 | "${workspaceFolder}/out/test/**/*.js" 32 | ], 33 | "preLaunchTask": "${defaultBuildTask}" 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /example/pages/list_extension.hb: -------------------------------------------------------------------------------- 1 | {{#each extensions}} 2 |
3 |
4 | {{#if extension.icon}} 5 | 6 | {{else}} 7 | 8 | {{/if}} 9 |
10 |
11 |
12 |
13 |
14 | {{extension.extId}} 15 | {{extension.currentVersion}} 16 |
17 |
18 | {{extension.describe}} 19 |
20 |
21 | Created:{{formatDate extension.dateCreated}}    Last Update:{{formatDate extension.lastUpdate}} 22 |
23 |
24 |
25 |
26 |
27 | 28 |
29 |
30 | {{/each}} -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "page-example", 3 | "displayName": "page-example", 4 | "author": "dteam", 5 | "publisher": "dteam", 6 | "repository": { 7 | "type": "git", 8 | "url": "git+https://github.com/DTeam-Top/vscode-page.git" 9 | }, 10 | "description": "this is a vscode-page example.", 11 | "version": "0.0.2", 12 | "engines": { 13 | "vscode": "^1.42.0" 14 | }, 15 | "categories": [ 16 | "Other" 17 | ], 18 | "activationEvents": [ 19 | "*" 20 | ], 21 | "main": "./out/extension.js", 22 | "contributes": { 23 | "commands": [ 24 | { 25 | "command": "ext.home", 26 | "title": "Show Example Page" 27 | } 28 | ] 29 | }, 30 | "scripts": { 31 | "vscode:prepublish": "npm run compile", 32 | "compile": "tsc -p ./", 33 | "lint": "eslint src --ext ts", 34 | "watch": "tsc -watch -p ./", 35 | "pretest": "npm run compile && npm run lint", 36 | "test": "node ./out/test/runTest.js" 37 | }, 38 | "devDependencies": { 39 | "@types/glob": "^7.1.1", 40 | "@types/mocha": "^7.0.1", 41 | "@types/node": "^12.11.7", 42 | "@types/vscode": "^1.42.0", 43 | "eslint": "^6.8.0", 44 | "@typescript-eslint/parser": "^2.18.0", 45 | "@typescript-eslint/eslint-plugin": "^2.18.0", 46 | "glob": "^7.1.6", 47 | "mocha": "^7.0.1", 48 | "typescript": "^3.7.5", 49 | "vscode-test": "^1.3.0" 50 | }, 51 | "dependencies": { 52 | "handlebars": "^4.7.7", 53 | "vscode-page": "0.0.1" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vscode-page", 3 | "author": "dteam", 4 | "publisher": "dteam", 5 | "version": "0.0.2", 6 | "description": "A light-weight page micro framework for vscode webview.", 7 | "license": "Apache-2.0", 8 | "tags": [ 9 | "functions", 10 | "classes", 11 | "typescript", 12 | "tools", 13 | "helpers", 14 | "vscode" 15 | ], 16 | "keywords": [ 17 | "functions", 18 | "classes", 19 | "js", 20 | "ecmascript", 21 | "javascript", 22 | "typescript", 23 | "tools", 24 | "helpers", 25 | "vscode", 26 | "visual", 27 | "studio", 28 | "code", 29 | "extensions", 30 | "modules" 31 | ], 32 | "engines": { 33 | "vscode": "^1.42.0" 34 | }, 35 | "main": "lib/pages.js", 36 | "typings": "lib/pages.d.ts", 37 | "scripts": { 38 | "prepare": "rm -rf lib && tsc && tsc -d", 39 | "prepublishOnly": "npm run compile && npm run lint", 40 | "compile": "tsc -p ./", 41 | "lint": "eslint src --ext ts", 42 | "watch": "tsc -watch -p ./", 43 | "pretest": "npm run compile && npm run lint", 44 | "test": "mocha out/test/**/*.test.js", 45 | "check": "gts check", 46 | "clean": "gts clean", 47 | "fix": "gts fix", 48 | "posttest": "npm run check" 49 | }, 50 | "devDependencies": { 51 | "@types/mocha": "^7.0.1", 52 | "@types/vscode": "^1.42.0", 53 | "@types/node": "^12.11.7", 54 | "@typescript-eslint/eslint-plugin": "^2.18.0", 55 | "@typescript-eslint/parser": "^2.18.0", 56 | "eslint": "^6.8.0", 57 | "mocha": "^7.0.1", 58 | "typescript": "^3.7.5", 59 | "handlebars": "^4.7.3", 60 | "gts": "^1.1.2" 61 | }, 62 | "repository": { 63 | "type": "git", 64 | "url": "git+https://github.com/DTeam-Top/vscode-page.git" 65 | }, 66 | "bugs": { 67 | "url": "https://github.com/DTeam-Top/vscode-page/issues" 68 | }, 69 | "homepage": "https://github.com/DTeam-Top/vscode-page/blob/master/README.md" 70 | } 71 | -------------------------------------------------------------------------------- /example/pages/detail_extension.hb: -------------------------------------------------------------------------------- 1 |
2 |
3 | {{#if details.metadata.icon}} 4 | 5 | {{else}} 6 | 7 | {{/if}} 8 |
9 |
10 |
11 |
12 |
13 | {{details.metadata.extId}} 14 | {{details.metadata.currentVersion}} 15 |
16 |
17 | {{details.metadata.describe}} 18 |
19 |
20 | Created:{{formatDate details.metadata.dateCreated}}     Last Update:{{formatDate details.metadata.lastUpdate}} 21 |
22 |
23 | {{#unless installed}} 24 | 25 | {{/unless}} 26 |
27 |
28 |
29 |
30 |
31 | 37 |
38 |
39 |
40 | 45 | -------------------------------------------------------------------------------- /example/vsc-extension-quickstart.md: -------------------------------------------------------------------------------- 1 | # Welcome to your VS Code Extension 2 | 3 | ## What's in the folder 4 | 5 | * This folder contains all of the files necessary for your extension. 6 | * `package.json` - this is the manifest file in which you declare your extension and command. 7 | * The sample plugin registers a command and defines its title and command name. With this information VS Code can show the command in the command palette. It doesn’t yet need to load the plugin. 8 | * `src/extension.ts` - this is the main file where you will provide the implementation of your command. 9 | * The file exports one function, `activate`, which is called the very first time your extension is activated (in this case by executing the command). Inside the `activate` function we call `registerCommand`. 10 | * We pass the function containing the implementation of the command as the second parameter to `registerCommand`. 11 | 12 | ## Get up and running straight away 13 | 14 | * Press `F5` to open a new window with your extension loaded. 15 | * Run your command from the command palette by pressing (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and typing `Hello World`. 16 | * Set breakpoints in your code inside `src/extension.ts` to debug your extension. 17 | * Find output from your extension in the debug console. 18 | 19 | ## Make changes 20 | 21 | * You can relaunch the extension from the debug toolbar after changing code in `src/extension.ts`. 22 | * You can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes. 23 | 24 | 25 | ## Explore the API 26 | 27 | * You can open the full set of our API when you open the file `node_modules/@types/vscode/index.d.ts`. 28 | 29 | ## Run tests 30 | 31 | * Open the debug viewlet (`Ctrl+Shift+D` or `Cmd+Shift+D` on Mac) and from the launch configuration dropdown pick `Extension Tests`. 32 | * Press `F5` to run the tests in a new window with your extension loaded. 33 | * See the output of the test result in the debug console. 34 | * Make changes to `src/test/suite/extension.test.ts` or create new test files inside the `test/suite` folder. 35 | * The provided test runner will only consider files matching the name pattern `**.test.ts`. 36 | * You can create folders inside the `test` folder to structure your tests any way you want. 37 | 38 | ## Go further 39 | 40 | * Reduce the extension size and improve the startup time by [bundling your extension](https://code.visualstudio.com/api/working-with-extensions/bundling-extension). 41 | * [Publish your extension](https://code.visualstudio.com/api/working-with-extensions/publishing-extension) on the VSCode extension marketplace. 42 | * Automate builds by setting up [Continuous Integration](https://code.visualstudio.com/api/working-with-extensions/continuous-integration). 43 | -------------------------------------------------------------------------------- /example/pages/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | Sample Page 16 | 17 | 18 | 19 | 41 |
42 |
43 |
44 | 49 | 50 |
51 |
52 |

53 |
54 |
55 |
56 |
57 |
58 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /src/pages.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from 'vscode'; 2 | import * as fs from 'fs'; 3 | import * as path from 'path'; 4 | import * as handlebars from 'handlebars'; 5 | 6 | export type MessageHandler = (parameters?: any) => Promise; 7 | export interface Template { 8 | id: string; 9 | content?: string; 10 | contentUrl?: string; 11 | } 12 | export interface MesssageMaping { 13 | command: string; 14 | handler: MessageHandler; 15 | templates?: Template[]; 16 | forward?: string; 17 | } 18 | 19 | interface Content { 20 | id: string; 21 | body: string; 22 | } 23 | interface CommandResponse { 24 | command: string; 25 | contents?: Content[]; 26 | result?: any; 27 | } 28 | 29 | const currentPanels: Map = new Map(); 30 | 31 | const initJS = ` 32 | function initEventListener(fn) { 33 | window.addEventListener('message', event => { 34 | const message = event.data; 35 | if (message.command.match(/Response$/) && message.contents) { 36 | message.contents.forEach(content => { 37 | let element = document.getElementById(content.id); 38 | element.innerHTML = content.body; 39 | }); 40 | } else { 41 | if (fn) { 42 | fn(message); 43 | } 44 | } 45 | }); 46 | } 47 | `; 48 | 49 | export function createOrShowPage( 50 | name: string, 51 | viewType: string, 52 | title: string, 53 | base: string, 54 | page: string, 55 | context: vscode.ExtensionContext, 56 | messageMappings: MesssageMaping[] 57 | ) { 58 | let panel = currentPanels.get(name); 59 | if (panel) { 60 | panel.reveal(); 61 | } else { 62 | const rootString = path.join(context.extensionPath, base); 63 | const localResourceRoots = vscode.Uri.file(path.join(rootString, '/')).with( 64 | { 65 | scheme: 'vscode-resource', 66 | } 67 | ); 68 | panel = vscode.window.createWebviewPanel( 69 | viewType, 70 | title, 71 | vscode.ViewColumn.One, 72 | { 73 | enableScripts: true, 74 | retainContextWhenHidden: true, 75 | localResourceRoots: [localResourceRoots], 76 | } 77 | ); 78 | 79 | const pagePath = path.join(rootString, page); 80 | panel.webview.html = fs 81 | .readFileSync(pagePath, 'utf-8') 82 | .replace('{{base}}', localResourceRoots.toString()) 83 | .replace('"{{init}}"', initJS); 84 | panel.webview.onDidReceiveMessage( 85 | createDispatch(messageMappings, panel, context) 86 | ); 87 | panel.onDidDispose( 88 | () => currentPanels.delete(name), 89 | undefined, 90 | context.subscriptions 91 | ); 92 | currentPanels.set(name, panel); 93 | } 94 | } 95 | 96 | function createDispatch( 97 | messageMappings: MesssageMaping[], 98 | currentPanel: vscode.WebviewPanel, 99 | context: vscode.ExtensionContext 100 | ) { 101 | const handler = (message: any) => { 102 | const mapping = messageMappings.find( 103 | mapping => mapping.command === message.command 104 | ); 105 | if (mapping) { 106 | const response: CommandResponse = { 107 | command: `${message.command}Response`, 108 | }; 109 | mapping.handler.call(null, message.parameters).then(result => { 110 | if (mapping.templates) { 111 | response.contents = []; 112 | mapping.templates.forEach(template => { 113 | if (template.content) { 114 | response.contents?.push({ 115 | id: template.id, 116 | body: handlebars.compile(template.content)(result), 117 | }); 118 | } else if (template.contentUrl) { 119 | response.contents?.push({ 120 | id: template.id, 121 | body: handlebars.compile( 122 | fs 123 | .readFileSync( 124 | path.join(context.extensionPath, template.contentUrl) 125 | ) 126 | .toString() 127 | )(result), 128 | }); 129 | } 130 | }); 131 | } else if (mapping.forward) { 132 | return handler.call(null, { 133 | command: mapping.forward, 134 | parameters: result, 135 | }); 136 | } else { 137 | response.result = result; 138 | } 139 | currentPanel.webview.postMessage(response); 140 | }); 141 | } else { 142 | vscode.window.showErrorMessage( 143 | `Can not find a handler for ${message.command}.` 144 | ); 145 | } 146 | }; 147 | return handler; 148 | } 149 | -------------------------------------------------------------------------------- /example/pages/shared/style.css: -------------------------------------------------------------------------------- 1 | 2 | body.vscode-dark { 3 | color: #e9e9e9; 4 | } 5 | 6 | body.vscode-light { 7 | color: #1b1b1b; 8 | } 9 | 10 | .vscode-light .bd-toc-link { 11 | color: rgba(0,0,0,.65) !important; 12 | } 13 | 14 | .vscode-dark .bd-toc-link { 15 | color: rgba(255,255,255,.65) !important; 16 | } 17 | .vscode-light .bd-sidebar{ 18 | border-right: 1px solid rgba(0,0,0,.1); 19 | } 20 | 21 | .vscode-dark .bd-sidebar{ 22 | border-right: 1px solid rgba(244,244,244,.1); 23 | } 24 | 25 | .vscode-light .bd-search { 26 | border-bottom: 1px solid rgba(0, 0, 0, .05); 27 | } 28 | 29 | .vscode-dark .bd-search { 30 | border-bottom: 1px solid rgba(244, 244, 244, .05); 31 | } 32 | 33 | .vscode-dark hr{ 34 | border-top: 1px solid rgba(244,244,244,.1); 35 | } 36 | .vscode-dark .table{ 37 | color:unset; 38 | } 39 | 40 | .vscode-dark .table .thead-light th { 41 | color: #ffffff; 42 | background-color: #343a40; 43 | border-color: #dee2e6; 44 | } 45 | .table tbody tr:hover{ 46 | background-color: #424040; 47 | } 48 | 49 | .vscode-light .table tbody tr:hover{ 50 | background-color: #dddddd; 51 | } 52 | .container-fluid{ 53 | padding-left: unset !important; 54 | padding-right: unset !important; 55 | } 56 | 57 | .extention-title{ 58 | font-size:2rem; 59 | } 60 | .list-title ,.extention-title{ 61 | font-weight: bold; 62 | } 63 | .version{ 64 | font-weight: 100; 65 | font-size: 12px; 66 | } 67 | 68 | .vertical-align { 69 | display: flex; 70 | align-items: center; 71 | } 72 | 73 | #settingBtn{ 74 | margin: 0px auto; 75 | width: 100px; 76 | } 77 | .pagetitle{ 78 | text-align: center; 79 | } 80 | .pagetitle h1{ 81 | margin-top: 20px; 82 | margin-bottom: 20px; 83 | font-size: 3.5rem; 84 | line-height: 2.5rem; 85 | font-weight: bold; 86 | color: #808080 !important; 87 | } 88 | .pagetitle h2{ 89 | margin-top: 20px; 90 | margin-bottom: 20px; 91 | } 92 | 93 | .content{ 94 | margin:10px; 95 | height:400px; 96 | } 97 | #repos li{ 98 | cursor: pointer; 99 | width:100%; 100 | } 101 | .repos_logo{ 102 | margin-right:30px; 103 | width: 24px; 104 | } 105 | #menuList{ 106 | padding: 0; 107 | } 108 | .bd-navbar { 109 | min-height: 4rem; 110 | background-color: #333333; 111 | box-shadow: 0 0.5rem 1rem rgba(0,0,0,.05), inset 0 -1px 0 rgba(0,0,0,.1); 112 | } 113 | .bd-sidebar { 114 | position: -webkit-sticky; 115 | position: sticky; 116 | top: 4rem; 117 | z-index: 1000; 118 | height: calc(100vh - 4rem); 119 | } 120 | .navbar-brand{ 121 | color:white !important; 122 | } 123 | .nav-item img{ 124 | width:20px; 125 | } 126 | .bd-toc-link { 127 | display: block; 128 | padding: .25rem 1.5rem; 129 | font-weight: 600; 130 | } 131 | .bd-toc-link:hover { color: #808080; } 132 | .no-padding{ 133 | padding:0px !important; 134 | } 135 | .bd-search { 136 | position: relative; 137 | padding: 1rem 15px; 138 | margin-right: -15px; 139 | margin-left: -15px; 140 | } 141 | #scroll-to-top { 142 | position: fixed; 143 | width: 40px; 144 | height: 40px; 145 | right: 25px; 146 | bottom: 25px; 147 | background-color: #444444; 148 | border-radius: 50%; 149 | cursor: pointer; 150 | box-shadow: 1px 1px 1px rgba(0,0,0,.25); 151 | outline: none; 152 | display: flex; 153 | justify-content: center; 154 | align-items: center; 155 | } 156 | #scroll-to-top span.icon::before { 157 | content: ""; 158 | display: block; 159 | background: url(imgs/top.png); 160 | width: 16px; 161 | height: 16px; 162 | } 163 | a{ 164 | color:#808080; 165 | } 166 | a:hover{ 167 | color:#f0f0f0; 168 | border:unset; 169 | } 170 | .tab-content{ 171 | height:250px; 172 | overflow: scroll; 173 | width:99% 174 | } 175 | .nav-tabs{ 176 | margin-top:20px; 177 | border-bottom: unset; 178 | } 179 | a:focus, textarea:focus { 180 | outline: unset; 181 | outline-offset: unset; 182 | } 183 | .nav-tabs .nav-item.show .nav-link, .nav-tabs .nav-link.active { 184 | color: #fff; 185 | border-bottom: 1px solid white; 186 | border-top:0px; 187 | border-right:0px; 188 | border-left:0px; 189 | background-color: unset; 190 | } 191 | .nav-link { 192 | margin-right: 2rem; 193 | padding: unset; 194 | } 195 | .nav-tabs .nav-link:focus, .nav-tabs .nav-link:hover { 196 | border-bottom: 1px solid white; 197 | border-top: 1px solid rgba(255, 255, 255, 0); 198 | border-right: 1px solid rgba(255, 255, 255, 0); 199 | border-left: 1px solid rgba(255, 255, 255, 0); 200 | } 201 | .vscode-light .nav-tabs .nav-item.show .nav-link,.vscode-light .nav-tabs .nav-link.active { 202 | color: #333; 203 | border-bottom: 1px solid #808080; 204 | border-top:1px solid rgba(255, 255, 255, 0); 205 | border-right:1px solid rgba(255, 255, 255, 0); 206 | border-left:1px solid rgba(255, 255, 255, 0); 207 | background-color: unset; 208 | } 209 | 210 | .vscode-light .nav-tabs .nav-link:focus, .vscode-light .nav-tabs .nav-link:hover { 211 | color: #333; 212 | border-bottom: 1px solid #808080; 213 | border-top:1px solid rgba(255, 255, 255, 0); 214 | border-right:1px solid rgba(255, 255, 255, 0); 215 | border-left:1px solid rgba(255, 255, 255, 0); 216 | } 217 | 218 | .extension-item:hover{ 219 | background-color: #424040; 220 | } 221 | 222 | .vscode-light .extension-item:hover{ 223 | background-color: #dddddd; 224 | } 225 | .extension-item{ 226 | margin-left:10px; 227 | margin-bottom: 10px; 228 | } 229 | 230 | .sidebar-sticky{ 231 | position: sticky; 232 | top: 0; 233 | height: calc(100vh - 135px); 234 | padding-top: .5rem; 235 | overflow-x: hidden; 236 | overflow-y: auto; 237 | list-style: none; 238 | -ms-flex-wrap: wrap; 239 | flex-wrap: wrap; 240 | padding-left: 0; 241 | margin-bottom: 0; 242 | } 243 | 244 | .changelog-sticky{ 245 | position: sticky; 246 | top: 0; 247 | height: calc(100vh - 244px); 248 | padding-top: .5rem; 249 | overflow-x: hidden; 250 | overflow-y: auto; 251 | -ms-flex-wrap: wrap; 252 | flex-wrap: wrap; 253 | padding-left: 0; 254 | margin-bottom: 0; 255 | } 256 | .setting-container{ 257 | position: sticky; 258 | top: 0; 259 | overflow-x: hidden; 260 | overflow-y: auto; 261 | -ms-flex-wrap: wrap; 262 | flex-wrap: wrap; 263 | padding-left: 0; 264 | margin-bottom: 0; 265 | } 266 | 267 | .vscode-dark pre{ 268 | color:white; 269 | } 270 | .example-div{ 271 | padding: 10px 10px 0px 10px; 272 | border: 1px solid #b4b1b1; 273 | height: calc(100vh - 244px); 274 | } 275 | 276 | .vscode-light .example-div{ 277 | padding: 10px; 278 | border: 1px solid #808080; 279 | } 280 | textarea{ 281 | margin-left: 10px; 282 | width:100%; 283 | height:calc(100vh - 244px); 284 | overflow:scroll; 285 | resize: none; 286 | } 287 | .button-div{ 288 | margin-top:20px; 289 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vscode-page 2 | 3 | [![Code Style: Google](https://img.shields.io/badge/code%20style-google-blueviolet.svg)](https://github.com/google/gts) 4 | 5 | [![NPM](https://nodei.co/npm/vscode-page.png?compact=true)](https://nodei.co/npm/vscode-page/) 6 | 7 | vscode-page is a light-weight page micro framework for vscode webview, it could accelerate Vs Code Extension Webview development. 8 | 9 | ## Features 10 | 11 | - abstract the communication between html page and WebviewPanel, developers can focus on business logic. 12 | - built-in template engine, with [handlebars.js](https://www.npmjs.com/package/handlebars). 13 | - message mapping, a simple way to organize page logic and view. 14 | - baseUrl support, relative paths can be used in html page. 15 | 16 | ## Installing 17 | 18 | ```shell 19 | npm install vscode-page 20 | ``` 21 | 22 | ## Usage 23 | 24 | vscode-page simplifies Webview development with following steps: 25 | 26 | 1. define messages between html page and vscode.WebviewPanel. 27 | 1. develop html page and js functions inside that page. 28 | 1. define MessageMappings. 29 | 1. register a command to create (or show) WebviewPanel with the MessageMappings defined in step 3. 30 | 31 | The whole architecture is shown below: 32 | 33 | ![vscode-page architecture](images/architecture.png) 34 | 35 | Also, there is [a demo project](example) to show its usage. Before check it, please read the following first. 36 | 37 | ### Messaging 38 | 39 | As described in vscode extension guide, html page and WebviewPanel can post messages each other. To standardize this communication, vscode-page defines two message formats. 40 | 41 | #### js -> WebviewPanel 42 | 43 | The message json format : 44 | 45 | - command, an indexed value for a command handler defined in a MessageMapping. 46 | - parameters (optional), an json argument passed to that command handler. 47 | 48 | Here is an example: 49 | 50 | ```json 51 | { 52 | "command": "showExtension", 53 | "parameters": { 54 | "repo": repo, 55 | "extId": extId, 56 | "installed": installed 57 | } 58 | } 59 | ``` 60 | 61 | #### WebviewPanel -> js 62 | 63 | The message json format : 64 | 65 | - command, if ending with "Response", it is a response of the prefix. Such as "showExtensionResponse" is response of "showExtension". 66 | - contents (optional), a content array. Each item has following keys: 67 | - id, element id in a html page. 68 | - body, innerHtml (generated by the template defined in a MessageMapping) of the element pointed by id. 69 | - result (optional), return value of the "\${command}" handler. 70 | 71 | Here is an example: 72 | 73 | ```json 74 | { 75 | "command": "showExtensionResponse", 76 | "contents": [ 77 | { "id": "title", "body": "Repo / Extension" }, 78 | { 79 | "id": "content", 80 | "body": "...." 81 | } 82 | ] 83 | } 84 | ``` 85 | 86 | ### HTML Page 87 | 88 | In order to initialize correctly, for each html page, please insert the following two lines in \: 89 | 90 | ``` 91 | 92 | 95 | ``` 96 | 97 | Here is the explaination: 98 | 99 | - {{base}} will be replaced by "path.join(context.extensionPath, root)", then relative paths can be used in that page. 100 | - {{init}} will be replaced by initEventListener function definition, which defines an EventListener receiving messages from WebviewPanel. 101 | 102 | Then it can be invoked to add an event listener to html page as below: 103 | 104 | ```javascript 105 | initEventListener(); 106 | ``` 107 | 108 | The default implementation will only process messages ending with "Response" and use contents as innerHtml of selected elements. 109 | 110 | For other messages, a customized function can be passed to initEventListener as below: 111 | 112 | ```javascript 113 | initEventListener(message => {...}); 114 | ``` 115 | 116 | The message has following key: 117 | 118 | - result, return value of a command handler. 119 | 120 | ### MessageMappings 121 | 122 | A MessageMapping defines: 123 | 124 | - command, the value of "command" field in message posted by js function. 125 | - handler, a function for the command above, its signature is below and the parameters is the value of "parameters" in the same message from js function. 126 | 127 | ```typescript 128 | (parameters?: any) => Promise; 129 | ``` 130 | 131 | - templates (optional), a template array for views of response of the command. Each item has the following keys: 132 | - id, element id in html page. 133 | - content, a inline handlebars template, it is optional. 134 | - contentUrl, a url to an external handlebars template, it is optional. 135 | - forward (optional), similar to request-forward pattern in web development, a MessageMapping the request flow will go. 136 | 137 | NOTE: 138 | 139 | - either "content" or "contentUrl" MUST be shown in a MessageMapping, not both. 140 | - both of "templates" and "forward" are optional, but if being used, only one of them can be shown in a MessageMapping. 141 | 142 | Here is a MessageMappings example: [home.ts](example/src/home.ts) 143 | 144 | ### createOrShowPage 145 | 146 | To create or show a WebviewPanel, invoke function createOrShowPage like beblow (from [extension.ts](example/src/extension.ts) in example): 147 | 148 | ```typescript 149 | createOrShowPage( 150 | 'name', 151 | 'ext.home', 152 | 'Sample Page', 153 | 'pages', 154 | 'home.html', 155 | context, 156 | messageMappings 157 | ); 158 | ``` 159 | 160 | The signature of createOrShowPage: 161 | 162 | ```typescript 163 | export function createOrShowPage( 164 | name: string, 165 | viewType: string, 166 | title: string, 167 | base: string, 168 | page: string, 169 | context: vscode.ExtensionContext, 170 | messageMappings: MesssageMaping[] 171 | ); 172 | ``` 173 | 174 | Each argument: 175 | 176 | - name, a named index of the WebviewPanel created. 177 | - viewType and title, both of them will be passed to vscode.window.createWebviewPanel. 178 | - base, a relative path to \ in html page. 179 | - page, a path to html file. 180 | - context, vscode.ExtensionContext. 181 | - messageMappings, MesssageMaping array defined, check examples in [home.ts](example/src/home.ts). 182 | 183 | ## Requirements 184 | 185 | vscode-page is a tool for [vscode](https://code.visualstudio.com/) extension development and uses [handlebars.js](https://www.npmjs.com/package/handlebars) as its template engine. 186 | 187 | So, please install **vscode** and **handlebars** first. 188 | 189 | ## Development 190 | 191 | For local debugging, please run the following command under the directory of vscode-page project: 192 | 193 | ```shell 194 | npm link 195 | ``` 196 | 197 | Then, in the project using vscode-page, please run the following command: 198 | 199 | ```shell 200 | npm link vscode-page 201 | ``` 202 | 203 | NOTE: 204 | 205 | The linked package in application will use its own node_modules, so if you defined your own handlebars helper in application, vscode-page can not find it. 206 | 207 | ```shell 208 | app 209 | |- node_modules 210 | |- vscode-page <-- project linked by "npm link" 211 | | ├─ node_modules 212 | | | |- handlebars.js <-- used by vscode-page 213 | | 214 | |- handlebars.js <-- you defined helper in it 215 | ``` 216 | 217 | I can not find an easy way to fix it, only find the following steps. If you have any good idea, please let me know. 218 | 219 | - "npm pack" in vscode-page project. 220 | - "npm install local-package" in your application. 221 | 222 | ## Resources 223 | 224 | - [使用 vscode-page 简化 vscode 插件的 Webview 开发](https://blog.dteam.top/posts/2020-03/simplify-vscode-webview-development-with-vscode-page.html) 225 | - [Simplifying VS Code Webview Development with vscode-page](https://dev.to/foxgem/simplifying-vs-code-webview-development-with-vscode-page-13c3) 226 | 227 | ## Known Issues 228 | 229 | Please visit [issues](https://github.com/DTeam-Top/vscode-page/issues) page to submit new issues or check known issues. 230 | 231 | ## Release Notes 232 | 233 | ### 0.0.1 234 | 235 | First release. 236 | 237 | ## License 238 | 239 | vscode-page is released under the Apache License 2.0 license. 240 | -------------------------------------------------------------------------------- /example/src/home.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from "vscode"; 2 | import { MesssageMaping } from "vscode-page"; 3 | import * as handlebars from "handlebars"; 4 | 5 | handlebars.registerHelper("formatDate", function(dateTime) { 6 | return new Date(dateTime).toLocaleDateString(); 7 | }); 8 | 9 | function loadFromHome() { 10 | return { 11 | repositories: [ 12 | { 13 | name: "repo1", 14 | options: { 15 | accessKeyId: "...", 16 | accessKeySecret: "...", 17 | bucket: "...", 18 | region: "..." 19 | }, 20 | type: "oss" 21 | }, 22 | { 23 | name: "repo2", 24 | options: { accessToken: "...", root: "..." }, 25 | type: "dropbox" 26 | } 27 | ], 28 | extensionInstalled: [ 29 | { 30 | extId: "dteam.my-ext", 31 | version: "0.0.1", 32 | describe: "my-ext", 33 | enabled: true, 34 | repository: "repo1" 35 | } 36 | ] 37 | }; 38 | } 39 | 40 | function listExtensions(repo: string) { 41 | return [ 42 | { 43 | extId: "dteam.my-ext", 44 | currentVersion: "0.0.1", 45 | icon: "", 46 | describe: "my-ext", 47 | dateCreated: "2020-02-28", 48 | lastUpdate: "2020-02-29" 49 | }, 50 | { 51 | extId: "dteam.another-ext", 52 | currentVersion: "0.0.2", 53 | icon: 54 | "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPoAAAD6CAMAAAC/MqoPAAAAz1BMVEUAAADUBy/DDi7dAzDdAzDdAzDdAzDDDi7DDi7DDi7dAzDdAzDdAzDDDi7DDi7DDi7dAzDdAzDdAzDDDi7DDi7DDi7dAzDdAzDDDi7DDi7dAzDdAzDDDi7DDi7dAzDDDi7fEz3HHTvugZjhh5f97/L78PLqYn7////aaHz74OX44eXmQmTSSmL3wMvww8vhI0rLLEjyobHppbHdAzDDDi7jMlfOO1XoUnHWWW/50Nj00tjscYvdd4nwkaTllqT0sL7stL7hRGPXBjDWBi/FDS4+JsiBAAAARXRSTlMAMDAwj9///9+PIHDPz3AgEGC/v2AQUK+vUJ/v75+AgP////////////////////////9AQP//////////////////r6+TKVt1AAAH7ElEQVR4AezUtaHDUBTA0I9mZtx/zHDMWOY+nQ3U6AsAAAAAAAAAAAAA8Em+f9Ts/v3713TDVK7esh3tRr9xPV+d7iCMtCf9KU5SJcKzXOvonaIU313VmjZK7zRtKXtsY/qI1OlZ9rN7Jb2rlza9IHS0JfoSV9D0wlxboa8oElljO5HeTU/C2E6kC5heN7Yz6QKm143tTLqA6QXrYzub/pxeKmFsV2buQllxZQ3DcJZ1jwuMS7AYGmx84Jy97/+exjNGWLv+zvst+O7gKfnrha6Kna4/ethhq9wUvdIf99G7EV8407xp1zpHevTuff8JrqN//3H/8PgPG0/njx5/2Hg6f/T4w8bTj/bo3ahKNWjdXpC76ty7B/9vMXz9Qbic+0cTOGz2JanRChw94LC55svyvPDNd5VH7+zrQQc2zPORJ/bi5ekhD5t94/zLJoAcOHrEYTNs+pU+M/CAowccNmBl/m1zD646evxhQ7f4Tl96cvzRW1WHjVs3/7HfswY6emv+v0Vy/Yo+oOnUP5rVT1F8SUVPeTnz8/bMaZZV8ipr+J1GDSeiD3/RRyJ61HTW+2bImWoTifxFY3pLQp/+Tp9J6G2eDuZMtflx0mMFffEnfamgd0g6nzNk1vD0R8qcUWZN86BdKXNGmTXr5jknzBlp1gC/4YQ5I82aqPkuZDkjzZprAL0lyxlp1rQB+mNY/iqv3WuY/gSgx6qc0WZNB6DflDWstGbvAPSVKGfEWbM+Ono32UdPezAdmCZn1FkTERPlDJ81PP0WKH+TX7K3oPw2Qm8pckadNW2Efi7IGXnWXEfosSBn5FnTQej3+ZzRZ80DhL7ic0afNWuEfsbnjD5rTiNkfM7osyZi9pzOGX3WvIDoLTpn9FnTJul8zvBZw9NjOmf0WdNh6XzOLJZs1vD0R6qcGU9UWfMUoq9EOfPO+feirFlD9HuinMmcL4CsYZ9e+Kb5sGtMus730nxnH4mioXYhyZmNc95vJVlzDaO3JA1bfqXPJTXbxuiPFTkzdV/pfqbImicYPVa8ML75Tn+reHvsYPSbgpwZuu90PxJkzR2MvhLkTL+iDwRZsz4a+qZG163ovXx3W4AOjc+ZhavofslnTcQNz5l8/Is+ybms4em36Jx5537R/Xs6a26D9BadM9nv9ILOmjZIfwbnTNL9nd5L4ax5CdJjOGcW7ne6X8JZ0wHp9+HHpvJP+hx+hHoA0ldszkzdn3Q/Y7NmDdLP2JzJ/qYXbNacRuDQnBnufrVghGZNRA7Nmf4ufUBlDU9vkY9N5S59Tj5CtVk6mDMLt0v3SyhreHoMPjaN6+gT8BGqw9K5nBm6OrofAVmD0YEHmP/VeLJ6epHv7v/804t9Kyxnkm49vZdiWbNG6Tewhl24erpfYjV7N0JH5Uxe7qPPcyprInYXzAtjle+79PqQH/BPL+a1oJzJ9tMLKGvaMP0xkzNDt5/uR0zWPIHpsZ3+ri7f6+n7Q/69nd6h6UjO5OVl9HkOZA1PXyE5s3CX0f0SyZo1TSdyJh9fTp/kQNbg9IjImaG7nO5HRNZE9Iicyf6LXgBZw9NvWXMG2wB9etE3zZCjj/RFQz7AZDm4wvj0Qi825gw4W9Z0cPp9W86gm9ieXuitbDmDzpQ1a5x+ZsoZeHP+6cUye85ws2RNdEh6N8fXOyi9pc8ZImvaB6UnPD09KD3W5wyRNR09nW9YpmYV9Ed8zlg24Z9e8KaZaugzumgMu6HPGSJr7kaC6XOGyJpIsQs+Z/isuSaht4Jzpj+u3z+TPRsEZ01bQn8cmjOJ27N/9wrS0Kx5IqHHoTmzsdO3oVnT0dMtOVPa6XN71ijpq8CcmTo73c8Cs2atpxtyJguhF/asEdKjsJxJXAjdp2FZE2kWljObMPrWnjVC+q2gnCnD6HN71tBPL4am6RuOXEU3HroBXzTIA0xiOHIV3XjoUvLpxbA4IGcSF0r3aUDWdET0+wE5swmnbwOy5oGIvgr42FAZTp8HfK5oLaKf2XNm6sLpfmbPmtNINPvHhrIm9ML+uaJINXPOJK4J3afmrJHRW8aGzTfN6NvcWLNtHd362FQ2o8+tj1A6emz8duLUNaP7mfErjJ0D0DPDkTPQC+MjlI7+yJYziWtK96kta57K6Ctbzmya07e2rFnL6Ddsj01lc/rc9gh1N5LNlDNT15zuZ6asiXS7sDw2ZQS9sDxCXRPSW4acSRxB96kha9pC+mNDzmwY+taQNU+E9NjwKeiSoc8NH5fuXDW97NctcwzdF4O6za+avvrcnl3Y6A5DQRS+PzMzF5FUMO/139KSeJmONdLe08EIvsR29+e9Of3n1TkdyXt6kI1OvtPP00CbX12n3zZBNzw6Tr/MokTV0m36qo5SbTtO0/uHYAO8k79ulHfy143yTv66Ud6J183VO/G6uXonWDfeu1P56WdWN9478brhtZYlp6+a4VTVKTW9X4dbi1OJ6ed1/DwD78Tr5uqdeN1cvROvm6t34nVz9U68bq7eidfN1Tvxurl6J0A3h6rxb0yfELrxLTo/nd5ndDPwTj66AeOP359+YYfzDZffm74CWTfwTrxurt6J183VO/G6uXonXjdX78Tr5uqdeN1cvROvm6t3ctYNGN9+ffoAGG7XcPdy+t5aN+BxWvxjsat3InTz79E7PekWQPbeyV83qOG//7PI/mhZlmVZlmVZlmVZlmXZPZmSvHpA7pEOAAAAAElFTkSuQmCC", 55 | describe: "another-ext", 56 | dateCreated: "2020-02-28", 57 | lastUpdate: "2020-02-29" 58 | } 59 | ]; 60 | } 61 | 62 | function showExtension(extId: string, repo: string) { 63 | const list = listExtensions(repo); 64 | const extIndex = list.map(i => i.extId).indexOf(extId); 65 | if( extId === 'dteam.my-ext') { 66 | return { 67 | metadata: list[extIndex], 68 | readme: 69 | "# my-ext README\n\nThis is My ext. And its version is 0.0.1\n", 70 | changelog: 71 | '# My-Ext Change Log\n\n## 0.0.1\n\nAll notable changes to the "my-ext" extension will be documented in this file.\n\nCheck [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.\n\n## [Unreleased]\n\n- Initial release' 72 | } 73 | } else if( extId === 'dteam.another-ext') { 74 | return { 75 | metadata: list[extIndex], 76 | readme: 77 | "# another-ext README\n\nThis is another ext. And its version is 0.0.2\n", 78 | changelog: 79 | '# Another-Ext Change Log\n\n## 0.0.2\n\nHere we are.\n\n## 0.0.1\n\nAll notable changes to the "another-ext" extension will be documented in this file.\n\nCheck [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.\n\n## [Unreleased]\n\n- Initial release' 80 | }; 81 | } 82 | return {}; 83 | } 84 | 85 | export const messageMappings: MesssageMaping[] = [ 86 | { 87 | command: "ready", 88 | handler: async () => { 89 | let result = loadFromHome(); 90 | return { 91 | repositories: result.repositories, 92 | extensionInstalled: result.extensionInstalled, 93 | title: "Installed Extensions" 94 | }; 95 | }, 96 | templates: [ 97 | { 98 | id: "repos", 99 | content: ` 100 | {{#each repositories}} 101 |
  • 102 | 103 | {{name}} 104 | 105 |
  • 106 | {{/each}} 107 | ` 108 | }, 109 | { id: "title", content: "{{title}}" }, 110 | { 111 | id: "content", 112 | contentUrl: "pages/list_intalled.hb" 113 | } 114 | ] 115 | }, 116 | { 117 | command: "listExtensions", 118 | handler: async parameters => { 119 | let result = await listExtensions(parameters.repo); 120 | let installedExtIds = (await loadFromHome()).extensionInstalled.map( 121 | extension => extension.extId 122 | ); 123 | let finalResult = new Array(); 124 | result.forEach(extensionMetadata => { 125 | finalResult.push({ 126 | extension: extensionMetadata, 127 | installed: installedExtIds.some(id => id === extensionMetadata.extId) 128 | }); 129 | }); 130 | 131 | return { 132 | title: parameters.repo, 133 | extensions: finalResult 134 | }; 135 | }, 136 | templates: [ 137 | { id: "title", content: "{{title}}" }, 138 | { 139 | id: "content", 140 | contentUrl: "pages/list_extension.hb" 141 | } 142 | ] 143 | }, 144 | { 145 | command: "showExtension", 146 | handler: async parameters => { 147 | let result = await showExtension(parameters.extId, parameters.repo); 148 | let readMe = (await vscode.commands.executeCommand( 149 | "markdown.api.render", 150 | result.readme 151 | )) as string; 152 | let changelog = (await vscode.commands.executeCommand( 153 | "markdown.api.render", 154 | result.changelog 155 | )) as string; 156 | return { 157 | title: `${parameters.repo} / ${parameters.extId}`, 158 | repo: parameters.repo, 159 | details: result, 160 | readMe: readMe, 161 | changelog: changelog, 162 | installed: parameters.installed 163 | }; 164 | }, 165 | templates: [ 166 | { id: "title", content: "{{title}}" }, 167 | { 168 | id: "content", 169 | contentUrl: "pages/detail_extension.hb" 170 | } 171 | ] 172 | }, 173 | { 174 | command: "installExtension", 175 | handler: async parameters => {} 176 | }, 177 | { 178 | command: "loadRepositories", 179 | handler: async () => { 180 | let result = await loadFromHome(); 181 | let example = [ 182 | { 183 | name: "repo1", 184 | type: "oss", 185 | options: { 186 | accessKeyId: "...", 187 | accessKeySecret: "...", 188 | bucket: "...", 189 | region: "..." 190 | } 191 | }, 192 | { 193 | name: "repo2", 194 | type: "dropbox", 195 | options: { 196 | password: "...", 197 | user: "..." 198 | } 199 | } 200 | ]; 201 | return { 202 | repositories: JSON.stringify(result.repositories, undefined, 4), 203 | title: "Repositories Setting", 204 | example: JSON.stringify(example, undefined, 2) 205 | }; 206 | }, 207 | templates: [ 208 | { id: "title", content: "{{title}}" }, 209 | { 210 | id: "content", 211 | contentUrl: "pages/setting.hb" 212 | } 213 | ] 214 | }, 215 | { 216 | command: "submitRepositories", 217 | handler: async parameters => { 218 | vscode.window.showInformationMessage("Repositories setting is updated."); 219 | }, 220 | forward: "ready" 221 | }, 222 | { 223 | command: "openExtension", 224 | handler: async parameters => { 225 | vscode.commands.executeCommand("extension.open", parameters.extId); 226 | } 227 | } 228 | ]; 229 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /example/pages/shared/popper.js/popper.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) Federico Zivolo 2019 3 | Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT). 4 | */(function(e,t){'object'==typeof exports&&'undefined'!=typeof module?module.exports=t():'function'==typeof define&&define.amd?define(t):e.Popper=t()})(this,function(){'use strict';function e(e){return e&&'[object Function]'==={}.toString.call(e)}function t(e,t){if(1!==e.nodeType)return[];var o=e.ownerDocument.defaultView,n=o.getComputedStyle(e,null);return t?n[t]:n}function o(e){return'HTML'===e.nodeName?e:e.parentNode||e.host}function n(e){if(!e)return document.body;switch(e.nodeName){case'HTML':case'BODY':return e.ownerDocument.body;case'#document':return e.body;}var i=t(e),r=i.overflow,p=i.overflowX,s=i.overflowY;return /(auto|scroll|overlay)/.test(r+s+p)?e:n(o(e))}function i(e){return e&&e.referenceNode?e.referenceNode:e}function r(e){return 11===e?re:10===e?pe:re||pe}function p(e){if(!e)return document.documentElement;for(var o=r(10)?document.body:null,n=e.offsetParent||null;n===o&&e.nextElementSibling;)n=(e=e.nextElementSibling).offsetParent;var i=n&&n.nodeName;return i&&'BODY'!==i&&'HTML'!==i?-1!==['TH','TD','TABLE'].indexOf(n.nodeName)&&'static'===t(n,'position')?p(n):n:e?e.ownerDocument.documentElement:document.documentElement}function s(e){var t=e.nodeName;return'BODY'!==t&&('HTML'===t||p(e.firstElementChild)===e)}function d(e){return null===e.parentNode?e:d(e.parentNode)}function a(e,t){if(!e||!e.nodeType||!t||!t.nodeType)return document.documentElement;var o=e.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_FOLLOWING,n=o?e:t,i=o?t:e,r=document.createRange();r.setStart(n,0),r.setEnd(i,0);var l=r.commonAncestorContainer;if(e!==l&&t!==l||n.contains(i))return s(l)?l:p(l);var f=d(e);return f.host?a(f.host,t):a(e,d(t).host)}function l(e){var t=1=o.clientWidth&&n>=o.clientHeight}),l=0a[e]&&!t.escapeWithReference&&(n=Q(f[o],a[e]-('right'===e?f.width:f.height))),ae({},o,n)}};return l.forEach(function(e){var t=-1===['left','top'].indexOf(e)?'secondary':'primary';f=le({},f,m[t](e))}),e.offsets.popper=f,e},priority:['left','right','top','bottom'],padding:5,boundariesElement:'scrollParent'},keepTogether:{order:400,enabled:!0,fn:function(e){var t=e.offsets,o=t.popper,n=t.reference,i=e.placement.split('-')[0],r=Z,p=-1!==['top','bottom'].indexOf(i),s=p?'right':'bottom',d=p?'left':'top',a=p?'width':'height';return o[s]r(n[s])&&(e.offsets.popper[d]=r(n[s])),e}},arrow:{order:500,enabled:!0,fn:function(e,o){var n;if(!K(e.instance.modifiers,'arrow','keepTogether'))return e;var i=o.element;if('string'==typeof i){if(i=e.instance.popper.querySelector(i),!i)return e;}else if(!e.instance.popper.contains(i))return console.warn('WARNING: `arrow.element` must be child of its popper element!'),e;var r=e.placement.split('-')[0],p=e.offsets,s=p.popper,d=p.reference,a=-1!==['left','right'].indexOf(r),l=a?'height':'width',f=a?'Top':'Left',m=f.toLowerCase(),h=a?'left':'top',c=a?'bottom':'right',u=S(i)[l];d[c]-us[c]&&(e.offsets.popper[m]+=d[m]+u-s[c]),e.offsets.popper=g(e.offsets.popper);var b=d[m]+d[l]/2-u/2,w=t(e.instance.popper),y=parseFloat(w['margin'+f],10),E=parseFloat(w['border'+f+'Width'],10),v=b-e.offsets.popper[m]-y-E;return v=ee(Q(s[l]-u,v),0),e.arrowElement=i,e.offsets.arrow=(n={},ae(n,m,$(v)),ae(n,h,''),n),e},element:'[x-arrow]'},flip:{order:600,enabled:!0,fn:function(e,t){if(W(e.instance.modifiers,'inner'))return e;if(e.flipped&&e.placement===e.originalPlacement)return e;var o=v(e.instance.popper,e.instance.reference,t.padding,t.boundariesElement,e.positionFixed),n=e.placement.split('-')[0],i=T(n),r=e.placement.split('-')[1]||'',p=[];switch(t.behavior){case ce.FLIP:p=[n,i];break;case ce.CLOCKWISE:p=G(n);break;case ce.COUNTERCLOCKWISE:p=G(n,!0);break;default:p=t.behavior;}return p.forEach(function(s,d){if(n!==s||p.length===d+1)return e;n=e.placement.split('-')[0],i=T(n);var a=e.offsets.popper,l=e.offsets.reference,f=Z,m='left'===n&&f(a.right)>f(l.left)||'right'===n&&f(a.left)f(l.top)||'bottom'===n&&f(a.top)f(o.right),g=f(a.top)f(o.bottom),b='left'===n&&h||'right'===n&&c||'top'===n&&g||'bottom'===n&&u,w=-1!==['top','bottom'].indexOf(n),y=!!t.flipVariations&&(w&&'start'===r&&h||w&&'end'===r&&c||!w&&'start'===r&&g||!w&&'end'===r&&u),E=!!t.flipVariationsByContent&&(w&&'start'===r&&c||w&&'end'===r&&h||!w&&'start'===r&&u||!w&&'end'===r&&g),v=y||E;(m||b||v)&&(e.flipped=!0,(m||b)&&(n=p[d+1]),v&&(r=z(r)),e.placement=n+(r?'-'+r:''),e.offsets.popper=le({},e.offsets.popper,C(e.instance.popper,e.offsets.reference,e.placement)),e=P(e.instance.modifiers,e,'flip'))}),e},behavior:'flip',padding:5,boundariesElement:'viewport',flipVariations:!1,flipVariationsByContent:!1},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,o=t.split('-')[0],n=e.offsets,i=n.popper,r=n.reference,p=-1!==['left','right'].indexOf(o),s=-1===['top','left'].indexOf(o);return i[p?'left':'top']=r[o]-(s?i[p?'width':'height']:0),e.placement=T(t),e.offsets.popper=g(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!K(e.instance.modifiers,'hide','preventOverflow'))return e;var t=e.offsets.reference,o=D(e.instance.modifiers,function(e){return'preventOverflow'===e.name}).boundaries;if(t.bottomo.right||t.top>o.bottom||t.rightwindow.devicePixelRatio||!fe),c='bottom'===o?'top':'bottom',g='right'===n?'left':'right',b=B('transform');if(d='bottom'==c?'HTML'===l.nodeName?-l.clientHeight+h.bottom:-f.height+h.bottom:h.top,s='right'==g?'HTML'===l.nodeName?-l.clientWidth+h.right:-f.width+h.right:h.left,a&&b)m[b]='translate3d('+s+'px, '+d+'px, 0)',m[c]=0,m[g]=0,m.willChange='transform';else{var w='bottom'==c?-1:1,y='right'==g?-1:1;m[c]=d*w,m[g]=s*y,m.willChange=c+', '+g}var E={"x-placement":e.placement};return e.attributes=le({},E,e.attributes),e.styles=le({},m,e.styles),e.arrowStyles=le({},e.offsets.arrow,e.arrowStyles),e},gpuAcceleration:!0,x:'bottom',y:'right'},applyStyle:{order:900,enabled:!0,fn:function(e){return V(e.instance.popper,e.styles),j(e.instance.popper,e.attributes),e.arrowElement&&Object.keys(e.arrowStyles).length&&V(e.arrowElement,e.arrowStyles),e},onLoad:function(e,t,o,n,i){var r=L(i,t,e,o.positionFixed),p=O(o.placement,r,t,e,o.modifiers.flip.boundariesElement,o.modifiers.flip.padding);return t.setAttribute('x-placement',p),V(t,{position:o.positionFixed?'fixed':'absolute'}),o},gpuAcceleration:void 0}}},ge}); 5 | //# sourceMappingURL=popper.min.js.map -------------------------------------------------------------------------------- /example/pages/shared/bootstrap/js/bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v4.4.1 (https://getbootstrap.com/) 3 | * Copyright 2011-2019 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */ 6 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery"),require("popper.js")):"function"==typeof define&&define.amd?define(["exports","jquery","popper.js"],e):e((t=t||self).bootstrap={},t.jQuery,t.Popper)}(this,function(t,g,u){"use strict";function i(t,e){for(var n=0;nthis._items.length-1||t<0))if(this._isSliding)g(this._element).one(Y.SLID,function(){return e.to(t)});else{if(n===t)return this.pause(),void this.cycle();var i=ndocument.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},t._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},t._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=t.left+t.right
    ',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:Se,popperConfig:null},Fe="show",Ue="out",We={HIDE:"hide"+Oe,HIDDEN:"hidden"+Oe,SHOW:"show"+Oe,SHOWN:"shown"+Oe,INSERTED:"inserted"+Oe,CLICK:"click"+Oe,FOCUSIN:"focusin"+Oe,FOCUSOUT:"focusout"+Oe,MOUSEENTER:"mouseenter"+Oe,MOUSELEAVE:"mouseleave"+Oe},qe="fade",Me="show",Ke=".tooltip-inner",Qe=".arrow",Be="hover",Ve="focus",Ye="click",ze="manual",Xe=function(){function i(t,e){if("undefined"==typeof u)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var t=i.prototype;return t.enable=function(){this._isEnabled=!0},t.disable=function(){this._isEnabled=!1},t.toggleEnabled=function(){this._isEnabled=!this._isEnabled},t.toggle=function(t){if(this._isEnabled)if(t){var e=this.constructor.DATA_KEY,n=g(t.currentTarget).data(e);n||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),g(t.currentTarget).data(e,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(g(this.getTipElement()).hasClass(Me))return void this._leave(null,this);this._enter(null,this)}},t.dispose=function(){clearTimeout(this._timeout),g.removeData(this.element,this.constructor.DATA_KEY),g(this.element).off(this.constructor.EVENT_KEY),g(this.element).closest(".modal").off("hide.bs.modal",this._hideModalHandler),this.tip&&g(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},t.show=function(){var e=this;if("none"===g(this.element).css("display"))throw new Error("Please use show on visible elements");var t=g.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){g(this.element).trigger(t);var n=_.findShadowRoot(this.element),i=g.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(t.isDefaultPrevented()||!i)return;var o=this.getTipElement(),r=_.getUID(this.constructor.NAME);o.setAttribute("id",r),this.element.setAttribute("aria-describedby",r),this.setContent(),this.config.animation&&g(o).addClass(qe);var s="function"==typeof this.config.placement?this.config.placement.call(this,o,this.element):this.config.placement,a=this._getAttachment(s);this.addAttachmentClass(a);var l=this._getContainer();g(o).data(this.constructor.DATA_KEY,this),g.contains(this.element.ownerDocument.documentElement,this.tip)||g(o).appendTo(l),g(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new u(this.element,o,this._getPopperConfig(a)),g(o).addClass(Me),"ontouchstart"in document.documentElement&&g(document.body).children().on("mouseover",null,g.noop);var c=function(){e.config.animation&&e._fixTransition();var t=e._hoverState;e._hoverState=null,g(e.element).trigger(e.constructor.Event.SHOWN),t===Ue&&e._leave(null,e)};if(g(this.tip).hasClass(qe)){var h=_.getTransitionDurationFromElement(this.tip);g(this.tip).one(_.TRANSITION_END,c).emulateTransitionEnd(h)}else c()}},t.hide=function(t){function e(){n._hoverState!==Fe&&i.parentNode&&i.parentNode.removeChild(i),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),g(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),t&&t()}var n=this,i=this.getTipElement(),o=g.Event(this.constructor.Event.HIDE);if(g(this.element).trigger(o),!o.isDefaultPrevented()){if(g(i).removeClass(Me),"ontouchstart"in document.documentElement&&g(document.body).children().off("mouseover",null,g.noop),this._activeTrigger[Ye]=!1,this._activeTrigger[Ve]=!1,this._activeTrigger[Be]=!1,g(this.tip).hasClass(qe)){var r=_.getTransitionDurationFromElement(i);g(i).one(_.TRANSITION_END,e).emulateTransitionEnd(r)}else e();this._hoverState=""}},t.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},t.isWithContent=function(){return Boolean(this.getTitle())},t.addAttachmentClass=function(t){g(this.getTipElement()).addClass(Pe+"-"+t)},t.getTipElement=function(){return this.tip=this.tip||g(this.config.template)[0],this.tip},t.setContent=function(){var t=this.getTipElement();this.setElementContent(g(t.querySelectorAll(Ke)),this.getTitle()),g(t).removeClass(qe+" "+Me)},t.setElementContent=function(t,e){"object"!=typeof e||!e.nodeType&&!e.jquery?this.config.html?(this.config.sanitize&&(e=we(e,this.config.whiteList,this.config.sanitizeFn)),t.html(e)):t.text(e):this.config.html?g(e).parent().is(t)||t.empty().append(e):t.text(g(e).text())},t.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t=t||("function"==typeof this.config.title?this.config.title.call(this.element):this.config.title)},t._getPopperConfig=function(t){var e=this;return l({},{placement:t,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:Qe},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){return e._handlePopperPlacementChange(t)}},{},this.config.popperConfig)},t._getOffset=function(){var e=this,t={};return"function"==typeof this.config.offset?t.fn=function(t){return t.offsets=l({},t.offsets,{},e.config.offset(t.offsets,e.element)||{}),t}:t.offset=this.config.offset,t},t._getContainer=function(){return!1===this.config.container?document.body:_.isElement(this.config.container)?g(this.config.container):g(document).find(this.config.container)},t._getAttachment=function(t){return Re[t.toUpperCase()]},t._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(t){if("click"===t)g(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(t){return i.toggle(t)});else if(t!==ze){var e=t===Be?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=t===Be?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;g(i.element).on(e,i.config.selector,function(t){return i._enter(t)}).on(n,i.config.selector,function(t){return i._leave(t)})}}),this._hideModalHandler=function(){i.element&&i.hide()},g(this.element).closest(".modal").on("hide.bs.modal",this._hideModalHandler),this.config.selector?this.config=l({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},t._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");!this.element.getAttribute("title")&&"string"==t||(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},t._enter=function(t,e){var n=this.constructor.DATA_KEY;(e=e||g(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),g(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusin"===t.type?Ve:Be]=!0),g(e.getTipElement()).hasClass(Me)||e._hoverState===Fe?e._hoverState=Fe:(clearTimeout(e._timeout),e._hoverState=Fe,e.config.delay&&e.config.delay.show?e._timeout=setTimeout(function(){e._hoverState===Fe&&e.show()},e.config.delay.show):e.show())},t._leave=function(t,e){var n=this.constructor.DATA_KEY;(e=e||g(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),g(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusout"===t.type?Ve:Be]=!1),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState=Ue,e.config.delay&&e.config.delay.hide?e._timeout=setTimeout(function(){e._hoverState===Ue&&e.hide()},e.config.delay.hide):e.hide())},t._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},t._getConfig=function(t){var e=g(this.element).data();return Object.keys(e).forEach(function(t){-1!==je.indexOf(t)&&delete e[t]}),"number"==typeof(t=l({},this.constructor.Default,{},e,{},"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),_.typeCheckConfig(Ae,t,this.constructor.DefaultType),t.sanitize&&(t.template=we(t.template,t.whiteList,t.sanitizeFn)),t},t._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},t._cleanTipClass=function(){var t=g(this.getTipElement()),e=t.attr("class").match(Le);null!==e&&e.length&&t.removeClass(e.join(""))},t._handlePopperPlacementChange=function(t){var e=t.instance;this.tip=e.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},t._fixTransition=function(){var t=this.getTipElement(),e=this.config.animation;null===t.getAttribute("x-placement")&&(g(t).removeClass(qe),this.config.animation=!1,this.hide(),this.show(),this.config.animation=e)},i._jQueryInterface=function(n){return this.each(function(){var t=g(this).data(Ne),e="object"==typeof n&&n;if((t||!/dispose|hide/.test(n))&&(t||(t=new i(this,e),g(this).data(Ne,t)),"string"==typeof n)){if("undefined"==typeof t[n])throw new TypeError('No method named "'+n+'"');t[n]()}})},s(i,null,[{key:"VERSION",get:function(){return"4.4.1"}},{key:"Default",get:function(){return xe}},{key:"NAME",get:function(){return Ae}},{key:"DATA_KEY",get:function(){return Ne}},{key:"Event",get:function(){return We}},{key:"EVENT_KEY",get:function(){return Oe}},{key:"DefaultType",get:function(){return He}}]),i}();g.fn[Ae]=Xe._jQueryInterface,g.fn[Ae].Constructor=Xe,g.fn[Ae].noConflict=function(){return g.fn[Ae]=ke,Xe._jQueryInterface};var $e="popover",Ge="bs.popover",Je="."+Ge,Ze=g.fn[$e],tn="bs-popover",en=new RegExp("(^|\\s)"+tn+"\\S+","g"),nn=l({},Xe.Default,{placement:"right",trigger:"click",content:"",template:''}),on=l({},Xe.DefaultType,{content:"(string|element|function)"}),rn="fade",sn="show",an=".popover-header",ln=".popover-body",cn={HIDE:"hide"+Je,HIDDEN:"hidden"+Je,SHOW:"show"+Je,SHOWN:"shown"+Je,INSERTED:"inserted"+Je,CLICK:"click"+Je,FOCUSIN:"focusin"+Je,FOCUSOUT:"focusout"+Je,MOUSEENTER:"mouseenter"+Je,MOUSELEAVE:"mouseleave"+Je},hn=function(t){function i(){return t.apply(this,arguments)||this}!function(t,e){t.prototype=Object.create(e.prototype),(t.prototype.constructor=t).__proto__=e}(i,t);var e=i.prototype;return e.isWithContent=function(){return this.getTitle()||this._getContent()},e.addAttachmentClass=function(t){g(this.getTipElement()).addClass(tn+"-"+t)},e.getTipElement=function(){return this.tip=this.tip||g(this.config.template)[0],this.tip},e.setContent=function(){var t=g(this.getTipElement());this.setElementContent(t.find(an),this.getTitle());var e=this._getContent();"function"==typeof e&&(e=e.call(this.element)),this.setElementContent(t.find(ln),e),t.removeClass(rn+" "+sn)},e._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},e._cleanTipClass=function(){var t=g(this.getTipElement()),e=t.attr("class").match(en);null!==e&&0=this._offsets[o]&&("undefined"==typeof this._offsets[o+1]||t+~]|"+R+")"+R+"*"),U=new RegExp(R+"|>"),V=new RegExp(W),X=new RegExp("^"+B+"$"),Q={ID:new RegExp("^#("+B+")"),CLASS:new RegExp("^\\.("+B+")"),TAG:new RegExp("^("+B+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+W),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+R+"*(even|odd|(([+-]|)(\\d*)n|)"+R+"*(?:([+-]|)"+R+"*(\\d+)|))"+R+"*\\)|)","i"),bool:new RegExp("^(?:"+I+")$","i"),needsContext:new RegExp("^"+R+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+R+"*((?:-\\d)?\\d*)"+R+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,G=/^(?:input|select|textarea|button)$/i,K=/^h\d$/i,J=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\([\\da-f]{1,6}"+R+"?|("+R+")|.)","ig"),ne=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){C()},ae=xe(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{O.apply(t=P.call(m.childNodes),m.childNodes),t[m.childNodes.length].nodeType}catch(e){O={apply:t.length?function(e,t){q.apply(e,P.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,d=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==d&&9!==d&&11!==d)return n;if(!r&&((e?e.ownerDocument||e:m)!==T&&C(e),e=e||T,E)){if(11!==d&&(u=Z.exec(t)))if(i=u[1]){if(9===d){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return O.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&p.getElementsByClassName&&e.getElementsByClassName)return O.apply(n,e.getElementsByClassName(i)),n}if(p.qsa&&!S[t+" "]&&(!v||!v.test(t))&&(1!==d||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===d&&U.test(t)){(s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=N),o=(l=h(t)).length;while(o--)l[o]="#"+s+" "+be(l[o]);c=l.join(","),f=ee.test(t)&&ye(e.parentNode)||e}try{return O.apply(n,f.querySelectorAll(c)),n}catch(e){S(t,!0)}finally{s===N&&e.removeAttribute("id")}}}return g(t.replace(F,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>x.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[N]=!0,e}function ce(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)x.attrHandle[n[r]]=t}function de(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function pe(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in p=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},C=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:m;return r!==T&&9===r.nodeType&&r.documentElement&&(a=(T=r).documentElement,E=!i(T),m!==T&&(n=T.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),p.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),p.getElementsByTagName=ce(function(e){return e.appendChild(T.createComment("")),!e.getElementsByTagName("*").length}),p.getElementsByClassName=J.test(T.getElementsByClassName),p.getById=ce(function(e){return a.appendChild(e).id=N,!T.getElementsByName||!T.getElementsByName(N).length}),p.getById?(x.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},x.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(x.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},x.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),x.find.TAG=p.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):p.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},x.find.CLASS=p.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(p.qsa=J.test(T.querySelectorAll))&&(ce(function(e){a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+R+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+R+"*(?:value|"+I+")"),e.querySelectorAll("[id~="+N+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+N+"+*").length||v.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=T.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+R+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(p.matchesSelector=J.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){p.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",W)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=J.test(a.compareDocumentPosition),y=t||J.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!p.sortDetached&&t.compareDocumentPosition(e)===n?e===T||e.ownerDocument===m&&y(m,e)?-1:t===T||t.ownerDocument===m&&y(m,t)?1:u?H(u,e)-H(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===T?-1:t===T?1:i?-1:o?1:u?H(u,e)-H(u,t):0;if(i===o)return de(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?de(a[r],s[r]):a[r]===m?-1:s[r]===m?1:0}),T},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==T&&C(e),p.matchesSelector&&E&&!S[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||p.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){S(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&V.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=d[e+" "];return t||(t=new RegExp("(^|"+R+")"+e+"("+R+"|$)"))&&d(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function L(e,n,r){return x(n)?E.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?E.grep(e,function(e){return e===n!==r}):"string"!=typeof n?E.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(E.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||j,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof E?t[0]:t,E.merge(this,E.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:v,!0)),D.test(r[1])&&E.isPlainObject(t))for(r in t)x(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=v.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):x(e)?void 0!==n.ready?n.ready(e):e(E):E.makeArray(e,this)}).prototype=E.fn,j=E(v);var O=/^(?:parents|prev(?:Until|All))/,P={children:!0,contents:!0,next:!0,prev:!0};function H(e,t){while((e=e[t])&&1!==e.nodeType);return e}E.fn.extend({has:function(e){var t=E(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,pe=/^$|^module$|\/(?:java|ecma)script/i,he={option:[1,""],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ge(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&S(e,t)?E.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;nx",b.noCloneChecked=!!ye.cloneNode(!0).lastChild.defaultValue;var we=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Te=/^([^.]*)(?:\.(.+)|)/;function Ee(){return!0}function Ne(){return!1}function Ae(e,t){return e===function(){try{return v.activeElement}catch(e){}}()==("focus"===t)}function ke(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)ke(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Ne;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return E().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=E.guid++)),e.each(function(){E.event.add(this,t,i,r,n)})}function Se(e,i,o){o?(G.set(e,i,!1),E.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=G.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(E.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),G.set(this,i,r),t=o(this,i),this[i](),r!==(n=G.get(this,i))||t?G.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(G.set(this,i,{value:E.event.trigger(E.extend(r[0],E.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===G.get(e,i)&&E.event.add(e,i,Ee)}E.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,d,p,h,g,v=G.get(t);if(v){n.handler&&(n=(o=n).handler,i=o.selector),i&&E.find.matchesSelector(ie,i),n.guid||(n.guid=E.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof E&&E.event.triggered!==e.type?E.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(I)||[""]).length;while(l--)p=g=(s=Te.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),p&&(f=E.event.special[p]||{},p=(i?f.delegateType:f.bindType)||p,f=E.event.special[p]||{},c=E.extend({type:p,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&E.expr.match.needsContext.test(i),namespace:h.join(".")},o),(d=u[p])||((d=u[p]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(p,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?d.splice(d.delegateCount++,0,c):d.push(c),E.event.global[p]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,d,p,h,g,v=G.hasData(e)&&G.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(I)||[""]).length;while(l--)if(p=g=(s=Te.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),p){f=E.event.special[p]||{},d=u[p=(r?f.delegateType:f.bindType)||p]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=d.length;while(o--)c=d[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(d.splice(o,1),c.selector&&d.delegateCount--,f.remove&&f.remove.call(e,c));a&&!d.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||E.removeEvent(e,p,v.handle),delete u[p])}else for(p in u)E.event.remove(e,p+t[l],n,r,!0);E.isEmptyObject(u)&&G.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=E.event.fix(e),u=new Array(arguments.length),l=(G.get(this,"events")||{})[s.type]||[],c=E.event.special[s.type]||{};for(u[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,Le=/\s*$/g;function Oe(e,t){return S(e,"table")&&S(11!==t.nodeType?t:t.firstChild,"tr")&&E(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function He(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Ie(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(G.hasData(e)&&(o=G.access(e),a=G.set(t,o),l=o.events))for(i in delete a.handle,a.events={},l)for(n=0,r=l[i].length;n")},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=oe(e);if(!(b.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||E.isXMLDoc(e)))for(a=ge(c),r=0,i=(o=ge(e)).length;r
    ",2===pt.childNodes.length),E.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(b.createHTMLDocument?((r=(t=v.implementation.createHTMLDocument("")).createElement("base")).href=v.location.href,t.head.appendChild(r)):t=v),o=!n&&[],(i=D.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&E(o).remove(),E.merge([],i.childNodes)));var r,i,o},E.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=E.css(e,"position"),c=E(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=E.css(e,"top"),u=E.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),x(t)&&(t=t.call(e,n,E.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},E.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){E.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===E.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===E.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=E(e).offset()).top+=E.css(e,"borderTopWidth",!0),i.left+=E.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-E.css(r,"marginTop",!0),left:t.left-i.left-E.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===E.css(e,"position"))e=e.offsetParent;return e||ie})}}),E.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;E.fn[t]=function(e){return z(this,function(e,t,n){var r;if(w(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),E.each(["top","left"],function(e,n){E.cssHooks[n]=ze(b.pixelPosition,function(e,t){if(t)return t=Fe(e,n),Me.test(t)?E(e).position()[n]+"px":t})}),E.each({Height:"height",Width:"width"},function(a,s){E.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){E.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return z(this,function(e,t,n){var r;return w(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?E.css(e,t,i):E.style(e,t,n,i)},s,n?e:void 0,n)}})}),E.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){E.fn[n]=function(e,t){return 0