├── .DS_Store
├── .gitignore
├── LICENSE
├── README.md
├── app.py
├── bot.py
├── composer.json
├── demo
├── fibonacci.js
└── fibonacci.py
├── editor.html
├── favicon.ico
├── index.html
├── index.php
├── js
├── app.js
├── editor.html
├── handlers.js
├── index.js
├── mic.js
└── parser.js
├── judge.py
├── lib
├── bravey.min.js
└── pane1
│ ├── codemirror.css
│ ├── codemirror.js
│ ├── dialog.css
│ ├── dialog.js
│ ├── javascript.js
│ ├── matchbrackets.js
│ ├── python.js
│ ├── searchcursor.js
│ └── vim.js
├── pane1.html
├── static
└── img
│ ├── dot.png
│ ├── english.svg
│ ├── hindi.svg
│ ├── js.svg
│ ├── logo-alt.svg
│ ├── logo.svg
│ ├── mic.svg
│ ├── python.svg
│ ├── run.svg
│ ├── text-logo.svg
│ └── undo.svg
└── styles
├── editor.css
├── editor.scss
├── home.css
├── home.scss
├── lol.html
└── reset.css
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/teamsudocode/dexter/0ccceac9a97687c39c84eb92ee834021d66767c8/.DS_Store
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | styles/home.css.map
2 | styles/editor.css.map
3 | styles/.sass-cache
4 | intermediate.py
5 | intermediate.js
6 | intermediate.js
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Dexter
2 |
3 | Ever wondered if you could talk to your computer in your natural language, and it writes the code for you, and that too in your favorite language?
4 |
5 | #### Dexter is an AI-based code editor that allows you to code parallelly in Javascript and Python just by conversing with it. It supports two of the most widely used languages in the country, Hindi and, English.
6 |
7 | Won 1st Prize at Hack36, MNNIT Allahabad.
8 |
9 | [Watch the Demo Video](https://www.youtube.com/watch?v=qFzCyY3lHZE)
10 |
11 | [View the Presentation](https://drive.google.com/file/d/1ziJM2d6zE2I5KthzUSVCVK7HWTWhoQ4A/view?usp=sharing)
12 |
13 | ### How to run
14 |
15 | ```
16 | $ git clone https://github.com/teamsudocode/dexter.git
17 | $ cd dexter
18 | $ pip install --user flask flask-cors zulip
19 | $ python3 app.py
20 | ```
21 |
22 | Open another terminal window
23 |
24 | ```
25 | $ cd dexter
26 | $ python3 -m http.server
27 | ```
28 | Navigate to localhost:8000.
29 |
30 | **Additional requirement**:
31 | `nodejs` to run `javascript` code.
32 |
--------------------------------------------------------------------------------
/app.py:
--------------------------------------------------------------------------------
1 | from flask import Flask, request, jsonify
2 | from judge import runProcess
3 | from flask_cors import CORS
4 | import zulip
5 |
6 | # Keyword arguments 'email' and 'api_key' are not required if you are using ~/.zuliprc
7 | client = zulip.Client(email="mydexter-bot@hack36.zulipchat.com",
8 | api_key="gX6ulWhAzExkZcYSAtWgpsAMbrXLjcJn",
9 | site="https://hack36.zulipchat.com")
10 |
11 | app = Flask('dexter')
12 | CORS(app)
13 |
14 |
15 | @app.route('/compile', methods=['POST'])
16 | def compile():
17 | content = r'' + request.form['content']
18 | # with open('my.py', 'w') as f:
19 | # print(exec(content))
20 | with open('intermediate.py', 'w') as f:
21 | # print(repr(content).replace("'", ''))
22 | # new_content = content.replace("'", '')
23 | for i in content:
24 | f.write(i)
25 |
26 | # f.write(repr(content).replace("", ''))
27 |
28 | outBuf, errBuf = runProcess(['python3', 'intermediate.py'])
29 | return jsonify({'out': str(outBuf), 'err': str(errBuf)})
30 |
31 |
32 | @app.route('/js', methods=['POST'])
33 | def interpret():
34 | content = r'' + request.form['content']
35 | # with open('my.py', 'w') as f:
36 | # print(exec(content))
37 | with open('intermediate.js', 'w') as f:
38 | # print(repr(content).replace("'", ''))
39 | # new_content = content.replace("'", '')
40 | for i in content:
41 | f.write(i)
42 |
43 | # f.write(repr(content).replace("", ''))
44 |
45 | outBuf, errBuf = runProcess(['node', 'intermediate.js'])
46 | return jsonify({'out': str(outBuf), 'err': str(errBuf)})
47 |
48 |
49 | @app.route('/zulip', methods=['POST'])
50 | def zulip():
51 | # email = request.form['email']
52 | email = 'kuchtohtha@gmail.com'
53 | content = request.form['content']
54 | client.send_message({
55 | "type": "private",
56 | "to": email,
57 | "content": content,
58 | })
59 | return 'ok'
60 |
61 |
62 |
63 | if __name__ == '__main__':
64 | app.run(debug=True)
65 |
--------------------------------------------------------------------------------
/bot.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import zulip
4 |
5 | # Keyword arguments 'email' and 'api_key' are not required if you are using ~/.zuliprc
6 | client = zulip.Client(email="mydexter-bot@hack36.zulipchat.com",
7 | api_key="gX6ulWhAzExkZcYSAtWgpsAMbrXLjcJn",
8 | site="https://hack36.zulipchat.com")
9 |
10 | # Send a private message
11 | def send_message(message, email):
12 | client.send_message({
13 | "type": "private",
14 | "to": email,
15 | "content": message,
16 | })
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 |
2 | {}
3 |
--------------------------------------------------------------------------------
/demo/fibonacci.js:
--------------------------------------------------------------------------------
1 | function fibo(n){
2 | if (n == 1 || n == 0){
3 | return 1;
4 | }
5 | else{
6 | return fibo(n-1) + fibo(n-2);
7 | }
8 |
9 | for(let i=0; i <1000; i++){
10 | console.log(fibo(i));
11 | }
12 |
13 |
--------------------------------------------------------------------------------
/demo/fibonacci.py:
--------------------------------------------------------------------------------
1 | def fibo(n):
2 | if n == 1 or n == 0:
3 | return 1
4 | else:
5 | return fibo(n - 1) + fibo(n - 2)
6 |
7 |
8 | for i in range(1000):
9 | print(fibo(i))
10 |
--------------------------------------------------------------------------------
/editor.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 | Debug
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
187 |
188 |
189 |
190 |
--------------------------------------------------------------------------------
/js/handlers.js:
--------------------------------------------------------------------------------
1 | function js_handler(result){
2 | const js_handler_literal = {
3 | "declare_string": declare_string_js,
4 | "declare_integer": declare_integer_js,
5 | "create_function": create_function_js,
6 | "create_loop": create_loop_js,
7 | "move_cursor_to_line": move_cursor_to_line,
8 | "if_condition": if_condition_js,
9 | "print": print_js,
10 | };
11 |
12 | let entity = result.intent;
13 | let function_handler = js_handler_literal[entity];
14 | let entities = {};
15 | for (let i of result.entities){
16 | entities[i.id] = i;
17 | }
18 | return function_handler(entities);
19 | }
20 |
21 | function py_handler(result){
22 | const py_handler_literal = {
23 | "declare_string": declare_string_py,
24 | "declare_integer": declare_integer_py,
25 | "create_function": create_function_py,
26 | "create_loop": create_loop_py,
27 | "move_cursor_to_line": move_cursor_to_line,
28 | "if_condition": if_condition_py,
29 | "print": print_py,
30 | };
31 |
32 | let entity = result.intent;
33 | let function_handler = py_handler_literal[entity];
34 | let entities = {};
35 | for (let i of result.entities){
36 | entities[i.id] = i;
37 | }
38 | return function_handler(entities);
39 | }
40 |
41 | function move_cursor_to_line(entities){
42 | const lineno = entities['move_cursor_to_line_number'].value;
43 | return ({
44 | intent: "move",
45 | entity: `M-g g ${lineno}`
46 | });
47 | }
48 | function create_function_js(entities){
49 | const name = entities['create_function_name'].value;
50 | const arg = entities['create_function_argument'].value;
51 | return ({
52 | intent: "insert",
53 | entity: `function ${name}(${arg}){\n\n}`,
54 | movement_callback: ["_lineUp"]
55 | });
56 | }
57 |
58 | function create_function_py(entities){
59 | const name = entities['create_function_name'].value;
60 | const arg = entities['create_function_argument'].value;
61 | return ({
62 | intent: "insert",
63 | entity: `def ${name}(${arg}):\n`,
64 | movement_callback: []
65 |
66 | });
67 | }
68 | function create_loop_py(entities){
69 | const upper_bound = entities['create_loop_counts'].value;
70 | return ({
71 | intent: "insert",
72 | entity: `for i in range(${upper_bound}):\n\t`,
73 | movement_callback: []
74 | });
75 | }
76 |
77 | function create_loop_js(entities){
78 | const upper_bound = entities['create_loop_counts'].value;
79 | return ({
80 | intent: "insert",
81 | entity: `for (i = 0; i < ${upper_bound}; i++){\n\n}`,
82 | movement_callback: [_lineUp]
83 | });
84 | }
85 |
86 | function declare_integer_js(entities){
87 | const name = entities["declare_integer_var_name"].value;
88 | const value = entities["declare_integer_var_value"].value;
89 | return ({
90 | intent: "insert",
91 | entity: `var ${name} = ${value};\n`,
92 | movement_callback: []
93 | });
94 | }
95 |
96 | function declare_integer_py(entities){
97 | const name = entities["declare_integer_var_name"].value
98 | const value = entities["declare_integer_var_value"].value
99 | return ({
100 | intent: "insert",
101 | entity: `${name} = ${value}\n`,
102 | movement_callback: []
103 | });
104 | }
105 | function declare_string_js(entities){
106 | const name = entities["declare_string_var_name"].value
107 | const value = entities["declare_string_var_value"].value
108 | return ({
109 | intent: "insert",
110 | entity: `var ${name} = ${value};\n`,
111 | movement_callback: []
112 | });
113 | }
114 |
115 | function declare_string_py(entities){
116 | const name = entities["declare_string_var_name"].value
117 | const value = entities["declare_string_var_value"].value
118 | return ({
119 | intent: "insert",
120 | entity: `${name} = ${value}\n`,
121 | movement_callback: []
122 | });
123 | }
124 |
125 | function print_js(entities){
126 | const name = entities[""];
127 | }
128 |
129 | function if_condition_js(){
130 |
131 | }
132 |
133 | function if_condition_py(){
134 |
135 | }
136 | function print_js(entities){
137 | const arg = (entities["argument"] === undefined) ? (entities['number'].value) : (entities['argument'].value)
138 | return ({
139 | intent: "insert",
140 | entity: `console.log(${arg})\n`
141 | });
142 | }
143 |
144 | function print_py(entities){
145 | const arg = (entities["argument"] === undefined) ? (entities['number'].value) : (entities['argument'].value)
146 | return ({
147 | intent: "insert",
148 | entity: `print(${arg})\n`
149 | });
150 | }
151 |
--------------------------------------------------------------------------------
/js/index.js:
--------------------------------------------------------------------------------
1 | var toggleHindi = function () {
2 | $('#hindi').css('opacity', '1');
3 | $('#english').css('opacity', '0.3');
4 | };
5 |
6 | var toggleEnglish = function () {
7 | $('#hindi').css('opacity', '0.3');
8 | $('#english').css('opacity', '1');
9 | };
10 |
11 |
12 | $('#hindi').click(toggleHindi);
13 | $('#english').click(toggleEnglish);
14 |
15 |
16 | var fullView = function () {
17 | $('#editorspane').css('grid-template-columns', '49.75% 0.5% 49.75%');
18 | }
19 |
20 | var jsView = function () {
21 | $('#editorspane').css('grid-template-columns', '100% 0% 0%');
22 | }
23 |
24 | var pyView = function () {
25 | $('#editorspane').css('grid-template-columns', '0% 0% 100%');
26 | }
27 |
--------------------------------------------------------------------------------
/js/mic.js:
--------------------------------------------------------------------------------
1 | class Mic {
2 | constructor(resultReceiver) {
3 | this.langs = [
4 | ['English (India)', 'en-IN'],
5 | ['Hindi', 'hi-IN']
6 | ];
7 |
8 | this.final_transcript = '';
9 | this.current_transcript = '';
10 | this.recognition = null;
11 | this.compatible = false;
12 | this.listening = false;
13 | this.languageSelector = null;
14 | this.currentLanguage = this.langs[0][1];
15 | this.resultReceiver = resultReceiver;
16 | }
17 |
18 | static capitalize(s) {
19 | let first_char = /\S/;
20 | return s.replace(first_char, function (m) { return m.toUpperCase(); });
21 | }
22 |
23 | static checkCompatibility() {
24 | return 'webkitSpeechRecognition' in window ||
25 | 'SpeechRecognition' in window;
26 | }
27 |
28 | setupRecognitionHandlers() {
29 | if (!this.recognition) {
30 | console.log("Recognition not set up. This should not happen.");
31 | return;
32 | }
33 | this.recognition.onstart = () => {
34 | this.listening = true;
35 | };
36 | this.recognition.onerror = (event) => {
37 | console.log("recognition says: wtf " + event.error);
38 | };
39 | this.recognition.onend = () => {
40 | if (this.listening && this.recognition !== undefined) {
41 | console.log('restarting mic')
42 | this.recognition.start();
43 | }
44 | };
45 | this.recognition.onresult = (event) => {
46 | for (var i = event.resultIndex; i < event.results.length; ++i) {
47 | if (event.results[i].isFinal) {
48 | this.current_transcript = event.results[i][0].transcript;
49 | // this.final_transcript += event.results[i][0].transcript + '. ';
50 | }
51 | }
52 | console.log('mic says:', this.current_transcript.toLowerCase())
53 | this.resultReceiver(this.current_transcript.toLowerCase())
54 |
55 | // this.final_transcript = Mic.capitalize(this.final_transcript);
56 | // askWatson(current_transcript, change);
57 | // console.log(this.current_transcript, '--', this.final_transcript);
58 | // if (this.resultDisplay)
59 | // this.resultDisplay.innerText = this.current_transcript;
60 | // final_span.innerHTML = linebreak(final_transcript);
61 | };
62 | }
63 |
64 | // garbage
65 | setupMic(resultReceiver) {
66 | this.resultReceiver = resultReceiver
67 | }
68 |
69 | // setupMic(micElem, outputElem, languageSelect, errorHandlerDiv) {
70 | // // setup language selectors
71 | // if (languageSelect) {
72 | // languageSelector = languageSelect;
73 | // while (languageSelect.options.length > 0)
74 | // languageSelect.options.remove(0);
75 | // for (let i = 0; i < this.langs.length; i++)
76 | // languageSelect.options.add(new Option(this.langs[i][0], this.langs[i][1]));
77 | // }
78 |
79 | // // setup mic elem
80 | // micElem.onclick = micClicked;
81 | // resultDisplay = outputElem;
82 | // }
83 |
84 | setLang(lang) {
85 | if (lang == 'en') this.currentLanguage = 'en-IN';
86 | else if (lang == 'hi') this.currentLanguage = 'hi-IN';
87 | }
88 |
89 | micClicked(event) {
90 | if (this.listening) {
91 | this.stopListening();
92 | return;
93 | }
94 | try {
95 | if (en == 1) this.setLang('en');
96 | else if (hi == 1) this.setLang('hi');
97 | } catch (e) { }
98 | this.startListening();
99 | }
100 |
101 |
102 | startListening() {
103 | if (!this.recognition) {
104 | this.recognition = new webkitSpeechRecognition();
105 | this.setupRecognitionHandlers();
106 | }
107 | this.listening = true;
108 | this.final_transcript = '';
109 | this.recognition.lang = this.currentLanguage;
110 | this.recognition.start();
111 | }
112 |
113 | stopListening() {
114 | if (this.recognition)
115 | this.listening = false;
116 | this.recognition = null;
117 | }
118 |
119 | }
120 |
121 |
122 | // function askWatson(text, callback) {
123 | // if (window.jQuery === undefined) {
124 | // console.log("i need to do ajax. import jquery before me");
125 | // }
126 | // if (currentLanguage == 'en-IN')
127 | // $.get('/askWatson/' + encodeURIComponent(text), callback);
128 | // else if (currentLanguage == 'hi-IN') {
129 | // $.get('http://api.mymemory.translated.net/get?q=' + current_transcript + '&langpair=hi|en', function (data) {
130 | // console.log(data.responseData.translatedText);
131 | // $.get('/askWatson/' + encodeURIComponent(data.responseData.translatedText), callback);
132 | // });
133 | // }
134 | // }
135 |
136 |
--------------------------------------------------------------------------------
/js/parser.js:
--------------------------------------------------------------------------------
1 | var allowed_variable_names = [
2 | { id: 'alpha', text: 'alpha' },
3 | { id: 'beta', text: 'beta' },
4 | { id: 'gamma', text: 'gamma' },
5 | { id: 'my_variable', text: 'my variable' },
6 | { id: 'random_number', text: 'random number' },
7 | { id: 'x', text: 'x' },
8 | { id: 'y', text: 'y' },
9 | { id: 'z', text: 'z' },
10 | { id: 'i', text: 'i' },
11 | ]
12 |
13 | var allowed_relational_operators = [
14 | { id: 'equal_to', text: 'equal to' },
15 | { id: 'equal_to', text: 'equal to' },
16 | { id: 'equal_to', text: 'equals to' },
17 | { id: 'equal_to', text: 'equals' },
18 | { id: 'greater_than', text: 'greater than' },
19 | { id: 'greater_than', text: 'is greater than' },
20 | { id: 'less_than', text: 'less than' },
21 | { id: 'less_than', text: 'is less than' },
22 | ]
23 |
24 | // var allowed_logical_operators = [ 'and', 'or', 'not' ]
25 | var allowed_logical_operators = [
26 | { id: 'and', text: 'and' },
27 | { id: 'or', text: 'or' },
28 | { id: 'not', text: 'not' },
29 | ]
30 |
31 | var allowed_arithmetic_operators = [
32 | { id: 'sum', text: 'sum' },
33 | { id: 'difference', text: 'difference' },
34 | { id: 'product', text: 'product' },
35 | { id: 'division', text: 'division' },
36 | ]
37 |
38 | var allowed_numbers = [
39 | { id: 'zero', text: 'zero' },
40 | { id: 'one', text: 'one' },
41 | { id: 'two', text: 'two' },
42 | { id: 'three', text: 'three' },
43 | { id: 'four', text: 'four' },
44 | { id: 'five', text: 'five' },
45 | ]
46 |
47 | var allowed_function_names = [
48 | { id: 'fibonacci', text: 'fibonacci' },
49 | { id: 'factorial', text: 'factorial' },
50 | { id: 'prime_finder', text: 'prime finder' },
51 | ]
52 |
53 | var known_commands = [
54 | { id: 'js_move_up', text: 'javascript move up' },
55 | { id: 'js_move_down', text: 'javascript move down' },
56 | { id: 'js_move_left', text: 'javascript move left' },
57 | { id: 'js_move_right', text: 'javascript move right' },
58 |
59 | { id: 'py_move_up', text: 'python move up' },
60 | { id: 'py_move_down', text: 'python move down' },
61 | { id: 'py_move_left', text: 'python move left' },
62 | { id: 'py_move_right', text: 'python move right' },
63 |
64 | { id: 'dexter_start', text: 'dexter start' },
65 | { id: 'dexter_stop', text: 'dexter stop' },
66 | { id: 'dexter_javascript', text: 'dexter javascript'},
67 | { id: 'dexter_python', text: 'dexter python'},
68 | { id: 'dexter_full', text: 'dexter full'},
69 |
70 | { id: 'dexter_clear', text: 'dexter clear' },
71 |
72 | // { id: 'dexter_run', text: 'dexter run code' },
73 | // { id: 'dexter_run', text: 'code chala do bhai' },
74 | { id: 'dexter_run_py', text: 'arey bhai bhai bhai' },
75 | { id: 'dexter_run_py', text: 'dexter run python' },
76 | { id: 'dexter_run_js', text: 'dexter run javascript' },
77 | { id: 'dexter_zulip', text: 'zulip pe bhej do' },
78 | { id: 'dexter_zulip', text: 'dexter save' },
79 |
80 | { id: 'dexter_undo', text: 'dexter undo' },
81 | { id: 'dexter_redo', text: 'dexter redo'},
82 |
83 | { id: 'dexter_add_closing_bracket', text: 'dexter add closing bracket' },
84 | ]
85 |
86 | function IsKnownCommand(command) {
87 | for (let each of known_commands) {
88 | if (each.id == command) return true
89 | }
90 | return false
91 | }
92 |
93 |
94 | function setUpNlp() {
95 | if (window.Bravey === undefined) {
96 | throw "Bravey is not available";
97 | }
98 |
99 | var nlp = new Bravey.Nlp.Fuzzy();
100 |
101 | // adding intents one by one
102 |
103 | // declare_integer
104 | {
105 | nlp.addIntent('declare_integer', [
106 | { entity: 'declare_integer_var_name', id: 'declare_integer_var_name' },
107 | { entity: 'declare_integer_var_value', id: 'declare_integer_var_value' },
108 | ]);
109 |
110 | let declare_integer_var_name = new Bravey.StringEntityRecognizer('declare_integer_var_name');
111 |
112 | for (let each of allowed_variable_names) {
113 | declare_integer_var_name.addMatch(each.id, each.text)
114 | }
115 | nlp.addEntity(declare_integer_var_name);
116 |
117 | let declare_integer_var_value = new Bravey.NumberEntityRecognizer('declare_integer_var_value');
118 | nlp.addEntity(declare_integer_var_value);
119 |
120 | // train with some examples
121 | nlp.addDocument(
122 | 'Declare an integer {declare_integer_var_name} with value {declare_integer_var_value}',
123 | 'declare_integer'
124 | );
125 |
126 | nlp.addDocument(
127 | 'Create an integer {declare_integer_var_name} with value {declare_integer_var_value}',
128 | 'declare_integer'
129 | );
130 |
131 | // test it
132 | showResults(nlp.test('declare an integer alpha with value 100'));
133 | // nlp.test('Declare an integer with value 100')
134 | }
135 |
136 | //create_function
137 | {
138 | nlp.addIntent('create_function', [
139 | { entity: 'create_function_name', id: 'create_function_name' },
140 | { entity: 'create_function_argument', id: 'create_function_argument' },
141 | ]);
142 | // let create_function_name = new Bravey.StringEntityRecognizer('create_function_name')
143 | // create_function_name.addMatch('fibonacci', 'fibonacci')
144 | // nlp.addEntity(create_function_name)
145 |
146 | let create_function_name = new Bravey.StringEntityRecognizer('create_function_name')
147 | for (let each of allowed_function_names) {
148 | create_function_name.addMatch(each.id, each.text)
149 | }
150 | nlp.addEntity(create_function_name)
151 |
152 | let create_function_argument = new Bravey.StringEntityRecognizer('create_function_argument')
153 | for (let each of allowed_variable_names) {
154 | create_function_argument.addMatch(each.id, each.text)
155 | }
156 |
157 | nlp.addEntity(create_function_argument);
158 |
159 | nlp.addDocument(
160 | 'Create a function {create_function_name} with argument {create_function_argument}',
161 | 'create_function'
162 | )
163 |
164 | showResults(nlp.test('create function fibonacci with argument alpha.'));
165 | }
166 |
167 | // declare_string
168 | {
169 | nlp.addIntent('declare_string', [
170 | { entity: 'declare_string_var_name', id: 'declare_string_var_name' },
171 | { entity: 'declare_string_var_value', id: 'declare_string_var_value' },
172 | ]);
173 |
174 | let declare_string_var_name = new Bravey.StringEntityRecognizer('declare_string_var_name');
175 | for (let each of allowed_variable_names) {
176 | declare_string_var_name.addMatch(each.id, each.text)
177 | }
178 | nlp.addEntity(declare_string_var_name);
179 |
180 | let declare_string_var_value = new Bravey.NumberEntityRecognizer('declare_string_var_value');
181 | nlp.addEntity(declare_string_var_value);
182 |
183 | // train with some examples
184 | nlp.addDocument(
185 | 'Declare an string {declare_string_var_name} with value {declare_string_var_value}',
186 | 'declare_string'
187 | );
188 |
189 | // test it
190 | showResults(nlp.test('declare an string alpha with value tomato'));
191 | // nlp.test('Declare an integer with value 100')
192 | }
193 |
194 | // create loop
195 | {
196 | nlp.addIntent('create_loop', [
197 | { entity: 'create_loop_counts', id: 'create_loop_counts' },
198 | ]);
199 |
200 | let create_loop_counts = new Bravey.NumberEntityRecognizer('create_loop_counts');
201 | nlp.addEntity(create_loop_counts);
202 |
203 | // train with some examples
204 | nlp.addDocument(
205 | 'Create a loop for {create_loop_counts} counts',
206 | 'create_loop'
207 | );
208 |
209 | // test it
210 | showResults(nlp.test('run a loop for 100 counts'));
211 | showResults(nlp.test('make a loop for 20 counts'));
212 | }
213 |
214 | // move cursor to line
215 | // {
216 | // nlp.addIntent('move_cursor_to_line', [
217 | // { entity: 'move_cursor_to_line_number', id: 'move_cursor_to_line_number' },
218 | // ]);
219 |
220 | // let move_cursor_to_line_number = new Bravey.NumberEntityRecognizer('move_cursor_to_line_number');
221 | // nlp.addEntity(move_cursor_to_line_number);
222 | // // train with some examples;
223 | // nlp.addDocument(
224 | // 'Move cursor to line {move_cursor_to_line_number}',
225 | // 'move_cursor_to_line'
226 | // );
227 |
228 | // // test it
229 | // showResults(nlp.test('move cursor to line 100'));
230 | // showResults(nlp.test('place cursor on line 343'));
231 | // }
232 |
233 | // if_else
234 | {
235 | nlp.addIntent('if_condition', [
236 | { entity: 'if_condition_1_lhs', id: 'if_condition_1_lhs' },
237 | { entity: 'if_condition_1_op', id: 'if_condition_1_op' },
238 | { entity: 'if_condition_1_rhs', id: 'if_condition_1_rhs' },
239 |
240 | { entity: 'if_condition_join_op', id: 'if_condition_join_op' },
241 |
242 | { entity: 'if_condition_2_lhs', id: 'if_condition_2_lhs' },
243 | { entity: 'if_condition_2_op', id: 'if_condition_2_op' },
244 | { entity: 'if_condition_2_rhs', id: 'if_condition_2_rhs' },
245 | ]);
246 |
247 | // for lhs, match with variable names
248 | for (let target of ['if_condition_1_lhs', 'if_condition_2_lhs']) {
249 | let variable_name = new Bravey.StringEntityRecognizer(target)
250 | for (let each of allowed_variable_names) {
251 | variable_name.addMatch(each.id, each.text)
252 | }
253 | nlp.addEntity(variable_name)
254 | }
255 |
256 | // for rhs, match with numbers
257 | for (let target of ['if_condition_1_rhs', 'if_condition_2_rhs']) {
258 | let number = new Bravey.StringEntityRecognizer(target)
259 | for (let each of allowed_numbers) {
260 | number.addMatch(each.id, each.text)
261 | }
262 | nlp.addEntity(number)
263 | }
264 |
265 | // for lhs, rhs, the relational operators
266 | for (let target of ['if_condition_1_op', 'if_condition_2_op']) {
267 | let operator = new Bravey.StringEntityRecognizer(target)
268 | for (let each of allowed_relational_operators) {
269 | operator.addMatch(each.id, each.text)
270 | }
271 | nlp.addEntity(operator)
272 | }
273 |
274 | // for the two clauses
275 | {
276 | let operator = new Bravey.StringEntityRecognizer('if_condition_join_op')
277 | for (let each of allowed_logical_operators) {
278 | operator.addMatch(each.id, each.text)
279 | }
280 | nlp.addEntity(operator)
281 | }
282 |
283 | // lets train it
284 | nlp.addDocument(
285 | 'if alpha equals one and alpha equals two',
286 | 'if_condition',
287 | { fromFullSentence: true, expandIntent: true },
288 | )
289 |
290 | nlp.addDocument(
291 | 'if alpha equals one or beta equals one',
292 | 'if_condition',
293 | { fromFullSentence: true, expandIntent: true },
294 | )
295 |
296 | nlp.addDocument(
297 | 'if alpha equals one and x equals zero',
298 | 'if_condition',
299 | { fromFullSentence: true, expandIntent: true },
300 | )
301 |
302 | // nlp.addDocument(
303 | // 'if with condition {if_condition_1_lhs} {if_condition_1_op} {if_condition_1_rhs} {if_condition_join_op} {if_condition_2_lhs} {if_condition_2_op} {if_condition_2_rhs}',
304 | // 'if_condition'
305 | // )
306 |
307 | // nlp.addDocument(
308 | // 'if {if_condition_1_lhs} {if_condition_1_op} {if_condition_1_rhs}',
309 | // 'if_condition'
310 | // )
311 |
312 | // testing some examples
313 | // showResults(nlp.test('if alpha is greater than 5'))
314 | showResults(nlp.test('if alpha equals one or beta equals two'))
315 | }
316 |
317 | // arithmetic operations
318 | {
319 | nlp.addIntent('arithmetic_operation', [
320 | { entity: 'arithmetic_operand_1', id: 'arithmetic_operand_1' },
321 | { entity: 'arithmetic_operand_2', id: 'arithmetic_operand_2' },
322 | { entity: 'arithmetic_operator', id: 'arithmetic_operator' },
323 | { entity: 'arithmetic_lhs', id: 'arithmetic_lhs' },
324 | ])
325 |
326 | nlp.addEntity(new Bravey.NumberEntityRecognizer('arithmetic_operand_2'))
327 | let arithmetc_operator = new Bravey.StringEntityRecognizer('arithmetic_operator')
328 | for (let each of allowed_arithmetic_operators) {
329 | arithmetc_operator.addMatch(each.id, each.text)
330 | }
331 | nlp.addEntity(arithmetc_operator)
332 |
333 | for (let target of ['arithmetic_operand_1', 'arithmetic_lhs']) {
334 | let variable_name = new Bravey.StringEntityRecognizer(target)
335 | for (let each of allowed_variable_names) {
336 | variable_name.addMatch(each.id, each.text)
337 | }
338 | nlp.addEntity(variable_name)
339 | }
340 |
341 | // train with some examples
342 | // nlp.addDocument(
343 | // '{arithmetic_operator} {arithmetic_operand_1} and {arithmetic_operand_2} and store it in {arithmetic_lhs}',
344 | // 'arithmetic_operation'
345 | // )
346 | nlp.addDocument(
347 | 'store sum of x and 3 in alpha',
348 | 'arithmetic_operation',
349 | { fromFullSentence: true, expandIntent: true }
350 | )
351 |
352 | nlp.addDocument(
353 | 'store product of alpha and 30 in beta',
354 | 'arithmetic_operation',
355 | { fromFullSentence: true, expandIntent: true }
356 | )
357 |
358 | nlp.addDocument(
359 | 'store difference of gamma and 10 in x',
360 | 'arithmetic_operation',
361 | { fromFullSentence: true, expandIntent: true }
362 | )
363 |
364 | nlp.addDocument(
365 | 'store the division of y and 8 in y',
366 | 'arithmetic_operation',
367 | { fromFullSentence: true, expandIntent: true }
368 | )
369 | // some tests
370 | showResults(nlp.test('store the sum of z and 20 in z'))
371 |
372 | }
373 |
374 | // some custom commands
375 |
376 | for (let command of known_commands) {
377 | nlp.addDocument(command.text, command.id, { fromFullSentence: true, expandIntent: true })
378 | }
379 |
380 |
381 | // print function
382 | {
383 | nlp.addIntent('print', [
384 | { entity: 'argument', id: 'argument' },
385 | { entity: 'number', id: 'number' },
386 | ]);
387 |
388 | let argument = new Bravey.StringEntityRecognizer('argument');
389 | for (let each of allowed_variable_names) {
390 | argument.addMatch(each.id, each.text)
391 | }
392 | nlp.addEntity(argument);
393 |
394 | nlp.addEntity(new Bravey.NumberEntityRecognizer('number'))
395 |
396 | // train with some examples
397 | nlp.addDocument(
398 | 'print {argument}',
399 | 'print'
400 | );
401 |
402 | nlp.addDocument(
403 | 'print {number}',
404 | 'print'
405 | )
406 |
407 | // test it
408 | showResults(nlp.test('print alpha'));
409 | showResults(nlp.test('print 100'))
410 | // nlp.test('Declare an integer with value 100')
411 | }
412 |
413 |
414 |
415 | return nlp;
416 | }
417 |
418 | function showResults(result) {
419 | if (result) {
420 | for (let entity of result.entities) {
421 | console.log(entity.id, entity.value);
422 | }
423 | } else {
424 | console.log('something failed here')
425 | }
426 | }
427 |
--------------------------------------------------------------------------------
/judge.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # Reference
4 | # https://stackoverflow.com/a/31867499
5 | # https://docs.python.org/3/library/threading.html
6 | # https://docs.python.org/3/library/subprocess.html
7 |
8 |
9 | from subprocess import Popen, PIPE
10 | from threading import Thread
11 | import queue # Python 2
12 |
13 | def reader(pipe, q):
14 | try:
15 | for line in iter(pipe.readline, b''):
16 | q.put((pipe, line))
17 | finally:
18 | q.put(None)
19 |
20 |
21 | def runProcess(command, timeout=10):
22 | process = Popen(command, stdout=PIPE, stderr=PIPE, bufsize=1)
23 | q = queue.Queue()
24 | outTh = Thread(target=reader, args=[process.stdout, q])
25 | errTh = Thread(target=reader, args=[process.stderr, q])
26 | outTh.start()
27 | errTh.start()
28 | outTh.join(timeout=timeout)
29 | errTh.join(timeout=timeout)
30 |
31 | outBuf, errBuf = b'', b''
32 | for _ in range(2):
33 | for source, line in iter(q.get, None):
34 | # print ("%s: %s" % (source, line))
35 | if source == process.stdout:
36 | outBuf += line
37 | elif source == process.stderr:
38 | errBuf += line
39 |
40 | return outBuf, errBuf
41 |
42 |
43 | if __name__ == '__main__':
44 | # outBuf, errBuf = runProcess(["python3", "sample.py"])
45 | outBuf, errBuf = runProcess(["gcc", "sample.c"])
46 | print("stdout:")
47 | print(outBuf)
48 | print()
49 | print("stderr:")
50 | print(errBuf)
51 |
52 | outBuf, errBuf = runProcess(["./a.out"])
53 | print("stdout:")
54 | print(outBuf)
55 | print()
56 | print("stderr:")
57 | print(errBuf)
58 |
--------------------------------------------------------------------------------
/lib/pane1/codemirror.css:
--------------------------------------------------------------------------------
1 | /* BASICS */
2 |
3 | .CodeMirror {
4 | /* Set height, width, borders, and global font properties here */
5 | font-family: 'Roboto Mono';
6 | line-height: 1.5em;
7 | color: white;
8 | direction: ltr;
9 | }
10 |
11 | /* PADDING */
12 |
13 | .CodeMirror-lines {
14 | padding: 0.5em 0; /* Vertical padding around content */
15 | }
16 | .CodeMirror pre {
17 | padding: 0 1.5em; /* Horizontal padding of content */
18 | }
19 |
20 | .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
21 | background-color: white; /* The little square between H and V scrollbars */
22 | }
23 |
24 | /* GUTTER */
25 |
26 | .CodeMirror-gutters {
27 | /* Rectangle 8: */
28 | background: transparent;
29 | white-space: nowrap;
30 | }
31 | .CodeMirror-linenumbers {}
32 | .CodeMirror-linenumber {
33 | padding: 0 4px 0 4px;
34 | min-width: 2em;
35 | text-align: right;
36 | color: #475174;
37 | white-space: nowrap;
38 | }
39 |
40 | .CodeMirror-guttermarker { color: black; }
41 | .CodeMirror-guttermarker-subtle { color: #475174; }
42 |
43 | /* CURSOR */
44 |
45 | .CodeMirror-cursor {
46 | border-left: 1px solid black;
47 | border-right: none;
48 | width: 0;
49 | }
50 | /* Shown when moving in bi-directional text */
51 | .CodeMirror div.CodeMirror-secondarycursor {
52 | border-left: 1px solid silver;
53 | }
54 | .cm-fat-cursor .CodeMirror-cursor {
55 | width: auto;
56 | border: 0 !important;
57 | background: #7e7;
58 | }
59 | .cm-fat-cursor div.CodeMirror-cursors {
60 | z-index: 1;
61 | }
62 | .cm-fat-cursor-mark {
63 | background-color: rgba(20, 255, 20, 0.5);
64 | -webkit-animation: blink 1.06s steps(1) infinite;
65 | -moz-animation: blink 1.06s steps(1) infinite;
66 | animation: blink 1.06s steps(1) infinite;
67 | }
68 | .cm-animate-fat-cursor {
69 | width: auto;
70 | border: 0;
71 | -webkit-animation: blink 1.06s steps(1) infinite;
72 | -moz-animation: blink 1.06s steps(1) infinite;
73 | animation: blink 1.06s steps(1) infinite;
74 | background-color: #7e7;
75 | }
76 | @-moz-keyframes blink {
77 | 0% {}
78 | 50% { background-color: transparent; }
79 | 100% {}
80 | }
81 | @-webkit-keyframes blink {
82 | 0% {}
83 | 50% { background-color: transparent; }
84 | 100% {}
85 | }
86 | @keyframes blink {
87 | 0% {}
88 | 50% { background-color: transparent; }
89 | 100% {}
90 | }
91 |
92 | /* Can style cursor different in overwrite (non-insert) mode */
93 | .CodeMirror-overwrite .CodeMirror-cursor {}
94 |
95 | .cm-tab { display: inline-block; text-decoration: inherit; }
96 |
97 | .CodeMirror-rulers {
98 | position: absolute;
99 | left: 0; right: 0; top: -50px; bottom: -20px;
100 | overflow: hidden;
101 | }
102 | .CodeMirror-ruler {
103 | border-left: 1px solid #ccc;
104 | top: 0; bottom: 0;
105 | position: absolute;
106 | }
107 |
108 | /* DEFAULT THEME */
109 |
110 | .cm-s-default .cm-header {color: blue;}
111 | .cm-s-default .cm-quote {color: #090;}
112 | .cm-negative {color: #FF2759;}
113 | .cm-positive {color: #42A15E;}
114 | .cm-header, .cm-strong {font-weight: bold;}
115 | .cm-em {font-style: italic;}
116 | .cm-link {text-decoration: underline;}
117 | .cm-strikethrough {text-decoration: line-through;}
118 |
119 | .cm-s-default .cm-keyword {color: #FF309D;}
120 | .cm-s-default .cm-atom {color: #00C1F9;}
121 | .cm-s-default .cm-number {color: white;}
122 | .cm-s-default .cm-def {color: #00B2F7;}
123 | .cm-s-default .cm-variable,
124 | .cm-s-default .cm-punctuation,
125 | .cm-s-default .cm-property,
126 | .cm-s-default .cm-operator {color: }
127 | .cm-s-default .cm-variable-2 {color: #0669A8;}
128 | .cm-s-default .cm-variable-3, .cm-s-default .cm-type {color: #42A15E;}
129 | .cm-s-default .cm-comment {color: #5762B9;}
130 | .cm-s-default .cm-string {color: #a11;}
131 | .cm-s-default .cm-string-2 {color: #f50;}
132 | .cm-s-default .cm-meta {color: #555;}
133 | .cm-s-default .cm-qualifier {color: #555;}
134 | .cm-s-default .cm-builtin {color: #FF2759;}
135 | .cm-s-default .cm-bracket {color: #997;}
136 | .cm-s-default .cm-tag {color: #170;}
137 | .cm-s-default .cm-attribute {color: #00c;}
138 | .cm-s-default .cm-hr {color: #999;}
139 | .cm-s-default .cm-link {color: #00c;}
140 |
141 | .cm-s-default .cm-error {color: #FF2759;}
142 | .cm-invalidchar {color: #FF2759;}
143 |
144 | .CodeMirror-composing { border-bottom: 2px solid; }
145 |
146 | /* Default styles for common addons */
147 |
148 | div.CodeMirror span.CodeMirror-matchingbracket {color: #00FFFF;}
149 | div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
150 | .CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
151 | .CodeMirror-activeline-background {background: #e8f2ff;}
152 |
153 | /* STOP */
154 |
155 | /* The rest of this file contains styles related to the mechanics of
156 | the editor. You probably shouldn't touch them. */
157 |
158 | .CodeMirror {
159 | position: relative;
160 | overflow: hidden;
161 | /* Rectangle 8: */
162 | background: transparent;
163 | }
164 |
165 | .CodeMirror-scroll {
166 | overflow: scroll !important; /* Things will break if this is overridden */
167 | /* 30px is the magic margin used to hide the element's real scrollbars */
168 | /* See overflow: hidden in .CodeMirror */
169 | margin-bottom: -30px; margin-right: -30px;
170 | padding-bottom: 30px;
171 | height: 100%;
172 | outline: none; /* Prevent dragging from highlighting the element */
173 | position: relative;
174 | }
175 | .CodeMirror-sizer {
176 | position: relative;
177 | border-right: 30px solid transparent;
178 | }
179 |
180 | /* The fake, visible scrollbars. Used to force redraw during scrolling
181 | before actual scrolling happens, thus preventing shaking and
182 | flickering artifacts. */
183 | .CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
184 | position: absolute;
185 | z-index: 6;
186 | display: none;
187 | }
188 | .CodeMirror-vscrollbar {
189 | right: 0; top: 0;
190 | overflow-x: hidden;
191 | overflow-y: scroll;
192 | }
193 | .CodeMirror-hscrollbar {
194 | bottom: 0; left: 0;
195 | overflow-y: hidden;
196 | overflow-x: scroll;
197 | }
198 | .CodeMirror-scrollbar-filler {
199 | right: 0; bottom: 0;
200 | }
201 | .CodeMirror-gutter-filler {
202 | left: 0; bottom: 0;
203 | }
204 |
205 | .CodeMirror-gutters {
206 | position: absolute; left: 0; top: 0;
207 | min-height: 100%;
208 | z-index: 3;
209 | }
210 | .CodeMirror-gutter {
211 | white-space: normal;
212 | height: 100%;
213 | display: inline-block;
214 | vertical-align: top;
215 | margin-bottom: -30px;
216 | }
217 | .CodeMirror-gutter-wrapper {
218 | position: absolute;
219 | z-index: 4;
220 | background: none !important;
221 | border: none !important;
222 | }
223 | .CodeMirror-gutter-background {
224 | position: absolute;
225 | top: 0; bottom: 0;
226 | z-index: 4;
227 | }
228 | .CodeMirror-gutter-elt {
229 | position: absolute;
230 | cursor: default;
231 | z-index: 4;
232 | }
233 | .CodeMirror-gutter-wrapper ::selection { background-color: transparent }
234 | .CodeMirror-gutter-wrapper ::-moz-selection { background-color: transparent }
235 |
236 | .CodeMirror-lines {
237 | cursor: text;
238 | min-height: 1px; /* prevents collapsing before first draw */
239 | }
240 | .CodeMirror pre {
241 | /* Reset some styles that the rest of the page might have set */
242 | -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
243 | border-width: 0;
244 | background: transparent;
245 | font-family: inherit;
246 | font-size: inherit;
247 | margin: 0;
248 | white-space: pre;
249 | word-wrap: normal;
250 | line-height: inherit;
251 | color: inherit;
252 | z-index: 2;
253 | position: relative;
254 | overflow: visible;
255 | -webkit-tap-highlight-color: transparent;
256 | -webkit-font-variant-ligatures: contextual;
257 | font-variant-ligatures: contextual;
258 | }
259 | .CodeMirror-wrap pre {
260 | word-wrap: break-word;
261 | white-space: pre-wrap;
262 | word-break: normal;
263 | }
264 |
265 | .CodeMirror-linebackground {
266 | position: absolute;
267 | left: 0; right: 0; top: 0; bottom: 0;
268 | z-index: 0;
269 | }
270 |
271 | .CodeMirror-linewidget {
272 | position: relative;
273 | z-index: 2;
274 | padding: 0.1px; /* Force widget margins to stay inside of the container */
275 | }
276 |
277 | .CodeMirror-widget {}
278 |
279 | .CodeMirror-rtl pre { direction: rtl; }
280 |
281 | .CodeMirror-code {
282 | outline: none;
283 | }
284 |
285 | /* Force content-box sizing for the elements where we expect it */
286 | .CodeMirror-scroll,
287 | .CodeMirror-sizer,
288 | .CodeMirror-gutter,
289 | .CodeMirror-gutters,
290 | .CodeMirror-linenumber {
291 | -moz-box-sizing: content-box;
292 | box-sizing: content-box;
293 | }
294 |
295 | .CodeMirror-measure {
296 | position: absolute;
297 | width: 100%;
298 | height: 0;
299 | overflow: hidden;
300 | visibility: hidden;
301 | }
302 |
303 | .CodeMirror-cursor {
304 | position: absolute;
305 | pointer-events: none;
306 | }
307 | .CodeMirror-measure pre { position: static; }
308 |
309 | div.CodeMirror-cursors {
310 | visibility: hidden;
311 | position: relative;
312 | z-index: 3;
313 | }
314 | div.CodeMirror-dragcursors {
315 | visibility: visible;
316 | }
317 |
318 | .CodeMirror-focused div.CodeMirror-cursors {
319 | visibility: visible;
320 | }
321 |
322 | .CodeMirror-selected { background: #d9d9d9; }
323 | .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
324 | .CodeMirror-crosshair { cursor: crosshair; }
325 | .CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
326 | .CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
327 |
328 | .cm-searching {
329 | background-color: #ffa;
330 | background-color: rgba(255, 255, 0, .4);
331 | }
332 |
333 | /* Used to force a border model for a node */
334 | .cm-force-border { padding-right: .1px; }
335 |
336 | @media print {
337 | /* Hide the cursor when printing */
338 | .CodeMirror div.CodeMirror-cursors {
339 | visibility: hidden;
340 | }
341 | }
342 |
343 | /* See issue #2901 */
344 | .cm-tab-wrap-hack:after { content: ''; }
345 |
346 | /* Help users use markselection to safely style text background */
347 | span.CodeMirror-selectedtext { background: none; }
348 |
--------------------------------------------------------------------------------
/lib/pane1/dialog.css:
--------------------------------------------------------------------------------
1 | .CodeMirror-dialog {
2 | position: absolute;
3 | left: 0; right: 0;
4 | background: inherit;
5 | z-index: 15;
6 | padding: .1em .8em;
7 | overflow: hidden;
8 | color: inherit;
9 | }
10 |
11 | .CodeMirror-dialog-top {
12 | border-bottom: 1px solid #eee;
13 | top: 0;
14 | }
15 |
16 | .CodeMirror-dialog-bottom {
17 | border-top: 1px solid #eee;
18 | bottom: 0;
19 | }
20 |
21 | .CodeMirror-dialog input {
22 | border: none;
23 | outline: none;
24 | background: transparent;
25 | width: 20em;
26 | color: inherit;
27 | font-family: monospace;
28 | }
29 |
30 | .CodeMirror-dialog button {
31 | font-size: 70%;
32 | }
33 |
--------------------------------------------------------------------------------
/lib/pane1/dialog.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: http://codemirror.net/LICENSE
3 |
4 | // Open simple dialogs on top of an editor. Relies on dialog.css.
5 |
6 | (function(mod) {
7 | if (typeof exports == "object" && typeof module == "object") // CommonJS
8 | mod(require("../../lib/codemirror"));
9 | else if (typeof define == "function" && define.amd) // AMD
10 | define(["../../lib/codemirror"], mod);
11 | else // Plain browser env
12 | mod(CodeMirror);
13 | })(function(CodeMirror) {
14 | function dialogDiv(cm, template, bottom) {
15 | var wrap = cm.getWrapperElement();
16 | var dialog;
17 | dialog = wrap.appendChild(document.createElement("div"));
18 | if (bottom)
19 | dialog.className = "CodeMirror-dialog CodeMirror-dialog-bottom";
20 | else
21 | dialog.className = "CodeMirror-dialog CodeMirror-dialog-top";
22 |
23 | if (typeof template == "string") {
24 | dialog.innerHTML = template;
25 | } else { // Assuming it's a detached DOM element.
26 | dialog.appendChild(template);
27 | }
28 | return dialog;
29 | }
30 |
31 | function closeNotification(cm, newVal) {
32 | if (cm.state.currentNotificationClose)
33 | cm.state.currentNotificationClose();
34 | cm.state.currentNotificationClose = newVal;
35 | }
36 |
37 | CodeMirror.defineExtension("openDialog", function(template, callback, options) {
38 | if (!options) options = {};
39 |
40 | closeNotification(this, null);
41 |
42 | var dialog = dialogDiv(this, template, options.bottom);
43 | var closed = false, me = this;
44 | function close(newVal) {
45 | if (typeof newVal == 'string') {
46 | inp.value = newVal;
47 | } else {
48 | if (closed) return;
49 | closed = true;
50 | dialog.parentNode.removeChild(dialog);
51 | me.focus();
52 |
53 | if (options.onClose) options.onClose(dialog);
54 | }
55 | }
56 |
57 | var inp = dialog.getElementsByTagName("input")[0], button;
58 | if (inp) {
59 | inp.focus();
60 |
61 | if (options.value) {
62 | inp.value = options.value;
63 | if (options.selectValueOnOpen !== false) {
64 | inp.select();
65 | }
66 | }
67 |
68 | if (options.onInput)
69 | CodeMirror.on(inp, "input", function(e) { options.onInput(e, inp.value, close);});
70 | if (options.onKeyUp)
71 | CodeMirror.on(inp, "keyup", function(e) {options.onKeyUp(e, inp.value, close);});
72 |
73 | CodeMirror.on(inp, "keydown", function(e) {
74 | if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; }
75 | if (e.keyCode == 27 || (options.closeOnEnter !== false && e.keyCode == 13)) {
76 | inp.blur();
77 | CodeMirror.e_stop(e);
78 | close();
79 | }
80 | if (e.keyCode == 13) callback(inp.value, e);
81 | });
82 |
83 | if (options.closeOnBlur !== false) CodeMirror.on(inp, "blur", close);
84 | } else if (button = dialog.getElementsByTagName("button")[0]) {
85 | CodeMirror.on(button, "click", function() {
86 | close();
87 | me.focus();
88 | });
89 |
90 | if (options.closeOnBlur !== false) CodeMirror.on(button, "blur", close);
91 |
92 | button.focus();
93 | }
94 | return close;
95 | });
96 |
97 | CodeMirror.defineExtension("openConfirm", function(template, callbacks, options) {
98 | closeNotification(this, null);
99 | var dialog = dialogDiv(this, template, options && options.bottom);
100 | var buttons = dialog.getElementsByTagName("button");
101 | var closed = false, me = this, blurring = 1;
102 | function close() {
103 | if (closed) return;
104 | closed = true;
105 | dialog.parentNode.removeChild(dialog);
106 | me.focus();
107 | }
108 | buttons[0].focus();
109 | for (var i = 0; i < buttons.length; ++i) {
110 | var b = buttons[i];
111 | (function(callback) {
112 | CodeMirror.on(b, "click", function(e) {
113 | CodeMirror.e_preventDefault(e);
114 | close();
115 | if (callback) callback(me);
116 | });
117 | })(callbacks[i]);
118 | CodeMirror.on(b, "blur", function() {
119 | --blurring;
120 | setTimeout(function() { if (blurring <= 0) close(); }, 200);
121 | });
122 | CodeMirror.on(b, "focus", function() { ++blurring; });
123 | }
124 | });
125 |
126 | /*
127 | * openNotification
128 | * Opens a notification, that can be closed with an optional timer
129 | * (default 5000ms timer) and always closes on click.
130 | *
131 | * If a notification is opened while another is opened, it will close the
132 | * currently opened one and open the new one immediately.
133 | */
134 | CodeMirror.defineExtension("openNotification", function(template, options) {
135 | closeNotification(this, close);
136 | var dialog = dialogDiv(this, template, options && options.bottom);
137 | var closed = false, doneTimer;
138 | var duration = options && typeof options.duration !== "undefined" ? options.duration : 5000;
139 |
140 | function close() {
141 | if (closed) return;
142 | closed = true;
143 | clearTimeout(doneTimer);
144 | dialog.parentNode.removeChild(dialog);
145 | }
146 |
147 | CodeMirror.on(dialog, 'click', function(e) {
148 | CodeMirror.e_preventDefault(e);
149 | close();
150 | });
151 |
152 | if (duration)
153 | doneTimer = setTimeout(close, duration);
154 |
155 | return close;
156 | });
157 | });
158 |
--------------------------------------------------------------------------------
/lib/pane1/javascript.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: http://codemirror.net/LICENSE
3 |
4 | (function(mod) {
5 | if (typeof exports == "object" && typeof module == "object") // CommonJS
6 | mod(require("../../lib/codemirror"));
7 | else if (typeof define == "function" && define.amd) // AMD
8 | define(["../../lib/codemirror"], mod);
9 | else // Plain browser env
10 | mod(CodeMirror);
11 | })(function(CodeMirror) {
12 | "use strict";
13 |
14 | CodeMirror.defineMode("javascript", function(config, parserConfig) {
15 | var indentUnit = config.indentUnit;
16 | var statementIndent = parserConfig.statementIndent;
17 | var jsonldMode = parserConfig.jsonld;
18 | var jsonMode = parserConfig.json || jsonldMode;
19 | var isTS = parserConfig.typescript;
20 | var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/;
21 |
22 | // Tokenizer
23 |
24 | var keywords = function(){
25 | function kw(type) {return {type: type, style: "keyword"};}
26 | var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"), D = kw("keyword d");
27 | var operator = kw("operator"), atom = {type: "atom", style: "atom"};
28 |
29 | return {
30 | "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
31 | "return": D, "break": D, "continue": D, "new": kw("new"), "delete": C, "void": C, "throw": C,
32 | "debugger": kw("debugger"), "var": kw("var"), "const": kw("var"), "let": kw("var"),
33 | "function": kw("function"), "catch": kw("catch"),
34 | "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
35 | "in": operator, "typeof": operator, "instanceof": operator,
36 | "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
37 | "this": kw("this"), "class": kw("class"), "super": kw("atom"),
38 | "yield": C, "export": kw("export"), "import": kw("import"), "extends": C,
39 | "await": C
40 | };
41 | }();
42 |
43 | var isOperatorChar = /[+\-*&%=<>!?|~^@]/;
44 | var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;
45 |
46 | function readRegexp(stream) {
47 | var escaped = false, next, inSet = false;
48 | while ((next = stream.next()) != null) {
49 | if (!escaped) {
50 | if (next == "/" && !inSet) return;
51 | if (next == "[") inSet = true;
52 | else if (inSet && next == "]") inSet = false;
53 | }
54 | escaped = !escaped && next == "\\";
55 | }
56 | }
57 |
58 | // Used as scratch variables to communicate multiple values without
59 | // consing up tons of objects.
60 | var type, content;
61 | function ret(tp, style, cont) {
62 | type = tp; content = cont;
63 | return style;
64 | }
65 | function tokenBase(stream, state) {
66 | var ch = stream.next();
67 | if (ch == '"' || ch == "'") {
68 | state.tokenize = tokenString(ch);
69 | return state.tokenize(stream, state);
70 | } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) {
71 | return ret("number", "number");
72 | } else if (ch == "." && stream.match("..")) {
73 | return ret("spread", "meta");
74 | } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
75 | return ret(ch);
76 | } else if (ch == "=" && stream.eat(">")) {
77 | return ret("=>", "operator");
78 | } else if (ch == "0" && stream.eat(/x/i)) {
79 | stream.eatWhile(/[\da-f]/i);
80 | return ret("number", "number");
81 | } else if (ch == "0" && stream.eat(/o/i)) {
82 | stream.eatWhile(/[0-7]/i);
83 | return ret("number", "number");
84 | } else if (ch == "0" && stream.eat(/b/i)) {
85 | stream.eatWhile(/[01]/i);
86 | return ret("number", "number");
87 | } else if (/\d/.test(ch)) {
88 | stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
89 | return ret("number", "number");
90 | } else if (ch == "/") {
91 | if (stream.eat("*")) {
92 | state.tokenize = tokenComment;
93 | return tokenComment(stream, state);
94 | } else if (stream.eat("/")) {
95 | stream.skipToEnd();
96 | return ret("comment", "comment");
97 | } else if (expressionAllowed(stream, state, 1)) {
98 | readRegexp(stream);
99 | stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
100 | return ret("regexp", "string-2");
101 | } else {
102 | stream.eat("=");
103 | return ret("operator", "operator", stream.current());
104 | }
105 | } else if (ch == "`") {
106 | state.tokenize = tokenQuasi;
107 | return tokenQuasi(stream, state);
108 | } else if (ch == "#") {
109 | stream.skipToEnd();
110 | return ret("error", "error");
111 | } else if (isOperatorChar.test(ch)) {
112 | if (ch != ">" || !state.lexical || state.lexical.type != ">") {
113 | if (stream.eat("=")) {
114 | if (ch == "!" || ch == "=") stream.eat("=")
115 | } else if (/[<>*+\-]/.test(ch)) {
116 | stream.eat(ch)
117 | if (ch == ">") stream.eat(ch)
118 | }
119 | }
120 | return ret("operator", "operator", stream.current());
121 | } else if (wordRE.test(ch)) {
122 | stream.eatWhile(wordRE);
123 | var word = stream.current()
124 | if (state.lastType != ".") {
125 | if (keywords.propertyIsEnumerable(word)) {
126 | var kw = keywords[word]
127 | return ret(kw.type, kw.style, word)
128 | }
129 | if (word == "async" && stream.match(/^(\s|\/\*.*?\*\/)*[\(\w]/, false))
130 | return ret("async", "keyword", word)
131 | }
132 | return ret("variable", "variable", word)
133 | }
134 | }
135 |
136 | function tokenString(quote) {
137 | return function(stream, state) {
138 | var escaped = false, next;
139 | if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){
140 | state.tokenize = tokenBase;
141 | return ret("jsonld-keyword", "meta");
142 | }
143 | while ((next = stream.next()) != null) {
144 | if (next == quote && !escaped) break;
145 | escaped = !escaped && next == "\\";
146 | }
147 | if (!escaped) state.tokenize = tokenBase;
148 | return ret("string", "string");
149 | };
150 | }
151 |
152 | function tokenComment(stream, state) {
153 | var maybeEnd = false, ch;
154 | while (ch = stream.next()) {
155 | if (ch == "/" && maybeEnd) {
156 | state.tokenize = tokenBase;
157 | break;
158 | }
159 | maybeEnd = (ch == "*");
160 | }
161 | return ret("comment", "comment");
162 | }
163 |
164 | function tokenQuasi(stream, state) {
165 | var escaped = false, next;
166 | while ((next = stream.next()) != null) {
167 | if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) {
168 | state.tokenize = tokenBase;
169 | break;
170 | }
171 | escaped = !escaped && next == "\\";
172 | }
173 | return ret("quasi", "string-2", stream.current());
174 | }
175 |
176 | var brackets = "([{}])";
177 | // This is a crude lookahead trick to try and notice that we're
178 | // parsing the argument patterns for a fat-arrow function before we
179 | // actually hit the arrow token. It only works if the arrow is on
180 | // the same line as the arguments and there's no strange noise
181 | // (comments) in between. Fallback is to only notice when we hit the
182 | // arrow, and not declare the arguments as locals for the arrow
183 | // body.
184 | function findFatArrow(stream, state) {
185 | if (state.fatArrowAt) state.fatArrowAt = null;
186 | var arrow = stream.string.indexOf("=>", stream.start);
187 | if (arrow < 0) return;
188 |
189 | if (isTS) { // Try to skip TypeScript return type declarations after the arguments
190 | var m = /:\s*(?:\w+(?:<[^>]*>|\[\])?|\{[^}]*\})\s*$/.exec(stream.string.slice(stream.start, arrow))
191 | if (m) arrow = m.index
192 | }
193 |
194 | var depth = 0, sawSomething = false;
195 | for (var pos = arrow - 1; pos >= 0; --pos) {
196 | var ch = stream.string.charAt(pos);
197 | var bracket = brackets.indexOf(ch);
198 | if (bracket >= 0 && bracket < 3) {
199 | if (!depth) { ++pos; break; }
200 | if (--depth == 0) { if (ch == "(") sawSomething = true; break; }
201 | } else if (bracket >= 3 && bracket < 6) {
202 | ++depth;
203 | } else if (wordRE.test(ch)) {
204 | sawSomething = true;
205 | } else if (/["'\/]/.test(ch)) {
206 | return;
207 | } else if (sawSomething && !depth) {
208 | ++pos;
209 | break;
210 | }
211 | }
212 | if (sawSomething && !depth) state.fatArrowAt = pos;
213 | }
214 |
215 | // Parser
216 |
217 | var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true};
218 |
219 | function JSLexical(indented, column, type, align, prev, info) {
220 | this.indented = indented;
221 | this.column = column;
222 | this.type = type;
223 | this.prev = prev;
224 | this.info = info;
225 | if (align != null) this.align = align;
226 | }
227 |
228 | function inScope(state, varname) {
229 | for (var v = state.localVars; v; v = v.next)
230 | if (v.name == varname) return true;
231 | for (var cx = state.context; cx; cx = cx.prev) {
232 | for (var v = cx.vars; v; v = v.next)
233 | if (v.name == varname) return true;
234 | }
235 | }
236 |
237 | function parseJS(state, style, type, content, stream) {
238 | var cc = state.cc;
239 | // Communicate our context to the combinators.
240 | // (Less wasteful than consing up a hundred closures on every call.)
241 | cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style = style;
242 |
243 | if (!state.lexical.hasOwnProperty("align"))
244 | state.lexical.align = true;
245 |
246 | while(true) {
247 | var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
248 | if (combinator(type, content)) {
249 | while(cc.length && cc[cc.length - 1].lex)
250 | cc.pop()();
251 | if (cx.marked) return cx.marked;
252 | if (type == "variable" && inScope(state, content)) return "variable-2";
253 | return style;
254 | }
255 | }
256 | }
257 |
258 | // Combinator utils
259 |
260 | var cx = {state: null, column: null, marked: null, cc: null};
261 | function pass() {
262 | for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
263 | }
264 | function cont() {
265 | pass.apply(null, arguments);
266 | return true;
267 | }
268 | function register(varname) {
269 | function inList(list) {
270 | for (var v = list; v; v = v.next)
271 | if (v.name == varname) return true;
272 | return false;
273 | }
274 | var state = cx.state;
275 | cx.marked = "def";
276 | if (state.context) {
277 | if (inList(state.localVars)) return;
278 | state.localVars = {name: varname, next: state.localVars};
279 | } else {
280 | if (inList(state.globalVars)) return;
281 | if (parserConfig.globalVars)
282 | state.globalVars = {name: varname, next: state.globalVars};
283 | }
284 | }
285 |
286 | function isModifier(name) {
287 | return name == "public" || name == "private" || name == "protected" || name == "abstract" || name == "readonly"
288 | }
289 |
290 | // Combinators
291 |
292 | var defaultVars = {name: "this", next: {name: "arguments"}};
293 | function pushcontext() {
294 | cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
295 | cx.state.localVars = defaultVars;
296 | }
297 | function popcontext() {
298 | cx.state.localVars = cx.state.context.vars;
299 | cx.state.context = cx.state.context.prev;
300 | }
301 | function pushlex(type, info) {
302 | var result = function() {
303 | var state = cx.state, indent = state.indented;
304 | if (state.lexical.type == "stat") indent = state.lexical.indented;
305 | else for (var outer = state.lexical; outer && outer.type == ")" && outer.align; outer = outer.prev)
306 | indent = outer.indented;
307 | state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info);
308 | };
309 | result.lex = true;
310 | return result;
311 | }
312 | function poplex() {
313 | var state = cx.state;
314 | if (state.lexical.prev) {
315 | if (state.lexical.type == ")")
316 | state.indented = state.lexical.indented;
317 | state.lexical = state.lexical.prev;
318 | }
319 | }
320 | poplex.lex = true;
321 |
322 | function expect(wanted) {
323 | function exp(type) {
324 | if (type == wanted) return cont();
325 | else if (wanted == ";") return pass();
326 | else return cont(exp);
327 | };
328 | return exp;
329 | }
330 |
331 | function statement(type, value) {
332 | if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex);
333 | if (type == "keyword a") return cont(pushlex("form"), parenExpr, statement, poplex);
334 | if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
335 | if (type == "keyword d") return cx.stream.match(/^\s*$/, false) ? cont() : cont(pushlex("stat"), maybeexpression, expect(";"), poplex);
336 | if (type == "debugger") return cont(expect(";"));
337 | if (type == "{") return cont(pushlex("}"), block, poplex);
338 | if (type == ";") return cont();
339 | if (type == "if") {
340 | if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex)
341 | cx.state.cc.pop()();
342 | return cont(pushlex("form"), parenExpr, statement, poplex, maybeelse);
343 | }
344 | if (type == "function") return cont(functiondef);
345 | if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
346 | if (type == "class" || (isTS && value == "interface")) { cx.marked = "keyword"; return cont(pushlex("form"), className, poplex); }
347 | if (type == "variable") {
348 | if (isTS && value == "type") {
349 | cx.marked = "keyword"
350 | return cont(typeexpr, expect("operator"), typeexpr, expect(";"));
351 | } else if (isTS && value == "declare") {
352 | cx.marked = "keyword"
353 | return cont(statement)
354 | } else if (isTS && (value == "module" || value == "enum") && cx.stream.match(/^\s*\w/, false)) {
355 | cx.marked = "keyword"
356 | return cont(pushlex("form"), pattern, expect("{"), pushlex("}"), block, poplex, poplex)
357 | } else if (isTS && value == "namespace") {
358 | cx.marked = "keyword"
359 | return cont(pushlex("form"), expression, block, poplex)
360 | } else {
361 | return cont(pushlex("stat"), maybelabel);
362 | }
363 | }
364 | if (type == "switch") return cont(pushlex("form"), parenExpr, expect("{"), pushlex("}", "switch"),
365 | block, poplex, poplex);
366 | if (type == "case") return cont(expression, expect(":"));
367 | if (type == "default") return cont(expect(":"));
368 | if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
369 | statement, poplex, popcontext);
370 | if (type == "export") return cont(pushlex("stat"), afterExport, poplex);
371 | if (type == "import") return cont(pushlex("stat"), afterImport, poplex);
372 | if (type == "async") return cont(statement)
373 | if (value == "@") return cont(expression, statement)
374 | return pass(pushlex("stat"), expression, expect(";"), poplex);
375 | }
376 | function expression(type, value) {
377 | return expressionInner(type, value, false);
378 | }
379 | function expressionNoComma(type, value) {
380 | return expressionInner(type, value, true);
381 | }
382 | function parenExpr(type) {
383 | if (type != "(") return pass()
384 | return cont(pushlex(")"), expression, expect(")"), poplex)
385 | }
386 | function expressionInner(type, value, noComma) {
387 | if (cx.state.fatArrowAt == cx.stream.start) {
388 | var body = noComma ? arrowBodyNoComma : arrowBody;
389 | if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, expect("=>"), body, popcontext);
390 | else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
391 | }
392 |
393 | var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
394 | if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
395 | if (type == "function") return cont(functiondef, maybeop);
396 | if (type == "class" || (isTS && value == "interface")) { cx.marked = "keyword"; return cont(pushlex("form"), classExpression, poplex); }
397 | if (type == "keyword c" || type == "async") return cont(noComma ? expressionNoComma : expression);
398 | if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop);
399 | if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
400 | if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
401 | if (type == "{") return contCommasep(objprop, "}", null, maybeop);
402 | if (type == "quasi") return pass(quasi, maybeop);
403 | if (type == "new") return cont(maybeTarget(noComma));
404 | return cont();
405 | }
406 | function maybeexpression(type) {
407 | if (type.match(/[;\}\)\],]/)) return pass();
408 | return pass(expression);
409 | }
410 |
411 | function maybeoperatorComma(type, value) {
412 | if (type == ",") return cont(expression);
413 | return maybeoperatorNoComma(type, value, false);
414 | }
415 | function maybeoperatorNoComma(type, value, noComma) {
416 | var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
417 | var expr = noComma == false ? expression : expressionNoComma;
418 | if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
419 | if (type == "operator") {
420 | if (/\+\+|--/.test(value) || isTS && value == "!") return cont(me);
421 | if (isTS && value == "<" && cx.stream.match(/^([^>]|<.*?>)*>\s*\(/, false))
422 | return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, me);
423 | if (value == "?") return cont(expression, expect(":"), expr);
424 | return cont(expr);
425 | }
426 | if (type == "quasi") { return pass(quasi, me); }
427 | if (type == ";") return;
428 | if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
429 | if (type == ".") return cont(property, me);
430 | if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
431 | if (isTS && value == "as") { cx.marked = "keyword"; return cont(typeexpr, me) }
432 | if (type == "regexp") {
433 | cx.state.lastType = cx.marked = "operator"
434 | cx.stream.backUp(cx.stream.pos - cx.stream.start - 1)
435 | return cont(expr)
436 | }
437 | }
438 | function quasi(type, value) {
439 | if (type != "quasi") return pass();
440 | if (value.slice(value.length - 2) != "${") return cont(quasi);
441 | return cont(expression, continueQuasi);
442 | }
443 | function continueQuasi(type) {
444 | if (type == "}") {
445 | cx.marked = "string-2";
446 | cx.state.tokenize = tokenQuasi;
447 | return cont(quasi);
448 | }
449 | }
450 | function arrowBody(type) {
451 | findFatArrow(cx.stream, cx.state);
452 | return pass(type == "{" ? statement : expression);
453 | }
454 | function arrowBodyNoComma(type) {
455 | findFatArrow(cx.stream, cx.state);
456 | return pass(type == "{" ? statement : expressionNoComma);
457 | }
458 | function maybeTarget(noComma) {
459 | return function(type) {
460 | if (type == ".") return cont(noComma ? targetNoComma : target);
461 | else if (type == "variable" && isTS) return cont(maybeTypeArgs, noComma ? maybeoperatorNoComma : maybeoperatorComma)
462 | else return pass(noComma ? expressionNoComma : expression);
463 | };
464 | }
465 | function target(_, value) {
466 | if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorComma); }
467 | }
468 | function targetNoComma(_, value) {
469 | if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorNoComma); }
470 | }
471 | function maybelabel(type) {
472 | if (type == ":") return cont(poplex, statement);
473 | return pass(maybeoperatorComma, expect(";"), poplex);
474 | }
475 | function property(type) {
476 | if (type == "variable") {cx.marked = "property"; return cont();}
477 | }
478 | function objprop(type, value) {
479 | if (type == "async") {
480 | cx.marked = "property";
481 | return cont(objprop);
482 | } else if (type == "variable" || cx.style == "keyword") {
483 | cx.marked = "property";
484 | if (value == "get" || value == "set") return cont(getterSetter);
485 | var m // Work around fat-arrow-detection complication for detecting typescript typed arrow params
486 | if (isTS && cx.state.fatArrowAt == cx.stream.start && (m = cx.stream.match(/^\s*:\s*/, false)))
487 | cx.state.fatArrowAt = cx.stream.pos + m[0].length
488 | return cont(afterprop);
489 | } else if (type == "number" || type == "string") {
490 | cx.marked = jsonldMode ? "property" : (cx.style + " property");
491 | return cont(afterprop);
492 | } else if (type == "jsonld-keyword") {
493 | return cont(afterprop);
494 | } else if (isTS && isModifier(value)) {
495 | cx.marked = "keyword"
496 | return cont(objprop)
497 | } else if (type == "[") {
498 | return cont(expression, maybetype, expect("]"), afterprop);
499 | } else if (type == "spread") {
500 | return cont(expressionNoComma, afterprop);
501 | } else if (value == "*") {
502 | cx.marked = "keyword";
503 | return cont(objprop);
504 | } else if (type == ":") {
505 | return pass(afterprop)
506 | }
507 | }
508 | function getterSetter(type) {
509 | if (type != "variable") return pass(afterprop);
510 | cx.marked = "property";
511 | return cont(functiondef);
512 | }
513 | function afterprop(type) {
514 | if (type == ":") return cont(expressionNoComma);
515 | if (type == "(") return pass(functiondef);
516 | }
517 | function commasep(what, end, sep) {
518 | function proceed(type, value) {
519 | if (sep ? sep.indexOf(type) > -1 : type == ",") {
520 | var lex = cx.state.lexical;
521 | if (lex.info == "call") lex.pos = (lex.pos || 0) + 1;
522 | return cont(function(type, value) {
523 | if (type == end || value == end) return pass()
524 | return pass(what)
525 | }, proceed);
526 | }
527 | if (type == end || value == end) return cont();
528 | return cont(expect(end));
529 | }
530 | return function(type, value) {
531 | if (type == end || value == end) return cont();
532 | return pass(what, proceed);
533 | };
534 | }
535 | function contCommasep(what, end, info) {
536 | for (var i = 3; i < arguments.length; i++)
537 | cx.cc.push(arguments[i]);
538 | return cont(pushlex(end, info), commasep(what, end), poplex);
539 | }
540 | function block(type) {
541 | if (type == "}") return cont();
542 | return pass(statement, block);
543 | }
544 | function maybetype(type, value) {
545 | if (isTS) {
546 | if (type == ":") return cont(typeexpr);
547 | if (value == "?") return cont(maybetype);
548 | }
549 | }
550 | function mayberettype(type) {
551 | if (isTS && type == ":") {
552 | if (cx.stream.match(/^\s*\w+\s+is\b/, false)) return cont(expression, isKW, typeexpr)
553 | else return cont(typeexpr)
554 | }
555 | }
556 | function isKW(_, value) {
557 | if (value == "is") {
558 | cx.marked = "keyword"
559 | return cont()
560 | }
561 | }
562 | function typeexpr(type, value) {
563 | if (type == "variable" || value == "void") {
564 | if (value == "keyof") {
565 | cx.marked = "keyword"
566 | return cont(typeexpr)
567 | } else {
568 | cx.marked = "type"
569 | return cont(afterType)
570 | }
571 | }
572 | if (type == "string" || type == "number" || type == "atom") return cont(afterType);
573 | if (type == "[") return cont(pushlex("]"), commasep(typeexpr, "]", ","), poplex, afterType)
574 | if (type == "{") return cont(pushlex("}"), commasep(typeprop, "}", ",;"), poplex, afterType)
575 | if (type == "(") return cont(commasep(typearg, ")"), maybeReturnType)
576 | }
577 | function maybeReturnType(type) {
578 | if (type == "=>") return cont(typeexpr)
579 | }
580 | function typeprop(type, value) {
581 | if (type == "variable" || cx.style == "keyword") {
582 | cx.marked = "property"
583 | return cont(typeprop)
584 | } else if (value == "?") {
585 | return cont(typeprop)
586 | } else if (type == ":") {
587 | return cont(typeexpr)
588 | } else if (type == "[") {
589 | return cont(expression, maybetype, expect("]"), typeprop)
590 | }
591 | }
592 | function typearg(type) {
593 | if (type == "variable") return cont(typearg)
594 | else if (type == ":") return cont(typeexpr)
595 | }
596 | function afterType(type, value) {
597 | if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType)
598 | if (value == "|" || type == ".") return cont(typeexpr)
599 | if (type == "[") return cont(expect("]"), afterType)
600 | if (value == "extends" || value == "implements") { cx.marked = "keyword"; return cont(typeexpr) }
601 | }
602 | function maybeTypeArgs(_, value) {
603 | if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType)
604 | }
605 | function typeparam() {
606 | return pass(typeexpr, maybeTypeDefault)
607 | }
608 | function maybeTypeDefault(_, value) {
609 | if (value == "=") return cont(typeexpr)
610 | }
611 | function vardef() {
612 | return pass(pattern, maybetype, maybeAssign, vardefCont);
613 | }
614 | function pattern(type, value) {
615 | if (isTS && isModifier(value)) { cx.marked = "keyword"; return cont(pattern) }
616 | if (type == "variable") { register(value); return cont(); }
617 | if (type == "spread") return cont(pattern);
618 | if (type == "[") return contCommasep(pattern, "]");
619 | if (type == "{") return contCommasep(proppattern, "}");
620 | }
621 | function proppattern(type, value) {
622 | if (type == "variable" && !cx.stream.match(/^\s*:/, false)) {
623 | register(value);
624 | return cont(maybeAssign);
625 | }
626 | if (type == "variable") cx.marked = "property";
627 | if (type == "spread") return cont(pattern);
628 | if (type == "}") return pass();
629 | return cont(expect(":"), pattern, maybeAssign);
630 | }
631 | function maybeAssign(_type, value) {
632 | if (value == "=") return cont(expressionNoComma);
633 | }
634 | function vardefCont(type) {
635 | if (type == ",") return cont(vardef);
636 | }
637 | function maybeelse(type, value) {
638 | if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex);
639 | }
640 | function forspec(type) {
641 | if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex);
642 | }
643 | function forspec1(type) {
644 | if (type == "var") return cont(vardef, expect(";"), forspec2);
645 | if (type == ";") return cont(forspec2);
646 | if (type == "variable") return cont(formaybeinof);
647 | return pass(expression, expect(";"), forspec2);
648 | }
649 | function formaybeinof(_type, value) {
650 | if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
651 | return cont(maybeoperatorComma, forspec2);
652 | }
653 | function forspec2(type, value) {
654 | if (type == ";") return cont(forspec3);
655 | if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
656 | return pass(expression, expect(";"), forspec3);
657 | }
658 | function forspec3(type) {
659 | if (type != ")") cont(expression);
660 | }
661 | function functiondef(type, value) {
662 | if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
663 | if (type == "variable") {register(value); return cont(functiondef);}
664 | if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, mayberettype, statement, popcontext);
665 | if (isTS && value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, functiondef)
666 | }
667 | function funarg(type, value) {
668 | if (value == "@") cont(expression, funarg)
669 | if (type == "spread") return cont(funarg);
670 | if (isTS && isModifier(value)) { cx.marked = "keyword"; return cont(funarg); }
671 | return pass(pattern, maybetype, maybeAssign);
672 | }
673 | function classExpression(type, value) {
674 | // Class expressions may have an optional name.
675 | if (type == "variable") return className(type, value);
676 | return classNameAfter(type, value);
677 | }
678 | function className(type, value) {
679 | if (type == "variable") {register(value); return cont(classNameAfter);}
680 | }
681 | function classNameAfter(type, value) {
682 | if (value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, classNameAfter)
683 | if (value == "extends" || value == "implements" || (isTS && type == ","))
684 | return cont(isTS ? typeexpr : expression, classNameAfter);
685 | if (type == "{") return cont(pushlex("}"), classBody, poplex);
686 | }
687 | function classBody(type, value) {
688 | if (type == "async" ||
689 | (type == "variable" &&
690 | (value == "static" || value == "get" || value == "set" || (isTS && isModifier(value))) &&
691 | cx.stream.match(/^\s+[\w$\xa1-\uffff]/, false))) {
692 | cx.marked = "keyword";
693 | return cont(classBody);
694 | }
695 | if (type == "variable" || cx.style == "keyword") {
696 | cx.marked = "property";
697 | return cont(isTS ? classfield : functiondef, classBody);
698 | }
699 | if (type == "[")
700 | return cont(expression, maybetype, expect("]"), isTS ? classfield : functiondef, classBody)
701 | if (value == "*") {
702 | cx.marked = "keyword";
703 | return cont(classBody);
704 | }
705 | if (type == ";") return cont(classBody);
706 | if (type == "}") return cont();
707 | if (value == "@") return cont(expression, classBody)
708 | }
709 | function classfield(type, value) {
710 | if (value == "?") return cont(classfield)
711 | if (type == ":") return cont(typeexpr, maybeAssign)
712 | if (value == "=") return cont(expressionNoComma)
713 | return pass(functiondef)
714 | }
715 | function afterExport(type, value) {
716 | if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
717 | if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
718 | if (type == "{") return cont(commasep(exportField, "}"), maybeFrom, expect(";"));
719 | return pass(statement);
720 | }
721 | function exportField(type, value) {
722 | if (value == "as") { cx.marked = "keyword"; return cont(expect("variable")); }
723 | if (type == "variable") return pass(expressionNoComma, exportField);
724 | }
725 | function afterImport(type) {
726 | if (type == "string") return cont();
727 | return pass(importSpec, maybeMoreImports, maybeFrom);
728 | }
729 | function importSpec(type, value) {
730 | if (type == "{") return contCommasep(importSpec, "}");
731 | if (type == "variable") register(value);
732 | if (value == "*") cx.marked = "keyword";
733 | return cont(maybeAs);
734 | }
735 | function maybeMoreImports(type) {
736 | if (type == ",") return cont(importSpec, maybeMoreImports)
737 | }
738 | function maybeAs(_type, value) {
739 | if (value == "as") { cx.marked = "keyword"; return cont(importSpec); }
740 | }
741 | function maybeFrom(_type, value) {
742 | if (value == "from") { cx.marked = "keyword"; return cont(expression); }
743 | }
744 | function arrayLiteral(type) {
745 | if (type == "]") return cont();
746 | return pass(commasep(expressionNoComma, "]"));
747 | }
748 |
749 | function isContinuedStatement(state, textAfter) {
750 | return state.lastType == "operator" || state.lastType == "," ||
751 | isOperatorChar.test(textAfter.charAt(0)) ||
752 | /[,.]/.test(textAfter.charAt(0));
753 | }
754 |
755 | function expressionAllowed(stream, state, backUp) {
756 | return state.tokenize == tokenBase &&
757 | /^(?:operator|sof|keyword [bcd]|case|new|export|default|spread|[\[{}\(,;:]|=>)$/.test(state.lastType) ||
758 | (state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0))))
759 | }
760 |
761 | // Interface
762 |
763 | return {
764 | startState: function(basecolumn) {
765 | var state = {
766 | tokenize: tokenBase,
767 | lastType: "sof",
768 | cc: [],
769 | lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
770 | localVars: parserConfig.localVars,
771 | context: parserConfig.localVars && {vars: parserConfig.localVars},
772 | indented: basecolumn || 0
773 | };
774 | if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
775 | state.globalVars = parserConfig.globalVars;
776 | return state;
777 | },
778 |
779 | token: function(stream, state) {
780 | if (stream.sol()) {
781 | if (!state.lexical.hasOwnProperty("align"))
782 | state.lexical.align = false;
783 | state.indented = stream.indentation();
784 | findFatArrow(stream, state);
785 | }
786 | if (state.tokenize != tokenComment && stream.eatSpace()) return null;
787 | var style = state.tokenize(stream, state);
788 | if (type == "comment") return style;
789 | state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type;
790 | return parseJS(state, style, type, content, stream);
791 | },
792 |
793 | indent: function(state, textAfter) {
794 | if (state.tokenize == tokenComment) return CodeMirror.Pass;
795 | if (state.tokenize != tokenBase) return 0;
796 | var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical, top
797 | // Kludge to prevent 'maybelse' from blocking lexical scope pops
798 | if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) {
799 | var c = state.cc[i];
800 | if (c == poplex) lexical = lexical.prev;
801 | else if (c != maybeelse) break;
802 | }
803 | while ((lexical.type == "stat" || lexical.type == "form") &&
804 | (firstChar == "}" || ((top = state.cc[state.cc.length - 1]) &&
805 | (top == maybeoperatorComma || top == maybeoperatorNoComma) &&
806 | !/^[,\.=+\-*:?[\(]/.test(textAfter))))
807 | lexical = lexical.prev;
808 | if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
809 | lexical = lexical.prev;
810 | var type = lexical.type, closing = firstChar == type;
811 |
812 | if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0);
813 | else if (type == "form" && firstChar == "{") return lexical.indented;
814 | else if (type == "form") return lexical.indented + indentUnit;
815 | else if (type == "stat")
816 | return lexical.indented + (isContinuedStatement(state, textAfter) ? statementIndent || indentUnit : 0);
817 | else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false)
818 | return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
819 | else if (lexical.align) return lexical.column + (closing ? 0 : 1);
820 | else return lexical.indented + (closing ? 0 : indentUnit);
821 | },
822 |
823 | electricInput: /^\s*(?:case .*?:|default:|\{|\})$/,
824 | blockCommentStart: jsonMode ? null : "/*",
825 | blockCommentEnd: jsonMode ? null : "*/",
826 | blockCommentContinue: jsonMode ? null : " * ",
827 | lineComment: jsonMode ? null : "//",
828 | fold: "brace",
829 | closeBrackets: "()[]{}''\"\"``",
830 |
831 | helperType: jsonMode ? "json" : "javascript",
832 | jsonldMode: jsonldMode,
833 | jsonMode: jsonMode,
834 |
835 | expressionAllowed: expressionAllowed,
836 |
837 | skipExpression: function(state) {
838 | var top = state.cc[state.cc.length - 1]
839 | if (top == expression || top == expressionNoComma) state.cc.pop()
840 | }
841 | };
842 | });
843 |
844 | CodeMirror.registerHelper("wordChars", "javascript", /[\w$]/);
845 |
846 | CodeMirror.defineMIME("text/javascript", "javascript");
847 | CodeMirror.defineMIME("text/ecmascript", "javascript");
848 | CodeMirror.defineMIME("application/javascript", "javascript");
849 | CodeMirror.defineMIME("application/x-javascript", "javascript");
850 | CodeMirror.defineMIME("application/ecmascript", "javascript");
851 | CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
852 | CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true});
853 | CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true});
854 | CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
855 | CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });
856 |
857 | });
858 |
--------------------------------------------------------------------------------
/lib/pane1/matchbrackets.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: http://codemirror.net/LICENSE
3 |
4 | (function(mod) {
5 | if (typeof exports == "object" && typeof module == "object") // CommonJS
6 | mod(require("../../lib/codemirror"));
7 | else if (typeof define == "function" && define.amd) // AMD
8 | define(["../../lib/codemirror"], mod);
9 | else // Plain browser env
10 | mod(CodeMirror);
11 | })(function(CodeMirror) {
12 | var ie_lt8 = /MSIE \d/.test(navigator.userAgent) &&
13 | (document.documentMode == null || document.documentMode < 8);
14 |
15 | var Pos = CodeMirror.Pos;
16 |
17 | var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"};
18 |
19 | function findMatchingBracket(cm, where, config) {
20 | var line = cm.getLineHandle(where.line), pos = where.ch - 1;
21 | var afterCursor = config && config.afterCursor
22 | if (afterCursor == null)
23 | afterCursor = /(^| )cm-fat-cursor($| )/.test(cm.getWrapperElement().className)
24 |
25 | // A cursor is defined as between two characters, but in in vim command mode
26 | // (i.e. not insert mode), the cursor is visually represented as a
27 | // highlighted box on top of the 2nd character. Otherwise, we allow matches
28 | // from before or after the cursor.
29 | var match = (!afterCursor && pos >= 0 && matching[line.text.charAt(pos)]) ||
30 | matching[line.text.charAt(++pos)];
31 | if (!match) return null;
32 | var dir = match.charAt(1) == ">" ? 1 : -1;
33 | if (config && config.strict && (dir > 0) != (pos == where.ch)) return null;
34 | var style = cm.getTokenTypeAt(Pos(where.line, pos + 1));
35 |
36 | var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config);
37 | if (found == null) return null;
38 | return {from: Pos(where.line, pos), to: found && found.pos,
39 | match: found && found.ch == match.charAt(0), forward: dir > 0};
40 | }
41 |
42 | // bracketRegex is used to specify which type of bracket to scan
43 | // should be a regexp, e.g. /[[\]]/
44 | //
45 | // Note: If "where" is on an open bracket, then this bracket is ignored.
46 | //
47 | // Returns false when no bracket was found, null when it reached
48 | // maxScanLines and gave up
49 | function scanForBracket(cm, where, dir, style, config) {
50 | var maxScanLen = (config && config.maxScanLineLength) || 10000;
51 | var maxScanLines = (config && config.maxScanLines) || 1000;
52 |
53 | var stack = [];
54 | var re = config && config.bracketRegex ? config.bracketRegex : /[(){}[\]]/;
55 | var lineEnd = dir > 0 ? Math.min(where.line + maxScanLines, cm.lastLine() + 1)
56 | : Math.max(cm.firstLine() - 1, where.line - maxScanLines);
57 | for (var lineNo = where.line; lineNo != lineEnd; lineNo += dir) {
58 | var line = cm.getLine(lineNo);
59 | if (!line) continue;
60 | var pos = dir > 0 ? 0 : line.length - 1, end = dir > 0 ? line.length : -1;
61 | if (line.length > maxScanLen) continue;
62 | if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0);
63 | for (; pos != end; pos += dir) {
64 | var ch = line.charAt(pos);
65 | if (re.test(ch) && (style === undefined || cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style)) {
66 | var match = matching[ch];
67 | if ((match.charAt(1) == ">") == (dir > 0)) stack.push(ch);
68 | else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch};
69 | else stack.pop();
70 | }
71 | }
72 | }
73 | return lineNo - dir == (dir > 0 ? cm.lastLine() : cm.firstLine()) ? false : null;
74 | }
75 |
76 | function matchBrackets(cm, autoclear, config) {
77 | // Disable brace matching in long lines, since it'll cause hugely slow updates
78 | var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000;
79 | var marks = [], ranges = cm.listSelections();
80 | for (var i = 0; i < ranges.length; i++) {
81 | var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, config);
82 | if (match && cm.getLine(match.from.line).length <= maxHighlightLen) {
83 | var style = match.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket";
84 | marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style}));
85 | if (match.to && cm.getLine(match.to.line).length <= maxHighlightLen)
86 | marks.push(cm.markText(match.to, Pos(match.to.line, match.to.ch + 1), {className: style}));
87 | }
88 | }
89 |
90 | if (marks.length) {
91 | // Kludge to work around the IE bug from issue #1193, where text
92 | // input stops going to the textare whever this fires.
93 | if (ie_lt8 && cm.state.focused) cm.focus();
94 |
95 | var clear = function() {
96 | cm.operation(function() {
97 | for (var i = 0; i < marks.length; i++) marks[i].clear();
98 | });
99 | };
100 | if (autoclear) setTimeout(clear, 800);
101 | else return clear;
102 | }
103 | }
104 |
105 | var currentlyHighlighted = null;
106 | function doMatchBrackets(cm) {
107 | cm.operation(function() {
108 | if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;}
109 | currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets);
110 | });
111 | }
112 |
113 | CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) {
114 | if (old && old != CodeMirror.Init) {
115 | cm.off("cursorActivity", doMatchBrackets);
116 | if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;}
117 | }
118 | if (val) {
119 | cm.state.matchBrackets = typeof val == "object" ? val : {};
120 | cm.on("cursorActivity", doMatchBrackets);
121 | }
122 | });
123 |
124 | CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);});
125 | CodeMirror.defineExtension("findMatchingBracket", function(pos, config, oldConfig){
126 | // Backwards-compatibility kludge
127 | if (oldConfig || typeof config == "boolean") {
128 | if (!oldConfig) {
129 | config = config ? {strict: true} : null
130 | } else {
131 | oldConfig.strict = config
132 | config = oldConfig
133 | }
134 | }
135 | return findMatchingBracket(this, pos, config)
136 | });
137 | CodeMirror.defineExtension("scanForBracket", function(pos, dir, style, config){
138 | return scanForBracket(this, pos, dir, style, config);
139 | });
140 | });
141 |
--------------------------------------------------------------------------------
/lib/pane1/python.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: http://codemirror.net/LICENSE
3 |
4 | (function(mod) {
5 | if (typeof exports == "object" && typeof module == "object") // CommonJS
6 | mod(require("../../lib/codemirror"));
7 | else if (typeof define == "function" && define.amd) // AMD
8 | define(["../../lib/codemirror"], mod);
9 | else // Plain browser env
10 | mod(CodeMirror);
11 | })(function(CodeMirror) {
12 | "use strict";
13 |
14 | function wordRegexp(words) {
15 | return new RegExp("^((" + words.join(")|(") + "))\\b");
16 | }
17 |
18 | var wordOperators = wordRegexp(["and", "or", "not", "is"]);
19 | var commonKeywords = ["as", "assert", "break", "class", "continue",
20 | "def", "del", "elif", "else", "except", "finally",
21 | "for", "from", "global", "if", "import",
22 | "lambda", "pass", "raise", "return",
23 | "try", "while", "with", "yield", "in"];
24 | var commonBuiltins = ["abs", "all", "any", "bin", "bool", "bytearray", "callable", "chr",
25 | "classmethod", "compile", "complex", "delattr", "dict", "dir", "divmod",
26 | "enumerate", "eval", "filter", "float", "format", "frozenset",
27 | "getattr", "globals", "hasattr", "hash", "help", "hex", "id",
28 | "input", "int", "isinstance", "issubclass", "iter", "len",
29 | "list", "locals", "map", "max", "memoryview", "min", "next",
30 | "object", "oct", "open", "ord", "pow", "property", "range",
31 | "repr", "reversed", "round", "set", "setattr", "slice",
32 | "sorted", "staticmethod", "str", "sum", "super", "tuple",
33 | "type", "vars", "zip", "__import__", "NotImplemented",
34 | "Ellipsis", "__debug__"];
35 | CodeMirror.registerHelper("hintWords", "python", commonKeywords.concat(commonBuiltins));
36 |
37 | function top(state) {
38 | return state.scopes[state.scopes.length - 1];
39 | }
40 |
41 | CodeMirror.defineMode("python", function(conf, parserConf) {
42 | var ERRORCLASS = "error";
43 |
44 | var delimiters = parserConf.delimiters || parserConf.singleDelimiters || /^[\(\)\[\]\{\}@,:`=;\.]/;
45 | // (Backwards-compatiblity with old, cumbersome config system)
46 | var operators = [parserConf.singleOperators, parserConf.doubleOperators, parserConf.doubleDelimiters, parserConf.tripleDelimiters,
47 | parserConf.operators || /^([-+*/%\/&|^]=?|[<>=]+|\/\/=?|\*\*=?|!=|[~!@])/]
48 | for (var i = 0; i < operators.length; i++) if (!operators[i]) operators.splice(i--, 1)
49 |
50 | var hangingIndent = parserConf.hangingIndent || conf.indentUnit;
51 |
52 | var myKeywords = commonKeywords, myBuiltins = commonBuiltins;
53 | if (parserConf.extra_keywords != undefined)
54 | myKeywords = myKeywords.concat(parserConf.extra_keywords);
55 |
56 | if (parserConf.extra_builtins != undefined)
57 | myBuiltins = myBuiltins.concat(parserConf.extra_builtins);
58 |
59 | var py3 = !(parserConf.version && Number(parserConf.version) < 3)
60 | if (py3) {
61 | // since http://legacy.python.org/dev/peps/pep-0465/ @ is also an operator
62 | var identifiers = parserConf.identifiers|| /^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*/;
63 | myKeywords = myKeywords.concat(["nonlocal", "False", "True", "None", "async", "await"]);
64 | myBuiltins = myBuiltins.concat(["ascii", "bytes", "exec", "print"]);
65 | var stringPrefixes = new RegExp("^(([rbuf]|(br))?('{3}|\"{3}|['\"]))", "i");
66 | } else {
67 | var identifiers = parserConf.identifiers|| /^[_A-Za-z][_A-Za-z0-9]*/;
68 | myKeywords = myKeywords.concat(["exec", "print"]);
69 | myBuiltins = myBuiltins.concat(["apply", "basestring", "buffer", "cmp", "coerce", "execfile",
70 | "file", "intern", "long", "raw_input", "reduce", "reload",
71 | "unichr", "unicode", "xrange", "False", "True", "None"]);
72 | var stringPrefixes = new RegExp("^(([rubf]|(ur)|(br))?('{3}|\"{3}|['\"]))", "i");
73 | }
74 | var keywords = wordRegexp(myKeywords);
75 | var builtins = wordRegexp(myBuiltins);
76 |
77 | // tokenizers
78 | function tokenBase(stream, state) {
79 | if (stream.sol()) state.indent = stream.indentation()
80 | // Handle scope changes
81 | if (stream.sol() && top(state).type == "py") {
82 | var scopeOffset = top(state).offset;
83 | if (stream.eatSpace()) {
84 | var lineOffset = stream.indentation();
85 | if (lineOffset > scopeOffset)
86 | pushPyScope(state);
87 | else if (lineOffset < scopeOffset && dedent(stream, state) && stream.peek() != "#")
88 | state.errorToken = true;
89 | return null;
90 | } else {
91 | var style = tokenBaseInner(stream, state);
92 | if (scopeOffset > 0 && dedent(stream, state))
93 | style += " " + ERRORCLASS;
94 | return style;
95 | }
96 | }
97 | return tokenBaseInner(stream, state);
98 | }
99 |
100 | function tokenBaseInner(stream, state) {
101 | if (stream.eatSpace()) return null;
102 |
103 | var ch = stream.peek();
104 |
105 | // Handle Comments
106 | if (ch == "#") {
107 | stream.skipToEnd();
108 | return "comment";
109 | }
110 |
111 | // Handle Number Literals
112 | if (stream.match(/^[0-9\.]/, false)) {
113 | var floatLiteral = false;
114 | // Floats
115 | if (stream.match(/^[\d_]*\.\d+(e[\+\-]?\d+)?/i)) { floatLiteral = true; }
116 | if (stream.match(/^[\d_]+\.\d*/)) { floatLiteral = true; }
117 | if (stream.match(/^\.\d+/)) { floatLiteral = true; }
118 | if (floatLiteral) {
119 | // Float literals may be "imaginary"
120 | stream.eat(/J/i);
121 | return "number";
122 | }
123 | // Integers
124 | var intLiteral = false;
125 | // Hex
126 | if (stream.match(/^0x[0-9a-f_]+/i)) intLiteral = true;
127 | // Binary
128 | if (stream.match(/^0b[01_]+/i)) intLiteral = true;
129 | // Octal
130 | if (stream.match(/^0o[0-7_]+/i)) intLiteral = true;
131 | // Decimal
132 | if (stream.match(/^[1-9][\d_]*(e[\+\-]?[\d_]+)?/)) {
133 | // Decimal literals may be "imaginary"
134 | stream.eat(/J/i);
135 | // TODO - Can you have imaginary longs?
136 | intLiteral = true;
137 | }
138 | // Zero by itself with no other piece of number.
139 | if (stream.match(/^0(?![\dx])/i)) intLiteral = true;
140 | if (intLiteral) {
141 | // Integer literals may be "long"
142 | stream.eat(/L/i);
143 | return "number";
144 | }
145 | }
146 |
147 | // Handle Strings
148 | if (stream.match(stringPrefixes)) {
149 | state.tokenize = tokenStringFactory(stream.current());
150 | return state.tokenize(stream, state);
151 | }
152 |
153 | for (var i = 0; i < operators.length; i++)
154 | if (stream.match(operators[i])) return "operator"
155 |
156 | if (stream.match(delimiters)) return "punctuation";
157 |
158 | if (state.lastToken == "." && stream.match(identifiers))
159 | return "property";
160 |
161 | if (stream.match(keywords) || stream.match(wordOperators))
162 | return "keyword";
163 |
164 | if (stream.match(builtins))
165 | return "builtin";
166 |
167 | if (stream.match(/^(self|cls)\b/))
168 | return "variable-2";
169 |
170 | if (stream.match(identifiers)) {
171 | if (state.lastToken == "def" || state.lastToken == "class")
172 | return "def";
173 | return "variable";
174 | }
175 |
176 | // Handle non-detected items
177 | stream.next();
178 | return ERRORCLASS;
179 | }
180 |
181 | function tokenStringFactory(delimiter) {
182 | while ("rubf".indexOf(delimiter.charAt(0).toLowerCase()) >= 0)
183 | delimiter = delimiter.substr(1);
184 |
185 | var singleline = delimiter.length == 1;
186 | var OUTCLASS = "string";
187 |
188 | function tokenString(stream, state) {
189 | while (!stream.eol()) {
190 | stream.eatWhile(/[^'"\\]/);
191 | if (stream.eat("\\")) {
192 | stream.next();
193 | if (singleline && stream.eol())
194 | return OUTCLASS;
195 | } else if (stream.match(delimiter)) {
196 | state.tokenize = tokenBase;
197 | return OUTCLASS;
198 | } else {
199 | stream.eat(/['"]/);
200 | }
201 | }
202 | if (singleline) {
203 | if (parserConf.singleLineStringErrors)
204 | return ERRORCLASS;
205 | else
206 | state.tokenize = tokenBase;
207 | }
208 | return OUTCLASS;
209 | }
210 | tokenString.isString = true;
211 | return tokenString;
212 | }
213 |
214 | function pushPyScope(state) {
215 | while (top(state).type != "py") state.scopes.pop()
216 | state.scopes.push({offset: top(state).offset + conf.indentUnit,
217 | type: "py",
218 | align: null})
219 | }
220 |
221 | function pushBracketScope(stream, state, type) {
222 | var align = stream.match(/^([\s\[\{\(]|#.*)*$/, false) ? null : stream.column() + 1
223 | state.scopes.push({offset: state.indent + hangingIndent,
224 | type: type,
225 | align: align})
226 | }
227 |
228 | function dedent(stream, state) {
229 | var indented = stream.indentation();
230 | while (state.scopes.length > 1 && top(state).offset > indented) {
231 | if (top(state).type != "py") return true;
232 | state.scopes.pop();
233 | }
234 | return top(state).offset != indented;
235 | }
236 |
237 | function tokenLexer(stream, state) {
238 | if (stream.sol()) state.beginningOfLine = true;
239 |
240 | var style = state.tokenize(stream, state);
241 | var current = stream.current();
242 |
243 | // Handle decorators
244 | if (state.beginningOfLine && current == "@")
245 | return stream.match(identifiers, false) ? "meta" : py3 ? "operator" : ERRORCLASS;
246 |
247 | if (/\S/.test(current)) state.beginningOfLine = false;
248 |
249 | if ((style == "variable" || style == "builtin")
250 | && state.lastToken == "meta")
251 | style = "meta";
252 |
253 | // Handle scope changes.
254 | if (current == "pass" || current == "return")
255 | state.dedent += 1;
256 |
257 | if (current == "lambda") state.lambda = true;
258 | if (current == ":" && !state.lambda && top(state).type == "py")
259 | pushPyScope(state);
260 |
261 | var delimiter_index = current.length == 1 ? "[({".indexOf(current) : -1;
262 | if (delimiter_index != -1)
263 | pushBracketScope(stream, state, "])}".slice(delimiter_index, delimiter_index+1));
264 |
265 | delimiter_index = "])}".indexOf(current);
266 | if (delimiter_index != -1) {
267 | if (top(state).type == current) state.indent = state.scopes.pop().offset - hangingIndent
268 | else return ERRORCLASS;
269 | }
270 | if (state.dedent > 0 && stream.eol() && top(state).type == "py") {
271 | if (state.scopes.length > 1) state.scopes.pop();
272 | state.dedent -= 1;
273 | }
274 |
275 | return style;
276 | }
277 |
278 | var external = {
279 | startState: function(basecolumn) {
280 | return {
281 | tokenize: tokenBase,
282 | scopes: [{offset: basecolumn || 0, type: "py", align: null}],
283 | indent: basecolumn || 0,
284 | lastToken: null,
285 | lambda: false,
286 | dedent: 0
287 | };
288 | },
289 |
290 | token: function(stream, state) {
291 | var addErr = state.errorToken;
292 | if (addErr) state.errorToken = false;
293 | var style = tokenLexer(stream, state);
294 |
295 | if (style && style != "comment")
296 | state.lastToken = (style == "keyword" || style == "punctuation") ? stream.current() : style;
297 | if (style == "punctuation") style = null;
298 |
299 | if (stream.eol() && state.lambda)
300 | state.lambda = false;
301 | return addErr ? style + " " + ERRORCLASS : style;
302 | },
303 |
304 | indent: function(state, textAfter) {
305 | if (state.tokenize != tokenBase)
306 | return state.tokenize.isString ? CodeMirror.Pass : 0;
307 |
308 | var scope = top(state), closing = scope.type == textAfter.charAt(0)
309 | if (scope.align != null)
310 | return scope.align - (closing ? 1 : 0)
311 | else
312 | return scope.offset - (closing ? hangingIndent : 0)
313 | },
314 |
315 | electricInput: /^\s*[\}\]\)]$/,
316 | closeBrackets: {triples: "'\""},
317 | lineComment: "#",
318 | fold: "indent"
319 | };
320 | return external;
321 | });
322 |
323 | CodeMirror.defineMIME("text/x-python", "python");
324 |
325 | var words = function(str) { return str.split(" "); };
326 |
327 | CodeMirror.defineMIME("text/x-cython", {
328 | name: "python",
329 | extra_keywords: words("by cdef cimport cpdef ctypedef enum except "+
330 | "extern gil include nogil property public "+
331 | "readonly struct union DEF IF ELIF ELSE")
332 | });
333 |
334 | });
--------------------------------------------------------------------------------
/lib/pane1/searchcursor.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: http://codemirror.net/LICENSE
3 |
4 | (function(mod) {
5 | if (typeof exports == "object" && typeof module == "object") // CommonJS
6 | mod(require("../../lib/codemirror"))
7 | else if (typeof define == "function" && define.amd) // AMD
8 | define(["../../lib/codemirror"], mod)
9 | else // Plain browser env
10 | mod(CodeMirror)
11 | })(function(CodeMirror) {
12 | "use strict"
13 | var Pos = CodeMirror.Pos
14 |
15 | function regexpFlags(regexp) {
16 | var flags = regexp.flags
17 | return flags != null ? flags : (regexp.ignoreCase ? "i" : "")
18 | + (regexp.global ? "g" : "")
19 | + (regexp.multiline ? "m" : "")
20 | }
21 |
22 | function ensureGlobal(regexp) {
23 | return regexp.global ? regexp : new RegExp(regexp.source, regexpFlags(regexp) + "g")
24 | }
25 |
26 | function maybeMultiline(regexp) {
27 | return /\\s|\\n|\n|\\W|\\D|\[\^/.test(regexp.source)
28 | }
29 |
30 | function searchRegexpForward(doc, regexp, start) {
31 | regexp = ensureGlobal(regexp)
32 | for (var line = start.line, ch = start.ch, last = doc.lastLine(); line <= last; line++, ch = 0) {
33 | regexp.lastIndex = ch
34 | var string = doc.getLine(line), match = regexp.exec(string)
35 | if (match)
36 | return {from: Pos(line, match.index),
37 | to: Pos(line, match.index + match[0].length),
38 | match: match}
39 | }
40 | }
41 |
42 | function searchRegexpForwardMultiline(doc, regexp, start) {
43 | if (!maybeMultiline(regexp)) return searchRegexpForward(doc, regexp, start)
44 |
45 | regexp = ensureGlobal(regexp)
46 | var string, chunk = 1
47 | for (var line = start.line, last = doc.lastLine(); line <= last;) {
48 | // This grows the search buffer in exponentially-sized chunks
49 | // between matches, so that nearby matches are fast and don't
50 | // require concatenating the whole document (in case we're
51 | // searching for something that has tons of matches), but at the
52 | // same time, the amount of retries is limited.
53 | for (var i = 0; i < chunk; i++) {
54 | var curLine = doc.getLine(line++)
55 | string = string == null ? curLine : string + "\n" + curLine
56 | }
57 | chunk = chunk * 2
58 | regexp.lastIndex = start.ch
59 | var match = regexp.exec(string)
60 | if (match) {
61 | var before = string.slice(0, match.index).split("\n"), inside = match[0].split("\n")
62 | var startLine = start.line + before.length - 1, startCh = before[before.length - 1].length
63 | return {from: Pos(startLine, startCh),
64 | to: Pos(startLine + inside.length - 1,
65 | inside.length == 1 ? startCh + inside[0].length : inside[inside.length - 1].length),
66 | match: match}
67 | }
68 | }
69 | }
70 |
71 | function lastMatchIn(string, regexp) {
72 | var cutOff = 0, match
73 | for (;;) {
74 | regexp.lastIndex = cutOff
75 | var newMatch = regexp.exec(string)
76 | if (!newMatch) return match
77 | match = newMatch
78 | cutOff = match.index + (match[0].length || 1)
79 | if (cutOff == string.length) return match
80 | }
81 | }
82 |
83 | function searchRegexpBackward(doc, regexp, start) {
84 | regexp = ensureGlobal(regexp)
85 | for (var line = start.line, ch = start.ch, first = doc.firstLine(); line >= first; line--, ch = -1) {
86 | var string = doc.getLine(line)
87 | if (ch > -1) string = string.slice(0, ch)
88 | var match = lastMatchIn(string, regexp)
89 | if (match)
90 | return {from: Pos(line, match.index),
91 | to: Pos(line, match.index + match[0].length),
92 | match: match}
93 | }
94 | }
95 |
96 | function searchRegexpBackwardMultiline(doc, regexp, start) {
97 | regexp = ensureGlobal(regexp)
98 | var string, chunk = 1
99 | for (var line = start.line, first = doc.firstLine(); line >= first;) {
100 | for (var i = 0; i < chunk; i++) {
101 | var curLine = doc.getLine(line--)
102 | string = string == null ? curLine.slice(0, start.ch) : curLine + "\n" + string
103 | }
104 | chunk *= 2
105 |
106 | var match = lastMatchIn(string, regexp)
107 | if (match) {
108 | var before = string.slice(0, match.index).split("\n"), inside = match[0].split("\n")
109 | var startLine = line + before.length, startCh = before[before.length - 1].length
110 | return {from: Pos(startLine, startCh),
111 | to: Pos(startLine + inside.length - 1,
112 | inside.length == 1 ? startCh + inside[0].length : inside[inside.length - 1].length),
113 | match: match}
114 | }
115 | }
116 | }
117 |
118 | var doFold, noFold
119 | if (String.prototype.normalize) {
120 | doFold = function(str) { return str.normalize("NFD").toLowerCase() }
121 | noFold = function(str) { return str.normalize("NFD") }
122 | } else {
123 | doFold = function(str) { return str.toLowerCase() }
124 | noFold = function(str) { return str }
125 | }
126 |
127 | // Maps a position in a case-folded line back to a position in the original line
128 | // (compensating for codepoints increasing in number during folding)
129 | function adjustPos(orig, folded, pos, foldFunc) {
130 | if (orig.length == folded.length) return pos
131 | for (var min = 0, max = pos + Math.max(0, orig.length - folded.length);;) {
132 | if (min == max) return min
133 | var mid = (min + max) >> 1
134 | var len = foldFunc(orig.slice(0, mid)).length
135 | if (len == pos) return mid
136 | else if (len > pos) max = mid
137 | else min = mid + 1
138 | }
139 | }
140 |
141 | function searchStringForward(doc, query, start, caseFold) {
142 | // Empty string would match anything and never progress, so we
143 | // define it to match nothing instead.
144 | if (!query.length) return null
145 | var fold = caseFold ? doFold : noFold
146 | var lines = fold(query).split(/\r|\n\r?/)
147 |
148 | search: for (var line = start.line, ch = start.ch, last = doc.lastLine() + 1 - lines.length; line <= last; line++, ch = 0) {
149 | var orig = doc.getLine(line).slice(ch), string = fold(orig)
150 | if (lines.length == 1) {
151 | var found = string.indexOf(lines[0])
152 | if (found == -1) continue search
153 | var start = adjustPos(orig, string, found, fold) + ch
154 | return {from: Pos(line, adjustPos(orig, string, found, fold) + ch),
155 | to: Pos(line, adjustPos(orig, string, found + lines[0].length, fold) + ch)}
156 | } else {
157 | var cutFrom = string.length - lines[0].length
158 | if (string.slice(cutFrom) != lines[0]) continue search
159 | for (var i = 1; i < lines.length - 1; i++)
160 | if (fold(doc.getLine(line + i)) != lines[i]) continue search
161 | var end = doc.getLine(line + lines.length - 1), endString = fold(end), lastLine = lines[lines.length - 1]
162 | if (endString.slice(0, lastLine.length) != lastLine) continue search
163 | return {from: Pos(line, adjustPos(orig, string, cutFrom, fold) + ch),
164 | to: Pos(line + lines.length - 1, adjustPos(end, endString, lastLine.length, fold))}
165 | }
166 | }
167 | }
168 |
169 | function searchStringBackward(doc, query, start, caseFold) {
170 | if (!query.length) return null
171 | var fold = caseFold ? doFold : noFold
172 | var lines = fold(query).split(/\r|\n\r?/)
173 |
174 | search: for (var line = start.line, ch = start.ch, first = doc.firstLine() - 1 + lines.length; line >= first; line--, ch = -1) {
175 | var orig = doc.getLine(line)
176 | if (ch > -1) orig = orig.slice(0, ch)
177 | var string = fold(orig)
178 | if (lines.length == 1) {
179 | var found = string.lastIndexOf(lines[0])
180 | if (found == -1) continue search
181 | return {from: Pos(line, adjustPos(orig, string, found, fold)),
182 | to: Pos(line, adjustPos(orig, string, found + lines[0].length, fold))}
183 | } else {
184 | var lastLine = lines[lines.length - 1]
185 | if (string.slice(0, lastLine.length) != lastLine) continue search
186 | for (var i = 1, start = line - lines.length + 1; i < lines.length - 1; i++)
187 | if (fold(doc.getLine(start + i)) != lines[i]) continue search
188 | var top = doc.getLine(line + 1 - lines.length), topString = fold(top)
189 | if (topString.slice(topString.length - lines[0].length) != lines[0]) continue search
190 | return {from: Pos(line + 1 - lines.length, adjustPos(top, topString, top.length - lines[0].length, fold)),
191 | to: Pos(line, adjustPos(orig, string, lastLine.length, fold))}
192 | }
193 | }
194 | }
195 |
196 | function SearchCursor(doc, query, pos, options) {
197 | this.atOccurrence = false
198 | this.doc = doc
199 | pos = pos ? doc.clipPos(pos) : Pos(0, 0)
200 | this.pos = {from: pos, to: pos}
201 |
202 | var caseFold
203 | if (typeof options == "object") {
204 | caseFold = options.caseFold
205 | } else { // Backwards compat for when caseFold was the 4th argument
206 | caseFold = options
207 | options = null
208 | }
209 |
210 | if (typeof query == "string") {
211 | if (caseFold == null) caseFold = false
212 | this.matches = function(reverse, pos) {
213 | return (reverse ? searchStringBackward : searchStringForward)(doc, query, pos, caseFold)
214 | }
215 | } else {
216 | query = ensureGlobal(query)
217 | if (!options || options.multiline !== false)
218 | this.matches = function(reverse, pos) {
219 | return (reverse ? searchRegexpBackwardMultiline : searchRegexpForwardMultiline)(doc, query, pos)
220 | }
221 | else
222 | this.matches = function(reverse, pos) {
223 | return (reverse ? searchRegexpBackward : searchRegexpForward)(doc, query, pos)
224 | }
225 | }
226 | }
227 |
228 | SearchCursor.prototype = {
229 | findNext: function() {return this.find(false)},
230 | findPrevious: function() {return this.find(true)},
231 |
232 | find: function(reverse) {
233 | var result = this.matches(reverse, this.doc.clipPos(reverse ? this.pos.from : this.pos.to))
234 |
235 | // Implements weird auto-growing behavior on null-matches for
236 | // backwards-compatiblity with the vim code (unfortunately)
237 | while (result && CodeMirror.cmpPos(result.from, result.to) == 0) {
238 | if (reverse) {
239 | if (result.from.ch) result.from = Pos(result.from.line, result.from.ch - 1)
240 | else if (result.from.line == this.doc.firstLine()) result = null
241 | else result = this.matches(reverse, this.doc.clipPos(Pos(result.from.line - 1)))
242 | } else {
243 | if (result.to.ch < this.doc.getLine(result.to.line).length) result.to = Pos(result.to.line, result.to.ch + 1)
244 | else if (result.to.line == this.doc.lastLine()) result = null
245 | else result = this.matches(reverse, Pos(result.to.line + 1, 0))
246 | }
247 | }
248 |
249 | if (result) {
250 | this.pos = result
251 | this.atOccurrence = true
252 | return this.pos.match || true
253 | } else {
254 | var end = Pos(reverse ? this.doc.firstLine() : this.doc.lastLine() + 1, 0)
255 | this.pos = {from: end, to: end}
256 | return this.atOccurrence = false
257 | }
258 | },
259 |
260 | from: function() {if (this.atOccurrence) return this.pos.from},
261 | to: function() {if (this.atOccurrence) return this.pos.to},
262 |
263 | replace: function(newText, origin) {
264 | if (!this.atOccurrence) return
265 | var lines = CodeMirror.splitLines(newText)
266 | this.doc.replaceRange(lines, this.pos.from, this.pos.to, origin)
267 | this.pos.to = Pos(this.pos.from.line + lines.length - 1,
268 | lines[lines.length - 1].length + (lines.length == 1 ? this.pos.from.ch : 0))
269 | }
270 | }
271 |
272 | CodeMirror.defineExtension("getSearchCursor", function(query, pos, caseFold) {
273 | return new SearchCursor(this.doc, query, pos, caseFold)
274 | })
275 | CodeMirror.defineDocExtension("getSearchCursor", function(query, pos, caseFold) {
276 | return new SearchCursor(this, query, pos, caseFold)
277 | })
278 |
279 | CodeMirror.defineExtension("selectMatches", function(query, caseFold) {
280 | var ranges = []
281 | var cur = this.getSearchCursor(query, this.getCursor("from"), caseFold)
282 | while (cur.findNext()) {
283 | if (CodeMirror.cmpPos(cur.to(), this.getCursor("to")) > 0) break
284 | ranges.push({anchor: cur.from(), head: cur.to()})
285 | }
286 | if (ranges.length)
287 | this.setSelections(ranges, 0)
288 | })
289 | });
290 |
--------------------------------------------------------------------------------
/pane1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
21 |
22 |
23 |
24 |
38 |
39 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/static/img/dot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/teamsudocode/dexter/0ccceac9a97687c39c84eb92ee834021d66767c8/static/img/dot.png
--------------------------------------------------------------------------------
/static/img/english.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/static/img/hindi.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/static/img/js.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/static/img/logo-alt.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/static/img/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/static/img/mic.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/static/img/python.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/static/img/run.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/static/img/text-logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/static/img/undo.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/styles/editor.css:
--------------------------------------------------------------------------------
1 | @import url(reset.css);
2 | body {
3 | max-height: 100%;
4 | overflow-y: hidden; }
5 |
6 | .container {
7 | display: grid;
8 | height: 100vh;
9 | grid-template-rows: 10% 65% 25%; }
10 | .container .nav {
11 | padding: 2em;
12 | display: grid;
13 | grid-template-columns: 20% 60% 20%;
14 | background: #121E4A;
15 | box-shadow: 0 5px 4px 0 rgba(3, 16, 64, 0.54); }
16 | .container .nav span {
17 | font-family: 'Roboto';
18 | font-size: 14px;
19 | text-transform: uppercase;
20 | color: rgba(255, 255, 255, 0.5);
21 | letter-spacing: 6px;
22 | text-align: center; }
23 | .container .nav .language {
24 | display: flex;
25 | justify-content: flex-end;
26 | align-items: center; }
27 | .container .nav .language p {
28 | display: inline-block;
29 | font-family: 'Roboto';
30 | font-size: 14px;
31 | font-weight: 400;
32 | color: #5762B9; }
33 | .container .nav .language img {
34 | margin-left: 1.5em;
35 | cursor: pointer;
36 | transition: all 0.2s ease-in-out; }
37 | .container .nav .language #hindi {
38 | opacity: 0.3; }
39 | .container .editors {
40 | display: grid;
41 | grid-template-columns: 49.75% 0.5% 49.75%; }
42 | .container .editors #js .title .filename {
43 | border-bottom: 2px solid #FF309D; }
44 | .container .editors #python .title .filename {
45 | border-bottom: 2px solid #00B2F7; }
46 | .container .editors .pane {
47 | display: grid;
48 | grid-template-columns: 1% 99%;
49 | grid-template-rows: 10% 90%;
50 | background-image: linear-gradient(-180deg, #2E3478 0%, #0F1C46 100%); }
51 | .container .editors .pane .title {
52 | display: flex;
53 | flex-direction: row;
54 | justify-content: space-between;
55 | padding: 1em;
56 | height: 1.7em; }
57 | .container .editors .pane .title .filename {
58 | display: inline-block; }
59 | .container .editors .pane .title .filename img {
60 | vertical-align: middle;
61 | margin-right: 0.5em; }
62 | .container .editors .pane .title .filename span {
63 | font-family: 'Roboto';
64 | font-size: 1em;
65 | font-weight: 500;
66 | vertical-align: middle;
67 | color: #FFFFFF;
68 | letter-spacing: 0.44px; }
69 | .container .editors .pane .title .actions {
70 | display: flex;
71 | padding: 0 1em; }
72 | .container .editors .pane .title .actions #undo {
73 | cursor: pointer; }
74 | .container .editors .pane .title .actions button {
75 | margin-left: 2em;
76 | cursor: pointer;
77 | background: #42A15E;
78 | border-radius: 2px;
79 | font-family: Roboto;
80 | font-weight: 500;
81 | border: none;
82 | padding: 0.5em;
83 | font-size: 0.8em;
84 | color: #FFFFFF; }
85 | .container .editors .pane .title .actions button img {
86 | margin-left: 0.5em; }
87 | .container .editors .pane .index {
88 | padding: 0px 1em 1em 1em;
89 | font-family: 'Roboto Mono';
90 | text-align: center;
91 | font-size: 1em;
92 | color: rgba(255, 255, 255, 0.22);
93 | line-height: 1.55em; }
94 | .container .editors .pane .editor {
95 | background-color: transparent;
96 | border: none;
97 | font-family: 'Roboto Mono';
98 | font-size: 1em;
99 | color: #FFF;
100 | line-height: 1.55em; }
101 | .container .editors .pane .editor:focus {
102 | outline: none; }
103 | .container .editors .divider {
104 | background-color: #495297; }
105 | .container .preview {
106 | display: flex;
107 | justify-content: center;
108 | align-items: center;
109 | flex-direction: column;
110 | background-image: linear-gradient(-180deg, #122256 0%, #0B164B 100%); }
111 | .container .preview div {
112 | font-family: 'Roboto Mono';
113 | font-size: 1.2em;
114 | letter-spacing: 0.2em;
115 | text-transform: uppercase;
116 | text-align: center;
117 | line-height: 1.5em;
118 | color: #00B2F7;
119 | position: relative; }
120 | .container .preview .Loader {
121 | position: relative;
122 | display: flex;
123 | align-items: center;
124 | justify-content: center;
125 | width: 100%;
126 | max-width: 3.4rem;
127 | margin-top: 1.7rem;
128 | margin-bottom: 3.4rem; }
129 | .container .preview .Loader:before, .container .preview .Loader:after {
130 | content: "";
131 | position: absolute;
132 | border-radius: 50%;
133 | animation-duration: 1.8s;
134 | animation-iteration-count: infinite;
135 | animation-timing-function: ease-in-out;
136 | filter: drop-shadow(0 0 0.08889rem rgba(0, 208, 250, 0.75)); }
137 | .container .preview .Loader:before {
138 | width: 100%;
139 | padding-bottom: 100%;
140 | box-shadow: inset 0 0 0 0.2rem #00D0FA;
141 | animation-name: pulsA; }
142 | .container .preview .Loader:after {
143 | width: calc(100% - 0.2rem*2);
144 | padding-bottom: calc(100% - 0.2rem*2);
145 | box-shadow: 0 0 0 0 #00D0FA;
146 | animation-name: pulsB; }
147 | .container .preview .Loader img:before, .container .preview .Loader img:after {
148 | animation-duration: 1.8s;
149 | animation-iteration-count: infinite;
150 | animation-timing-function: ease-in-out; }
151 | .container .preview .Loader img:before {
152 | animation-name: pulsA; }
153 | .container .preview .Loader img:after {
154 | animation-name: pulsB; }
155 | .container .preview #rec-btn {
156 | cursor: pointer; }
157 | .container .preview .alive {
158 | display: visible; }
159 | .container .preview .dead {
160 | margin-bottom: 3em;
161 | margin-top: 1.5em;
162 | display: none; }
163 | @keyframes pulsA {
164 | 0% {
165 | box-shadow: inset 0 0 0 0.2rem #00D0FA;
166 | opacity: 1; }
167 | 50%,
168 | 100% {
169 | box-shadow: inset 0 0 0 0 #00D0FA;
170 | opacity: 0; } }
171 | @keyframes pulsB {
172 | 0%,
173 | 50% {
174 | box-shadow: 0 0 0 0 #00D0FA;
175 | opacity: 0; }
176 | 100% {
177 | box-shadow: 0 0 0 0.2rem #00D0FA;
178 | opacity: 1; } }
179 |
180 | /*# sourceMappingURL=editor.css.map */
181 |
--------------------------------------------------------------------------------
/styles/editor.scss:
--------------------------------------------------------------------------------
1 | @import 'reset.css';
2 | body {
3 | max-height: 100%;
4 | overflow-y: hidden;
5 | }
6 |
7 | .container {
8 | display: grid;
9 | height: 100vh;
10 | grid-template-rows: 10% 65% 25%;
11 | .nav {
12 | padding: 2em;
13 | display: grid;
14 | grid-template-columns: 20% 60% 20%;
15 | background: #121E4A;
16 | box-shadow: 0 5px 4px 0 rgba(3, 16, 64, 0.54);
17 | span {
18 | font-family: 'Roboto';
19 | font-size: 14px;
20 | text-transform: uppercase;
21 | color: rgba(255, 255, 255, 0.50);
22 | letter-spacing: 6px;
23 | text-align: center;
24 | }
25 | .language {
26 | display: flex;
27 | justify-content: flex-end;
28 | align-items: center;
29 | p {
30 | display: inline-block;
31 | font-family: 'Roboto';
32 | font-size: 14px;
33 | font-weight: 400;
34 | color: #5762B9;
35 | }
36 | img {
37 | margin-left: 1.5em;
38 | cursor: pointer;
39 | transition: all 0.2s ease-in-out;
40 | }
41 | #hindi{
42 | opacity: 0.3;
43 | }
44 | }
45 | }
46 | .editors {
47 | display: grid;
48 | grid-template-columns: 49.75% 0.5% 49.75%;
49 | #js {
50 | .title {
51 | .filename {
52 | border-bottom: 2px solid #FF309D;
53 | }
54 | }
55 | }
56 | #python {
57 | .title {
58 | .filename {
59 | border-bottom: 2px solid #00B2F7;
60 | }
61 | }
62 | }
63 | .pane {
64 | display: grid;
65 | grid-template-columns: 1% 99%;
66 | grid-template-rows: 10% 90%;
67 | background-image: linear-gradient(-180deg, #2E3478 0%, #0F1C46 100%);
68 | .title {
69 | display: flex;
70 | flex-direction: row;
71 | justify-content: space-between;
72 | padding: 1em;
73 | height: 1.7em;
74 | .filename {
75 | display: inline-block;
76 | img {
77 | vertical-align: middle;
78 | margin-right: 0.5em;
79 | }
80 | span {
81 | font-family: 'Roboto';
82 | font-size: 1em;
83 | font-weight: 500;
84 | vertical-align: middle;
85 | color: #FFFFFF;
86 | letter-spacing: 0.44px;
87 | }
88 | }
89 | .actions {
90 | display: flex;
91 | padding: 0 1em;
92 | #undo {
93 | cursor: pointer;
94 | }
95 | button {
96 | margin-left: 2em;
97 | cursor: pointer;
98 | background: #42A15E;
99 | border-radius: 2px;
100 | font-family: Roboto;
101 | font-weight: 500;
102 | border: none;
103 | padding: 0.5em;
104 | font-size: 0.8em;
105 | color: #FFFFFF;
106 | img {
107 | margin-left: 0.5em;
108 | }
109 | }
110 | }
111 | }
112 | .index {
113 | padding: 0px 1em 1em 1em;
114 | font-family: 'Roboto Mono';
115 | text-align: center;
116 | font-size: 1em;
117 | color: rgba(255, 255, 255, 0.22);
118 | line-height: 1.55em;
119 | }
120 | .editor {
121 | background-color: transparent;
122 | border: none;
123 | font-family: 'Roboto Mono';
124 | font-size: 1em;
125 | color: #FFF;
126 | line-height: 1.55em;
127 | &:focus {
128 | outline: none;
129 | }
130 | }
131 | }
132 | .divider {
133 | background-color: #495297;
134 | }
135 | }
136 | .preview {
137 | display: flex;
138 | justify-content: center;
139 | align-items: center;
140 | flex-direction: column;
141 | background-image: linear-gradient(-180deg, #122256 0%, #0B164B 100%);
142 | div {
143 | font-family: 'Roboto Mono';
144 | font-size: 1.2em;
145 | letter-spacing: 0.2em;
146 | text-transform: uppercase;
147 | text-align: center;
148 | line-height: 1.5em;
149 | color: #00B2F7;
150 | position: relative;
151 | }
152 | $Loader-color: #00D0FA;
153 | $Loader-size: 3.4rem;
154 | $Loader-offset: 0.2rem;
155 | $Loader-timing: ease-in-out;
156 | .Loader {
157 | position: relative;
158 | display: flex;
159 | align-items: center;
160 | justify-content: center;
161 | width: 100%;
162 | max-width: $Loader-size;
163 | margin-top: $Loader-size/2;
164 | margin-bottom: $Loader-size;
165 | &:before,
166 | &:after {
167 | content: "";
168 | position: absolute;
169 | border-radius: 50%;
170 | animation-duration: 1.8s;
171 | animation-iteration-count: infinite;
172 | animation-timing-function: $Loader-timing;
173 | filter: drop-shadow(0 0 $Loader-offset/2.25 rgba($Loader-color, 0.75));
174 | }
175 | &:before {
176 | width: 100%;
177 | padding-bottom: 100%;
178 | box-shadow: inset 0 0 0 $Loader-offset $Loader-color;
179 | animation-name: pulsA;
180 | }
181 | &:after {
182 | width: calc(100% - #{$Loader-offset}*2);
183 | padding-bottom: calc(100% - #{$Loader-offset}*2);
184 | box-shadow: 0 0 0 0 $Loader-color;
185 | animation-name: pulsB;
186 | }
187 | img {
188 | &:before,
189 | &:after {
190 | animation-duration: 1.8s;
191 | animation-iteration-count: infinite;
192 | animation-timing-function: $Loader-timing;;
193 | }
194 | &:before {
195 | animation-name: pulsA;
196 | }
197 | &:after {
198 | animation-name: pulsB;
199 | }
200 | }
201 | }
202 | #rec-btn{
203 | cursor: pointer;
204 | }
205 | .alive{
206 | display: visible;
207 | }
208 | .dead{
209 | margin-bottom: 3em;
210 | margin-top: 1.5em;
211 | display: none;
212 | }
213 | @keyframes pulsA {
214 | 0% {
215 | box-shadow: inset 0 0 0 $Loader-offset $Loader-color;
216 | opacity: 1;
217 | }
218 | 50%,
219 | 100% {
220 | box-shadow: inset 0 0 0 0 $Loader-color;
221 | opacity: 0;
222 | }
223 | }
224 | @keyframes pulsB {
225 | 0%,
226 | 50% {
227 | box-shadow: 0 0 0 0 $Loader-color;
228 | opacity: 0;
229 | }
230 | 100% {
231 | box-shadow: 0 0 0 $Loader-offset $Loader-color;
232 | opacity: 1;
233 | }
234 | }
235 | }
236 | }
237 |
--------------------------------------------------------------------------------
/styles/home.css:
--------------------------------------------------------------------------------
1 | @import url(reset.css);
2 | body {
3 | background: linear-gradient(-180deg, #252C70 0%, #0F1C46 100%);
4 | height: 100vh;
5 | overflow-y: hidden; }
6 |
7 | .container {
8 | margin-top: 10%;
9 | display: flex;
10 | flex-direction: column;
11 | text-align: center; }
12 | .container .logo {
13 | height: 9em; }
14 | .container .textlogo {
15 | margin: 2em 0 2.5em 0;
16 | height: 3.5em; }
17 | .container h1 {
18 | font-family: 'Roboto';
19 | font-size: 1.2em;
20 | color: #FFFFFF;
21 | letter-spacing: 0.3em;
22 | margin-bottom: 2em;
23 | text-transform: uppercase; }
24 | .container .video-play-button {
25 | position: absolute;
26 | z-index: 10;
27 | bottom: 25vh;
28 | left: 50%;
29 | transform: translateX(-50%) translateY(-50%);
30 | box-sizing: content-box;
31 | display: block;
32 | width: 28px;
33 | height: 48px;
34 | border-radius: 50%;
35 | transition-duration: 0.15s;
36 | transition-timing-function: ease-in-out;
37 | transition-property: background;
38 | padding: 18px 20px 18px 28px; }
39 | .container .video-play-button:before {
40 | content: "";
41 | position: absolute;
42 | z-index: 0;
43 | left: 50%;
44 | top: 50%;
45 | transform: translateX(-50%) translateY(-50%);
46 | display: block;
47 | width: 120px;
48 | height: 120px;
49 | background: #114276;
50 | border-radius: 50%;
51 | animation: pulse-border 1500ms ease-out infinite; }
52 | .container .video-play-button:after {
53 | content: "";
54 | position: absolute;
55 | z-index: 1;
56 | left: 50%;
57 | top: 50%;
58 | transform: translateX(-50%) translateY(-50%);
59 | display: block;
60 | width: 120px;
61 | height: 120px;
62 | background: #00B2F7;
63 | border-radius: 50%;
64 | transition: all 200ms; }
65 | .container .video-play-button:hover:after {
66 | background-color: #00a0de; }
67 | .container .video-play-button img {
68 | position: relative;
69 | z-index: 3;
70 | max-width: 100%;
71 | width: auto;
72 | height: auto; }
73 | .container .video-play-button span {
74 | display: block;
75 | position: relative;
76 | z-index: 3;
77 | width: 0;
78 | height: 0;
79 | border-left: 32px solid #fff;
80 | border-top: 22px solid transparent;
81 | border-bottom: 22px solid transparent; }
82 | @keyframes pulse-border {
83 | 0% {
84 | transform: translateX(-50%) translateY(-50%) translateZ(0) scale(1);
85 | opacity: 1; }
86 | 100% {
87 | transform: translateX(-50%) translateY(-50%) translateZ(0) scale(1.5);
88 | opacity: 0; } }
89 |
90 | /*# sourceMappingURL=home.css.map */
91 |
--------------------------------------------------------------------------------
/styles/home.scss:
--------------------------------------------------------------------------------
1 | @import 'reset.css';
2 | body {
3 | background: linear-gradient(-180deg, #252C70 0%, #0F1C46 100%);
4 | height: 100vh;
5 | overflow-y: hidden;
6 | }
7 |
8 | .container {
9 | margin-top: 10%;
10 | display: flex;
11 | flex-direction: column;
12 | text-align: center;
13 | .logo {
14 | height: 9em;
15 | }
16 | .textlogo {
17 | margin: 2em 0 2.5em 0;
18 | height: 3.5em;
19 | }
20 | h1 {
21 | font-family: 'Roboto';
22 | font-size: 1.2em;
23 | color: #FFFFFF;
24 | letter-spacing: 0.3em;
25 | margin-bottom: 2em;
26 | text-transform: uppercase;
27 | }
28 | .video-play-button {
29 | position: absolute;
30 | z-index: 10;
31 | bottom: 25vh;
32 | left: 50%;
33 | transform: translateX(-50%) translateY(-50%);
34 | box-sizing: content-box;
35 | display: block;
36 | width: 28px;
37 | height: 48px;
38 | border-radius: 50%;
39 | transition-duration: 0.15s;
40 | transition-timing-function: ease-in-out;
41 | transition-property: background;
42 | padding: 18px 20px 18px 28px;
43 | }
44 | .video-play-button:before {
45 | content: "";
46 | position: absolute;
47 | z-index: 0;
48 | left: 50%;
49 | top: 50%;
50 | transform: translateX(-50%) translateY(-50%);
51 | display: block;
52 | width: 120px;
53 | height: 120px;
54 | background: #114276;
55 | border-radius: 50%;
56 | animation: pulse-border 1500ms ease-out infinite;
57 | }
58 | .video-play-button:after {
59 | content: "";
60 | position: absolute;
61 | z-index: 1;
62 | left: 50%;
63 | top: 50%;
64 | transform: translateX(-50%) translateY(-50%);
65 | display: block;
66 | width: 120px;
67 | height: 120px;
68 | background: #00B2F7;
69 | border-radius: 50%;
70 | transition: all 200ms;
71 | }
72 | .video-play-button:hover:after {
73 | background-color: darken(#00B2F7, 5%);
74 | }
75 | .video-play-button img {
76 | position: relative;
77 | z-index: 3;
78 | max-width: 100%;
79 | width: auto;
80 | height: auto;
81 | }
82 | .video-play-button span {
83 | display: block;
84 | position: relative;
85 | z-index: 3;
86 | width: 0;
87 | height: 0;
88 | border-left: 32px solid #fff;
89 | border-top: 22px solid transparent;
90 | border-bottom: 22px solid transparent;
91 | }
92 | @keyframes pulse-border {
93 | 0% {
94 | transform: translateX(-50%) translateY(-50%) translateZ(0) scale(1);
95 | opacity: 1;
96 | }
97 | 100% {
98 | transform: translateX(-50%) translateY(-50%) translateZ(0) scale(1.5);
99 | opacity: 0;
100 | }
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/styles/lol.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
Rich Text Editor
5 |
57 |
76 |
77 |
78 |
149 |
150 |
--------------------------------------------------------------------------------
/styles/reset.css:
--------------------------------------------------------------------------------
1 | /* http://meyerweb.com/eric/tools/css/reset/
2 | v2.0 | 20110126
3 | License: none (public domain)
4 | */
5 |
6 | html, body, div, span, applet, object, iframe,
7 | h1, h2, h3, h4, h5, h6, p, blockquote, pre,
8 | a, abbr, acronym, address, big, cite, code,
9 | del, dfn, em, img, ins, kbd, q, s, samp,
10 | small, strike, strong, sub, sup, tt, var,
11 | b, u, i, center,
12 | dl, dt, dd, ol, ul, li,
13 | fieldset, form, label, legend,
14 | table, caption, tbody, tfoot, thead, tr, th, td,
15 | article, aside, canvas, details, embed,
16 | figure, figcaption, footer, header, hgroup,
17 | menu, nav, output, ruby, section, summary,
18 | time, mark, audio, video {
19 | margin: 0;
20 | padding: 0;
21 | border: 0;
22 | font-size: 100%;
23 | font: inherit;
24 | vertical-align: baseline;
25 | }
26 | /* HTML5 display-role reset for older browsers */
27 | article, aside, details, figcaption, figure,
28 | footer, header, hgroup, menu, nav, section {
29 | display: block;
30 | }
31 | body {
32 | line-height: 1;
33 | }
34 | ol, ul {
35 | list-style: none;
36 | }
37 | blockquote, q {
38 | quotes: none;
39 | }
40 | blockquote:before, blockquote:after,
41 | q:before, q:after {
42 | content: '';
43 | content: none;
44 | }
45 | table {
46 | border-collapse: collapse;
47 | border-spacing: 0;
48 | }
--------------------------------------------------------------------------------