diff --git a/.gitignore b/.gitignore index 3d901ba..33f789d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,12 +2,20 @@ venv/ app/__init__.py app/__pycache__/ +.DS_Store +app/.DS_Store app/sqlite_commands.py app/static/usr/*.jpg app/static/img/ app/static/frequency/frequency_*.pickle app/static/frequency/frequency.p -app/static/wordfreqapp.db +app/wordfreqapp.db +app/db/wordfreqapp.db app/static/donate-the-author.jpg app/static/donate-the-author-hidden.jpg -app/model/__pycache__/ \ No newline at end of file +app/model/__pycache__/ +app/test/__pycache__/ +app/test/.pytest_cache/ +app/test/pytest_report.html +app/test/assets +app/log.txt diff --git a/Dockerfile b/Dockerfile index 284195a..55e5946 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,5 @@ -FROM tiangolo/uwsgi-nginx-flask:python3.6 -COPY requirements.txt /app -RUN pip3 install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/ -COPY ./app /app +FROM tiangolo/uwsgi-nginx-flask:python3.8-alpine +COPY requirements.txt /tmp +COPY ./app/ /app/ +RUN pip3 install -U pip -i https://mirrors.aliyun.com/pypi/simple/ +RUN pip3 install -r /tmp/requirements.txt -i https://mirrors.aliyun.com/pypi/simple/ diff --git a/Jenkinsfile b/Jenkinsfile index 2633859..c3772cc 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -10,8 +10,8 @@ pipeline { stages { stage('MakeDatabasefile') { steps { - sh 'touch ./app/static/wordfreqapp.db && rm -f ./app/static/wordfreqapp.db' - sh 'cat ./app/static/wordfreqapp.sql | sqlite3 ./app/static/wordfreqapp.db' + sh 'touch ./app/wordfreqapp.db && rm -f ./app/wordfreqapp.db' + sh 'cat ./app/static/wordfreqapp.sql | sqlite3 ./app/wordfreqapp.db' } } stage('BuildIt') { diff --git a/README.md b/README.md index 14cc9aa..15fc966 100644 --- a/README.md +++ b/README.md @@ -61,15 +61,15 @@ My steps for deploying English on a Ubuntu server. All articles are stored in the `article` table in a SQLite file called -`app/static/wordfreqapp.db`. +`app/db/wordfreqapp.db`. ### Adding new articles -To add articles, open and edit `app/static/wordfreqapp.db` using DB Browser for SQLite (https://sqlitebrowser.org). +To add articles, open and edit `app/db/wordfreqapp.db` using DB Browser for SQLite (https://sqlitebrowser.org). ### Extending an account's expiry date -By default, an account's expiry is 30 days after first sign-up. To extend account's expiry date, open and edit `user` table in `app/static/wordfreqapp.db`. Simply update field `expiry_date`. +By default, an account's expiry is 30 days after first sign-up. To extend account's expiry date, open and edit `user` table in `app/db/wordfreqapp.db`. Simply update field `expiry_date`. ### Exporting the database @@ -95,7 +95,7 @@ sqlite3 wordfreqapp.db`. Delete wordfreqapp.db first if it exists. ### Uploading wordfreqapp.db to the server -`pscp wordfreqapp.db lanhui@118.*.*.118:/home/lanhui/englishpal2/EnglishPal/app/static` +`pscp wordfreqapp.db lanhui@118.*.*.118:/home/lanhui/englishpal2/EnglishPal/app/db/` @@ -129,6 +129,28 @@ We welcome feedback on EnglishPal. Feedback examples: EnglishPal's bugs and improvement suggestions are recorded in [Bugzilla](http://118.25.96.118/bugzilla/buglist.cgi?bug_status=__all__&list_id=1302&order=Importance&product=EnglishPal&query_format=specific). Send (lanhui at zjnu.edu.cn) an email message for opening a Bugzilla account or reporting a bug. +## End-to-end testing + +We use the Selenium test framework to test our app. + +In order to run the test, first we need to download a webdriver executable. + +Microsoft Edge's webdriver can be downloaded from [microsoft-edge-tools-webdriver](https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/). Make sure the version we download matches the version of the web browser installed on our laptop. + +After extracting the downloaded zip file (e.g., edgedriver_win64.zip), rename msedgedriver.exe to MicrosoftWebDriver.exe. + +Add MicrosoftWebDriver.exe's path to system's PATH variable. + +Install the following dependencies too: + +- pip install -U selenium==3.141.0 +- pip install -U urllib3==1.26.2 + +Run English Pal first, then run the test using pytest as follows: pytest --html=pytest_report.html test_add_word.py + +The above command will generate a HTML report file pytest_report.html after finishing executing test_add_word.py. Note: you need to install pytest-html package first: pip install pytest-html. + +You may also want to use [webdriver-manager](https://pypi.org/project/webdriver-manager/) from PyPI, so that you can avoid tediously installing a web driver executable manually. However, my experience shows that webdriver-manager is too slow. For example, it took me 16 minutes to run 9 tests, while with the pre-installed web driver executable, it took less than 2 minutes. ## TODO diff --git a/app/Article.py b/app/Article.py index df9ac3a..98d56b6 100644 --- a/app/Article.py +++ b/app/Article.py @@ -1,6 +1,5 @@ from WordFreq import WordFreq from wordfreqCMD import youdao_link, sort_in_descending_order -from UseSqlite import InsertQuery, RecordQuery import pickle_idea, pickle_idea2 import os import random, glob @@ -8,18 +7,37 @@ import hashlib from datetime import datetime from flask import Flask, request, redirect, render_template, url_for, session, abort, flash, get_flashed_messages from difficulty import get_difficulty_level_for_user, text_difficulty_level, user_difficulty_level +from model.article import get_all_articles, get_article_by_id, get_number_of_articles +import logging +import re +path_prefix = './' +db_path_prefix = './db/' # comment this line in deployment +oxford_words_path='./db/oxford_words.txt' +def count_oxford_words(text, oxford_words): + words = re.findall(r'\b\w+\b', text.lower()) + total_words = len(words) + oxford_word_count = sum(1 for word in words if word in oxford_words) + return oxford_word_count, total_words -path_prefix = '/var/www/wordfreq/wordfreq/' -path_prefix = './' # comment this line in deployment +def calculate_ratio(oxford_word_count, total_words): + if total_words == 0: + return 0 + return oxford_word_count / total_words +def load_oxford_words(file_path): + oxford_words = {} + with open(file_path, 'r', encoding='utf-8') as file: + for line in file: + parts = line.strip().split() + word = parts[0] + pos = parts[1] + level = parts[2] + oxford_words[word] = {'pos': pos, 'level': level} + return oxford_words def total_number_of_essays(): - rq = RecordQuery(path_prefix + 'static/wordfreqapp.db') - rq.instructions("SELECT * FROM article") - rq.do() - result = rq.get_results() - return len(result) + return get_number_of_articles() def get_article_title(s): @@ -33,32 +51,36 @@ def get_article_body(s): def get_today_article(user_word_list, visited_articles): - rq = RecordQuery(path_prefix + 'static/wordfreqapp.db') if visited_articles is None: visited_articles = { "index" : 0, # 为 article_ids 的索引 "article_ids": [] # 之前显示文章的id列表,越后越新 } if visited_articles["index"] > len(visited_articles["article_ids"])-1: # 生成新的文章,因此查找所有的文章 - rq.instructions("SELECT * FROM article") + result = get_all_articles() else: # 生成阅读过的文章,因此查询指定 article_id 的文章 if visited_articles["article_ids"][visited_articles["index"]] == 'null': # 可能因为直接刷新页面导致直接去查询了'null',因此当刷新的页面的时候,需要直接进行“上一篇”操作 visited_articles["index"] -= 1 visited_articles["article_ids"].pop() - rq.instructions('SELECT * FROM article WHERE article_id=%d' % (visited_articles["article_ids"][visited_articles["index"]])) - rq.do() - result = rq.get_results() + article_id = visited_articles["article_ids"][visited_articles["index"]] + result = get_article_by_id(article_id) random.shuffle(result) # Choose article according to reader's level - d1 = load_freq_history(path_prefix + 'static/frequency/frequency.p') + logging.debug('* get_today_article(): start d1 = ... ') + d1 = load_freq_history(user_word_list) d2 = load_freq_history(path_prefix + 'static/words_and_tests.p') + logging.debug(' ... get_today_article(): get_difficulty_level_for_user() start') d3 = get_difficulty_level_for_user(d1, d2) + logging.debug(' ... get_today_article(): done') d = None result_of_generate_article = "not found" + d_user = load_freq_history(user_word_list) + logging.debug('* get_today_article(): user_difficulty_level() start') user_level = user_difficulty_level(d_user, d3) # more consideration as user's behaviour is dynamic. Time factor should be considered. + logging.debug('* get_today_article(): done') text_level = 0 if visited_articles["index"] > len(visited_articles["article_ids"])-1: # 生成新的文章 amount_of_visited_articles = len(visited_articles["article_ids"]) @@ -86,15 +108,19 @@ def get_today_article(user_word_list, visited_articles): today_article = None if d: + oxford_words = load_oxford_words(oxford_words_path) + oxford_word_count, total_words = count_oxford_words(d['text'],oxford_words) + ratio = calculate_ratio(oxford_word_count,total_words) today_article = { - "user_level": '%4.2f' % user_level, - "text_level": '%4.2f' % text_level, + "user_level": '%4.1f' % user_level, + "text_level": '%4.1f' % text_level, "date": d['date'], "article_title": get_article_title(d['text']), "article_body": get_article_body(d['text']), "source": d["source"], "question": get_question_part(d['question']), - "answer": get_answer_part(d['question']) + "answer": get_answer_part(d['question']), + "ratio" : ratio } return visited_articles, today_article, result_of_generate_article diff --git a/app/Login.py b/app/Login.py index cd750d1..d82a6d1 100644 --- a/app/Login.py +++ b/app/Login.py @@ -1,7 +1,8 @@ import hashlib import string from datetime import datetime, timedelta -from UseSqlite import InsertQuery, RecordQuery +import unicodedata + def md5(s): ''' @@ -12,16 +13,13 @@ def md5(s): h = hashlib.md5(s.encode(encoding='utf-8')) return h.hexdigest() + # import model.user after the defination of md5(s) to avoid circular import from model.user import get_user_by_username, insert_user, update_password_by_username path_prefix = '/var/www/wordfreq/wordfreq/' path_prefix = './' # comment this line in deployment -def verify_pass(newpass,oldpass): - if(newpass==oldpass): - return True - def verify_user(username, password): user = get_user_by_username(username) @@ -31,7 +29,7 @@ def verify_user(username, password): def add_user(username, password): start_date = datetime.now().strftime('%Y%m%d') - expiry_date = (datetime.now() + timedelta(days=30)).strftime('%Y%m%d') # will expire after 30 days + expiry_date = (datetime.now() + timedelta(days=30)).strftime('%Y%m%d') # will expire after 30 days # 将用户名和密码一起加密,以免暴露不同用户的相同密码 password = md5(username + password) insert_user(username=username, password=password, start_date=start_date, expiry_date=expiry_date) @@ -51,12 +49,12 @@ def change_password(username, old_password, new_password): :return: 修改成功:True 否则:False ''' if not verify_user(username, old_password): # 旧密码错误 - return False + return {'error':'Old password is wrong.', 'username':username} # 将用户名和密码一起加密,以免暴露不同用户的相同密码 - if verify_pass(new_password,old_password): #新旧密码一致 - return False + if new_password == old_password: #新旧密码一致 + return {'error':'New password cannot be the same as the old password.', 'username':username} update_password_by_username(username, new_password) - return True + return {'success':'Password changed', 'username':username} def get_expiry_date(username): @@ -66,30 +64,64 @@ def get_expiry_date(username): else: return user.expiry_date + class UserName: def __init__(self, username): self.username = username + def contains_chinese(self): + for char in self.username: + # Check if the character is in the CJK (Chinese, Japanese, Korean) Unicode block + if unicodedata.name(char).startswith('CJK UNIFIED IDEOGRAPH'): + return True + return False + def validate(self): if len(self.username) > 20: return f'{self.username} is too long. The user name cannot exceed 20 characters.' - if self.username.startswith('.'): # a user name must not start with a dot + if self.username.startswith('.'): # a user name must not start with a dot return 'Period (.) is not allowed as the first letter in the user name.' - if ' ' in self.username: # a user name must not include a whitespace + if ' ' in self.username: # a user name must not include a whitespace return 'Whitespace is not allowed in the user name.' - for c in self.username: # a user name must not include special characters, except non-leading periods or underscores + for c in self.username: # a user name must not include special characters, except non-leading periods or underscores if c in string.punctuation and c != '.' and c != '_': return f'{c} is not allowed in the user name.' - if self.username in ['signup', 'login', 'logout', 'reset', 'mark', 'back', 'unfamiliar', 'familiar', 'del', 'admin']: + if self.username in ['signup', 'login', 'logout', 'reset', 'mark', 'back', 'unfamiliar', 'familiar', 'del', + 'admin']: return 'You used a restricted word as your user name. Please come up with a better one.' + if self.contains_chinese(): + return 'Chinese characters are not allowed in the user name.' + return 'OK' + +class Password: + def __init__(self, password): + self.password = password + + def contains_chinese(self): + for char in self.password: + # Check if the character is in the CJK (Chinese, Japanese, Korean) Unicode block + if unicodedata.name(char).startswith('CJK UNIFIED IDEOGRAPH'): + return True + return False + + def validate(self): + if len(self.password) < 4: + return 'Password must be at least 4 characters long.' + if ' ' in self.password: + return 'Password cannot contain spaces.' + if self.contains_chinese(): + return 'Chinese characters are not allowed in the password.' return 'OK' class WarningMessage: - def __init__(self, s): + def __init__(self, s, type='username'): self.s = s + self.type = type def __str__(self): - return UserName(self.s).validate() - + if self.type == 'username': + return UserName(self.s).validate() + if self.type == 'password': + return Password(self.s).validate() diff --git a/app/UseSqlite.py b/app/UseSqlite.py deleted file mode 100644 index ea4baeb..0000000 --- a/app/UseSqlite.py +++ /dev/null @@ -1,87 +0,0 @@ -########################################################################### -# Copyright 2019 (C) Hui Lan -# Written permission must be obtained from the author for commercial uses. -########################################################################### - - -# Reference: Dusty Phillips. Python 3 Objected-oriented Programming Second Edition. Pages 326-328. -# Copyright (C) 2019 Hui Lan - -import sqlite3 - -class Sqlite3Template: - def __init__(self, db_fname): - self.db_fname = db_fname - - def connect(self, db_fname): - self.conn = sqlite3.connect(self.db_fname) - - def instructions(self, query_statement): - raise NotImplementedError() - - def operate(self): - self.conn.row_factory = sqlite3.Row - self.results = self.conn.execute(self.query) # self.query is to be given in the child classes - self.conn.commit() - - def format_results(self): - raise NotImplementedError() - - def do(self): - self.connect(self.db_fname) - self.instructions(self.query) - self.operate() - - def instructions_with_parameters(self, query_statement, parameters): - self.query = query_statement - self.parameters = parameters - - def do_with_parameters(self): - self.connect(self.db_fname) - self.instructions_with_parameters(self.query, self.parameters) - self.operate_with_parameters() - - def operate_with_parameters(self): - self.conn.row_factory = sqlite3.Row - self.results = self.conn.execute(self.query, self.parameters) # self.query is to be given in the child classes - self.conn.commit() - - -class InsertQuery(Sqlite3Template): - def instructions(self, query): - self.query = query - - -class RecordQuery(Sqlite3Template): - def instructions(self, query): - self.query = query - - def format_results(self): - output = [] - for row_dict in self.results.fetchall(): - lst = [] - for k in dict(row_dict): - lst.append( row_dict[k] ) - output.append(', '.join(lst)) - return '\n\n'.join(output) - - def get_results(self): - result = [] - for row_dict in self.results.fetchall(): - result.append( dict(row_dict) ) - return result - - - -if __name__ == '__main__': - - #iq = InsertQuery('RiskDB.db') - #iq.instructions("INSERT INTO inspection Values ('FoodSupplies', 'RI2019051301', '2019-05-13', '{}')") - #iq.do() - #iq.instructions("INSERT INTO inspection Values ('CarSupplies', 'RI2019051302', '2019-05-13', '{[{\"risk_name\":\"elevator\"}]}')") - #iq.do() - - rq = RecordQuery('wordfreqapp.db') - rq.instructions("SELECT * FROM article WHERE level=3") - rq.do() - #print(rq.format_results()) diff --git a/app/account_service.py b/app/account_service.py index a7ed0c4..a57be5c 100644 --- a/app/account_service.py +++ b/app/account_service.py @@ -1,7 +1,7 @@ from flask import * +from markupsafe import escape from Login import check_username_availability, verify_user, add_user, get_expiry_date, change_password, WarningMessage - # 初始化蓝图 accountService = Blueprint("accountService", __name__) @@ -43,7 +43,6 @@ def signup(): return jsonify({'status': '1'}) - @accountService.route("/login", methods=['GET', 'POST']) def login(): ''' @@ -59,17 +58,48 @@ def login(): username = escape(request.form['username']) password = escape(request.form['password']) verified = verify_user(username, password) - if verified: - # 登录成功,写入session - session['logged_in'] = True - session[username] = username - session['username'] = username - user_expiry_date = get_expiry_date(username) - session['expiry_date'] = user_expiry_date - session['visited_articles'] = None - return jsonify({'status': '1'}) - else: - return jsonify({'status': '0'}) + #读black.txt文件判断用户是否在黑名单中 + with open('black.txt') as f: + for line in f: + line = line.strip() + if username == line: + return jsonify({'status': '5'}) + with open('black.txt', 'a+') as f: + f.seek(0) + lines = f.readlines() + line=[] + for i in lines: + line.append(i.strip('\n')) + #读black.txt文件判断用户是否在黑名单中 + if verified and username not in line: #TODO: 一个用户名是另外一个用户名的子串怎么办? + # 登录成功,写入session + session['logged_in'] = True + session[username] = username + session['username'] = username + user_expiry_date = get_expiry_date(username) + session['expiry_date'] = user_expiry_date + session['visited_articles'] = None + f.close() + return jsonify({'status': '1'}) + elif verified==0 and password!='黑名单': + #输入错误密码次数小于5次 + return jsonify({'status': '0'}) + else: + #输入错误密码次数达到5次 + with open('black.txt', 'a+') as f: + f.seek(0) + lines = f.readlines() + line = [] + for i in lines: + line.append(i.strip('\n')) + if username in line: + return jsonify({'status': '5'}) + else: + f.write(username) + f.write('\n') + return jsonify({'status': '5'}) + + @accountService.route("/logout", methods=['GET', 'POST']) @@ -83,6 +113,7 @@ def logout(): return redirect(url_for('mainpage')) + @accountService.route("/reset", methods=['GET', 'POST']) def reset(): ''' @@ -102,9 +133,7 @@ def reset(): # POST请求用于提交修改后信息 old_password = escape(request.form['old-password']) new_password = escape(request.form['new-password']) - flag = change_password(username, old_password, new_password) # flag表示是否修改成功 - if flag: - session['logged_in'] = False - return jsonify({'status':'1'}) # 修改成功 - else: - return jsonify({'status':'2'}) # 修改失败 + result = change_password(username, old_password, new_password) + return jsonify(result) + + diff --git a/app/admin_service.py b/app/admin_service.py index a604b5e..2a295af 100644 --- a/app/admin_service.py +++ b/app/admin_service.py @@ -1,5 +1,6 @@ # System Library from flask import * +from markupsafe import escape # Personal library from Yaml import yml @@ -37,6 +38,22 @@ def admin(): @adminService.route("/admin/article", methods=["GET", "POST"]) def article(): + + def _make_title_and_content(article_lst): + for article in article_lst: + text = escape(article.text) # Fix XSS vulnerability, contributed by Xu Xuan + article.title = text.split("\n")[0] + article.content = '
'.join(text.split("\n")[1:]) + + + def _update_context(): + article_len = get_number_of_articles() + context["article_number"] = article_len + context["text_list"] = get_page_articles(_cur_page, _page_size) + _articles = get_page_articles(_cur_page, _page_size) + _make_title_and_content(_articles) + context["text_list"] = _articles + global _cur_page, _page_size is_admin = check_is_admin() @@ -44,20 +61,15 @@ def article(): return is_admin _article_number = get_number_of_articles() + try: - _page_size = min( - max(1, int(request.args.get("size", 5))), _article_number - ) # 最小的size是1 - _cur_page = min( - max(1, int(request.args.get("page", 1))), _article_number // _page_size + (_article_number % _page_size > 0) - ) # 最小的page是1 + _page_size = min(max(1, int(request.args.get("size", 5))), _article_number) # 最小的size是1 + _cur_page = min(max(1, int(request.args.get("page", 1))), _article_number // _page_size + (_article_number % _page_size > 0)) # 最小的page是1 except ValueError: - return "page parmas must be int!" - + return "page parameters must be integer!" + _articles = get_page_articles(_cur_page, _page_size) - for article in _articles: # 获取每篇文章的title - article.title = article.text.split("\n")[0] - article.content = '
'.join(article.text.split("\n")[1:]) + _make_title_and_content(_articles) context = { "article_number": _article_number, @@ -67,25 +79,18 @@ def article(): "username": session.get("username"), } - def _update_context(): - article_len = get_number_of_articles() - context["article_number"] = article_len - context["text_list"] = get_page_articles(_cur_page, _page_size) - _articles = get_page_articles(_cur_page, _page_size) - for article in _articles: # 获取每篇文章的title - article.title = article.text.split("\n")[0] - context["text_list"] = _articles - - if request.method == "GET": - try: - delete_id = int(request.args.get("delete_id", 0)) - except: - return "Delete article ID must be int!" - if delete_id: # delete article - delete_article_by_id(delete_id) - _update_context() - elif request.method == "POST": + if request.method == "POST": data = request.form + + if "delete_id" in data: + try: + delete_id = int(data["delete_id"]) # 转成int型 + delete_article_by_id(delete_id) # 根据id删除article + flash(f'Article ID {delete_id} deleted successfully.') # 刷新页首提示语 + _update_context() + except ValueError: + flash('Invalid article ID for deletion.') # 刷新页首提示语 + content = data.get("content", "") source = data.get("source", "") question = data.get("question", "") @@ -94,9 +99,10 @@ def article(): if level not in ['1', '2', '3', '4']: return "Level must be between 1 and 4." add_article(content, source, level, question) - _update_context() title = content.split('\n')[0] flash(f'Article added. Title: {title}') + _update_context() # 这行应在flash之后 否则会发生新建的文章即点即删 + return render_template("admin_manage_article.html", **context) diff --git a/app/api_service.py b/app/api_service.py new file mode 100644 index 0000000..fd88681 --- /dev/null +++ b/app/api_service.py @@ -0,0 +1,31 @@ +from flask import * +from flask_httpauth import HTTPTokenAuth +from Article import load_freq_history + +path_prefix = '/var/www/wordfreq/wordfreq/' +path_prefix = './' # comment this line in deployment + +apiService = Blueprint('site',__name__) + +auth = HTTPTokenAuth(scheme='Bearer') + +tokens = { + "token": "token", + "secret-token": "lanhui" # token, username +} + + +@auth.verify_token +def verify_token(token): + if token in tokens: + return tokens[token] + + +@apiService.route('/api/mywords') # HTTPie usage: http -A bearer -a secret-token http://127.0.0.1:5000/api/mywords +@auth.login_required +def show(): + username = auth.current_user() + word_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username) + d = load_freq_history(word_freq_record) + return jsonify(d) + diff --git a/app/black.txt b/app/black.txt new file mode 100644 index 0000000..daa84a2 --- /dev/null +++ b/app/black.txt @@ -0,0 +1 @@ +hsy diff --git a/app/db/README.txt b/app/db/README.txt new file mode 100644 index 0000000..bb826a6 --- /dev/null +++ b/app/db/README.txt @@ -0,0 +1 @@ +Put wordfreqapp.db here diff --git a/app/db/oxford_words.txt b/app/db/oxford_words.txt new file mode 100644 index 0000000..62a95f9 --- /dev/null +++ b/app/db/oxford_words.txt @@ -0,0 +1,5942 @@ +abandon verb B2 +ability noun A2 +able adjective A2 +abolish verb C1 +abortion noun C1 +about adverb A1 +about preposition A1 +above adverb A1 +above preposition A1 +abroad adverb A2 +absence noun C1 +absent adjective C1 +absolute adjective B2 +absolutely adverb B1 +absorb verb B2 +abstract adjective B2 +absurd adjective C1 +abundance noun C1 +abuse noun C1 +abuse verb C1 +academic adjective B1 +academic noun B2 +academy noun C1 +accelerate verb C1 +accent noun B2 +accept verb A2 +acceptable adjective B2 +acceptance noun C1 +access noun B1 +access verb B1 +accessible adjective C1 +accident noun A2 +accidentally adverb B2 +accommodate verb B2 +accommodation noun B1 +accompany verb B2 +accomplish verb B2 +accomplishment noun C1 +accordance noun C1 +according to preposition A2 +accordingly adverb C1 +account noun B1 +account verb B2 +accountability noun C1 +accountable adjective C1 +accountant noun B2 +accumulate verb C1 +accumulation noun C1 +accuracy noun B2 +accurate adjective B2 +accurately adverb B2 +accusation noun C1 +accuse verb B2 +accused noun C1 +achieve verb A2 +achievement noun B1 +acid adjective C1 +acid noun B2 +acknowledge verb B2 +acquire verb B2 +acquisition noun C1 +acre noun C1 +across adverb A1 +across preposition A1 +act noun B1 +act verb A2 +action noun A1 +activate verb B2 +activation noun C1 +active adjective A2 +activist noun C1 +activity noun A1 +actor noun A1 +actress noun A1 +actual adjective B2 +actually adverb A2 +acute adjective C1 +ad noun B1 +adapt verb B2 +adaptation noun C1 +add verb A1 +addiction noun B2 +addition noun B1 +additional adjective B2 +additionally adverb B2 +address noun A1 +address verb B2 +adequate adjective B2 +adequately adverb B2 +adhere verb C1 +adjacent adjective C1 +adjust verb B2 +adjustment noun C1 +administer verb C1 +administration noun B2 +administrative adjective C1 +administrator noun C1 +admire verb B1 +admission noun C1 +admit verb B1 +adolescent noun C1 +adopt verb B2 +adoption noun C1 +adult adjective A2 +adult noun A1 +advance adjective B2 +advance noun B2 +advance verb B2 +advanced adjective B1 +advantage noun A2 +adventure noun A2 +adverse adjective C1 +advertise verb A2 +advertisement noun A2 +advertising noun A2 +advice noun A1 +advise verb B1 +advocate noun C1 +advocate verb C1 +aesthetic adjective C1 +affair noun B2 +affect verb A2 +affection noun C1 +afford verb B1 +affordable adjective B2 +afraid adjective A1 +after adverb A2 +after conjunction A2 +after preposition A1 +aftermath noun C1 +afternoon noun A1 +afterwards adverb B2 +again adverb A1 +against preposition A2 +age noun A1 +age verb B1 +aged adjective B1 +agency noun B2 +agenda noun B2 +agent noun B1 +aggression noun C1 +aggressive adjective B2 +ago adverb A1 +agree verb A1 +agreement noun B1 +agricultural adjective C1 +agriculture noun B2 +ah exclamation A2 +ahead adverb B1 +aid noun B2 +aid verb B2 +aide noun C1 +AIDS noun B2 +aim noun B1 +aim verb B1 +air noun A1 +aircraft noun B2 +airline noun A2 +airport noun A1 +alarm noun B1 +alarm verb B2 +albeit conjunction C1 +album noun B1 +alcohol noun B1 +alcoholic adjective B1 +alert adjective C1 +alert noun C1 +alert verb C1 +alien adjective C1 +alien noun B2 +align verb C1 +alignment noun C1 +alike adjective C1 +alike adverb C1 +alive adjective A2 +all adverb A2 +all determiner A1 +all pronoun A1 +all right adjective A2 +all right adverb A2 +all right exclamation A2 +allegation noun C1 +allege verb C1 +allegedly adverb C1 +alliance noun C1 +allocate verb C1 +allocation noun C1 +allow verb A2 +allowance noun C1 +ally noun C1 +almost adverb A2 +alone adjective A2 +alone adverb A2 +along adverb A2 +along preposition A2 +alongside preposition B2 +already adverb A2 +also adverb A1 +alter verb B2 +alternative adjective B1 +alternative noun A2 +although conjunction A2 +altogether adverb B2 +aluminium noun C1 +always adverb A1 +amateur adjective C1 +amateur noun C1 +amazed adjective B1 +amazing adjective A1 +ambassador noun C1 +ambition noun B1 +ambitious adjective B1 +ambulance noun B2 +amend verb C1 +amendment noun C1 +amid preposition C1 +among preposition A2 +amount noun A2 +amount verb B2 +amusing adjective B2 +analogy noun C1 +analyse verb B1 +analysis noun B1 +analyst noun B2 +ancestor noun B2 +anchor noun C1 +ancient adjective A2 +and conjunction A1 +angel noun C1 +anger noun B2 +angle noun B2 +angry adjective A1 +animal noun A1 +animation noun B2 +ankle noun A2 +anniversary noun B2 +announ ce verb B1 +announ cement noun B1 +annoy verb B1 +annoyed adjective B1 +annoying adjective B1 +annual adjective B2 +annually adverb B2 +anonymous adjective C1 +another determiner A1 +another pronoun A1 +answer noun A1 +answer verb A1 +anticipate verb B2 +anxiety noun B2 +anxious adjective B2 +any adverb A2 +any determiner A1 +any pronoun A1 +any more adverb A2 +anybody pronoun A2 +anyone pronoun A1 +anything pronoun A1 +anyway adverb A2 +anywhere adverb A2 +anywhere pronoun A2 +apart adverb B1 +apartment noun A1 +apologize verb B1 +apology noun B2 +app noun A2 +apparatus noun C1 +apparent adjective B2 +apparently adverb B2 +appeal noun B2 +appeal verb B2 +appealing adjective C1 +appear verb A2 +appearance noun A2 +appetite noun C1 +applaud verb C1 +apple noun A1 +applicable adjective C1 +applicant noun B2 +application noun B1 +apply verb A2 +appoint verb C1 +appointment noun B1 +appreciate verb B1 +appreciation noun C1 +approach noun B2 +approach verb B2 +appropriate adjective B2 +appropriately adverb B2 +approval noun B2 +approve verb B2 +approximately adverb B1 +April noun A1 +arbitrary adjective C1 +architect noun A2 +architectural adjective C1 +architecture noun A2 +archive noun C1 +area noun A1 +arena noun C1 +arguably adverb C1 +argue verb A2 +argument noun A2 +arise verb B2 +arm noun A1 +arm verb C1 +armed adjective B2 +arms noun B2 +army noun A2 +around adverb A1 +around preposition A1 +arrange verb A2 +arrangement noun A2 +array noun C1 +arrest noun B1 +arrest verb B1 +arrival noun B1 +arrive verb A1 +arrow noun B2 +art noun A1 +article noun A1 +articulate verb C1 +artificial adjective B2 +artist noun A1 +artistic adjective B2 +artwork noun B2 +as adverb A2 +as conjunction A2 +as preposition A1 +ash noun C1 +ashamed adjective B2 +aside adverb B2 +ask verb A1 +asleep adjective A2 +aspect noun B2 +aspiration noun C1 +aspire verb C1 +assassination noun C1 +assault noun C1 +assault verb C1 +assemble verb C1 +assembly noun C1 +assert verb C1 +assertion noun C1 +assess verb B2 +assessment noun B2 +asset noun B2 +assign verb B2 +assignment noun B1 +assist verb B1 +assistance noun B2 +assistant adjective A2 +assistant noun A2 +associate verb B2 +associated adjective B2 +association noun B2 +assume verb B2 +assumption noun B2 +assurance noun C1 +assure verb B2 +astonishing adjective B2 +asylum noun C1 +at preposition A1 +athlete noun A2 +atmosphere noun B1 +atrocity noun C1 +attach verb B1 +attachment noun B2 +attack noun A2 +attack verb A2 +attain verb C1 +attempt noun B2 +attempt verb B2 +attend verb A2 +attendance noun C1 +attention exclamation A2 +attention noun A2 +attitude noun B1 +attorney noun C1 +attract verb B1 +attraction noun B1 +attractive adjective A2 +attribute noun C1 +attribute verb C1 +auction noun B2 +audience noun A2 +audio adjective B2 +audit noun C1 +August noun A1 +aunt noun A1 +authentic adjective C1 +author noun A2 +authority noun B1 +authorize verb C1 +auto noun C1 +automatic adjective B2 +automatically adverb B2 +autonomy noun C1 +autumn noun A1 +availability noun C1 +available adjective A2 +average adjective A2 +average noun A2 +average verb B1 +avoid verb A2 +await verb C1 +award noun A2 +award verb B1 +aware adjective B1 +awareness noun B2 +away adverb A1 +awful adjective A2 +awkward adjective B2 +baby noun A1 +back adjective A2 +back adverb A1 +back noun A1 +back verb B2 +backdrop noun C1 +background noun A2 +backing noun C1 +backup noun C1 +backwards adverb B1 +bacteria noun B2 +bad adjective A1 +badge noun B2 +badly adverb A2 +bag noun A1 +bail noun C1 +bake verb B1 +balance noun B1 +balance verb B1 +balanced adjective B2 +ball noun A1 +ballet noun B2 +balloon noun B2 +ballot noun C1 +ban noun B1 +ban verb B1 +banana noun A1 +band noun A1 +bank noun A1 +banner noun C1 +bar noun A2 +bar verb B2 +bare adjective C1 +barely adverb B2 +bargain noun B2 +barrel noun C1 +barrier noun B2 +base noun B1 +base verb B1 +baseball noun A2 +based adjective A2 +basement noun B2 +basic adjective B1 +basically adverb B2 +basis noun B1 +basket noun B2 +basketball noun A2 +bass noun C1 +bat noun B2 +bat verb C1 +bath noun A1 +bathroom noun A1 +battery noun B1 +battle noun B1 +battle verb B2 +battlefield noun C1 +bay noun C1 +be verb A1 +be auxiliary verb A1 +beach noun A1 +beam noun C1 +bean noun A2 +bear noun A2 +bear verb B2 +beast noun C1 +beat noun B2 +beat verb A2 +beautiful adjective A1 +beauty noun B1 +because conjunction A1 +become verb A1 +bed noun A1 +bedroom noun A1 +bee noun B1 +beef noun A2 +beer noun A1 +before adverb A2 +before conjunction A2 +before preposition A1 +beg verb B2 +begin verb A1 +beginning noun A1 +behalf noun C1 +behave verb A2 +behaviour noun A2 +behind adverb A1 +behind preposition A1 +being noun B2 +belief noun B1 +believe verb A1 +bell noun B1 +belong verb A2 +beloved adjective C1 +below adverb A1 +below preposition A1 +belt noun A2 +bench noun C1 +benchmark noun C1 +bend noun B1 +bend verb B1 +beneath preposition C1 +beneficial adjective B2 +beneficiary noun C1 +benefit noun A2 +benefit verb B1 +bent adjective B2 +beside preposition B2 +besides adverb B2 +besides preposition B2 +best adjective A1 +best adverb A2 +best noun A2 +bet noun B2 +bet verb B2 +betray verb C1 +better adjective A1 +better adverb A2 +better noun B1 +between adverb A2 +between preposition A1 +beyond adverb B2 +beyond preposition B2 +bias noun B2 +bicycle noun A1 +bid noun B2 +bid verb B2 +big adjective A1 +bike noun A1 +bill noun A1 +bill verb B2 +billion number A2 +bin noun A2 +bind verb C1 +biography noun C1 +biological adjective B2 +biology noun A2 +bird noun A1 +birth noun A2 +birthday noun A1 +biscuit noun A2 +bishop noun C1 +bit noun A2 +bite noun B1 +bite verb B1 +bitter adjective B2 +bizarre adjective C1 +black adjective A1 +black noun A1 +blade noun C1 +blame noun B2 +blame verb B2 +blank adjective A2 +blank noun A2 +blanket noun B2 +blast noun C1 +blast verb C1 +bleed verb C1 +blend noun C1 +blend verb C1 +bless verb C1 +blessing noun C1 +blind adjective B2 +block noun B1 +block verb B1 +blog noun A1 +blonde adjective A1 +blood noun A2 +blow noun B2 +blow verb A2 +blue adjective A1 +blue noun A1 +board noun A2 +board verb B1 +boast verb C1 +boat noun A1 +body noun A1 +boil verb A2 +bold adjective B2 +bomb noun B1 +bomb verb B1 +bombing noun B2 +bond noun B2 +bone noun A2 +bonus noun C1 +book noun A1 +book verb A2 +booking noun B2 +boom noun C1 +boost noun B2 +boost verb B2 +boot noun A1 +border noun B1 +border verb B2 +bored adjective A1 +boring adjective A1 +born verb A1 +borrow verb A2 +boss noun A2 +both determiner A1 +both pronoun A1 +bother verb B1 +bottle noun A1 +bottom adjective A2 +bottom noun A2 +bounce verb C1 +bound adjective B2 +boundary noun C1 +bow noun C1 +bow verb C1 +bowl noun A2 +box noun A1 +boy noun A1 +boyfriend noun A1 +brain noun A2 +branch noun B1 +brand noun B1 +brand verb B1 +brave adjective B1 +breach noun C1 +breach verb C1 +bread noun A1 +break noun A1 +break verb A1 +breakdown noun C1 +breakfast noun A1 +breakthrough noun C1 +breast noun B2 +breath noun B1 +breathe verb B1 +breathing noun B1 +breed noun C1 +breed verb C1 +brick noun B2 +bride noun B1 +bridge noun A2 +brief adjective B2 +briefly adverb B2 +bright adjective A2 +brilliant adjective A2 +bring verb A1 +broad adjective B2 +broadband noun C1 +broadcast noun B2 +broadcast verb B2 +broadcaster noun B2 +broadly adverb B2 +broken adjective A2 +brother noun A1 +brown adjective A1 +brown noun A1 +browser noun C1 +brush noun A2 +brush verb A2 +brutal adjective C1 +bubble noun B1 +buck noun C1 +buddy noun C1 +budget noun B2 +buffer noun C1 +bug noun B2 +build verb A1 +building noun A1 +bulk noun C1 +bullet noun B2 +bunch noun B2 +burden noun C1 +bureaucracy noun C1 +burial noun C1 +burn noun B2 +burn verb A2 +burst verb C1 +bury verb B1 +bus noun A1 +bush noun B2 +business noun A1 +businessman noun A2 +busy adjective A1 +but conjunction A1 +but preposition B2 +butter noun A1 +button noun A2 +buy verb A1 +by adverb B1 +by preposition A1 +bye exclamation A1 +cabin noun B2 +cabinet noun C1 +cable noun B2 +cafe noun A1 +cake noun A1 +calculate verb B2 +calculation noun C1 +call noun A1 +call verb A1 +calm adjective B1 +calm noun B1 +calm verb B1 +camera noun A1 +camp noun A2 +camp verb A2 +campaign noun B1 +campaign verb B1 +camping noun A2 +campus noun B1 +can noun A2 +can modal verb A1 +canal noun B2 +cancel verb B2 +cancer noun B2 +candidate noun B1 +candle noun B2 +cannot modal verb A1 +canvas noun C1 +cap noun B1 +capability noun C1 +capable adjective B2 +capacity noun B2 +capital adjective A1 +capital noun A1 +capitalism noun C1 +capitalist adjective C1 +captain noun B1 +capture noun B2 +capture verb B2 +car noun A1 +carbon noun B2 +card noun A1 +care noun A2 +care verb A2 +career noun A1 +careful adjective A2 +carefully adverb A2 +careless adjective B1 +cargo noun C1 +carpet noun A2 +carriage noun C1 +carrot noun A1 +carry verb A1 +cartoon noun A2 +carve verb C1 +case noun A2 +cash noun A2 +casino noun C1 +cast noun B2 +cast verb B2 +castle noun A2 +casual adjective B2 +casualty noun C1 +cat noun A1 +catalogue noun C1 +catch noun B2 +catch verb A2 +category noun B1 +cater verb C1 +cattle noun C1 +cause noun A2 +cause verb A2 +caution noun C1 +cautious adjective C1 +cave noun B2 +CD noun A1 +cease verb C1 +ceiling noun B1 +celebrate verb A2 +celebration noun B1 +celebrity noun A2 +cell noun B2 +cemetery noun C1 +cent noun A1 +central adjective B1 +centre noun A1 +centre verb B1 +century noun A1 +ceremony noun B1 +certain adjective A2 +certainly adverb A2 +certainty noun B2 +certificate noun B2 +chain noun B1 +chain verb B2 +chair noun A1 +chair verb B2 +chairman noun B2 +challenge noun B1 +challenge verb B2 +challenging adjective B2 +chamber noun C1 +champion noun B1 +championship noun B2 +chance noun A2 +change noun A1 +change verb A1 +channel noun B1 +chaos noun C1 +chapter noun B1 +character noun A2 +characteristic adjective B2 +characteristic noun B2 +characterize verb C1 +charge noun B1 +charge verb B1 +charity noun A2 +charm noun C1 +charming adjective B2 +chart noun A1 +chart verb B2 +charter noun C1 +chase noun B2 +chase verb B2 +chat noun A2 +chat verb A2 +cheap adjective A1 +cheap adverb B1 +cheat noun B1 +cheat verb B1 +check noun A2 +check verb A1 +cheek noun B2 +cheer noun B2 +cheer verb B2 +cheerful adjective B1 +cheese noun A1 +chef noun A2 +chemical adjective B1 +chemical noun B1 +chemistry noun A2 +chest noun B1 +chicken noun A1 +chief adjective B2 +chief noun B2 +child noun A1 +childhood noun B1 +chip noun A2 +chocolate noun A1 +choice noun A2 +choir noun B2 +choose verb A1 +chop verb B2 +chronic adjective C1 +chunk noun C1 +church noun A2 +cigarette noun A2 +cinema noun A1 +circle noun A2 +circle verb A2 +circuit noun B2 +circulate verb C1 +circulation noun C1 +circumstance noun B2 +cite verb B2 +citizen noun B2 +citizenship noun C1 +city noun A1 +civic adjective C1 +civil adjective B2 +civilian adjective C1 +civilian noun C1 +civilization noun B2 +claim noun B1 +claim verb B1 +clarify verb B2 +clarity noun C1 +clash noun C1 +class noun A1 +classic adjective B2 +classic noun B2 +classical adjective A2 +classification noun C1 +classify verb B2 +classroom noun A1 +clause noun B1 +clean adjective A1 +clean verb A1 +clear adjective A2 +clear verb B1 +clearly adverb A2 +clerk noun B2 +clever adjective A2 +click noun B1 +click verb B1 +client noun B1 +cliff noun B2 +climate noun A2 +climb noun B1 +climb verb A1 +cling verb C1 +clinic noun B2 +clinical adjective C1 +clip noun B2 +clock noun A1 +close adjective A2 +close adverb B1 +close noun B2 +close verb A1 +closed adjective A2 +closely adverb B2 +closure noun C1 +cloth noun B1 +clothes noun A1 +clothing noun A2 +cloud noun A2 +club noun A1 +clue noun B1 +cluster noun C1 +coach noun A2 +coach verb B1 +coal noun B1 +coalition noun C1 +coast noun A2 +coastal adjective C1 +coat noun A1 +cocktail noun C1 +code noun A2 +coffee noun A1 +cognitive adjective C1 +coin noun B1 +coincide verb C1 +coincidence noun B2 +cold adjective A1 +cold noun A1 +collaborate verb C1 +collaboration noun C1 +collapse noun B2 +collapse verb B2 +colleague noun A2 +collect verb A2 +collection noun B1 +collective adjective C1 +collector noun B2 +college noun A1 +collision noun C1 +colonial adjective C1 +colony noun B2 +colour noun A1 +coloured adjective B1 +colourful adjective B2 +column noun A2 +columnist noun C1 +combat noun C1 +combat verb C1 +combination noun B2 +combine verb B1 +come verb A1 +comedy noun A2 +comfort noun B2 +comfort verb B2 +comfortable adjective A2 +comic adjective B2 +comic noun B2 +command noun B2 +command verb B2 +commander noun B2 +commence verb C1 +comment noun A2 +comment verb B1 +commentary noun C1 +commentator noun C1 +commerce noun C1 +commercial adjective B1 +commercial noun B1 +commission noun B2 +commission verb B2 +commissioner noun C1 +commit verb B1 +commitment noun B2 +committee noun B2 +commodity noun C1 +common adjective A1 +commonly adverb B2 +communicate verb A2 +communication noun B1 +communist adjective C1 +community noun A2 +companion noun C1 +company noun A1 +comparable adjective C1 +comparative adjective B2 +compare verb A1 +comparison noun B1 +compassion noun C1 +compel verb C1 +compelling adjective C1 +compensate verb C1 +compensation noun C1 +compete verb A2 +competence noun C1 +competent adjective C1 +competition noun A2 +competitive adjective B1 +competitor noun B1 +compile verb C1 +complain verb A2 +complaint noun B1 +complement verb C1 +complete adjective A1 +complete verb A1 +completely adverb A2 +completion noun B2 +complex adjective B1 +complex noun B2 +complexity noun C1 +compliance noun C1 +complicated adjective B2 +complication noun C1 +comply verb C1 +component noun B2 +compose verb B2 +composer noun B2 +composition noun C1 +compound noun B2 +comprehensive adjective B2 +comprise verb B2 +compromise noun C1 +compromise verb C1 +compulsory adjective B2 +compute verb C1 +computer noun A1 +conceal verb C1 +concede verb C1 +conceive verb C1 +concentrate verb B1 +concentration noun B2 +concept noun B2 +conception noun C1 +concern noun B2 +concern verb B2 +concerned adjective B2 +concert noun A1 +concession noun C1 +conclude verb B1 +conclusion noun B1 +concrete adjective B2 +concrete noun B2 +condemn verb C1 +condition noun A2 +conduct noun B2 +conduct verb B2 +confer verb C1 +conference noun A2 +confess verb B2 +confession noun C1 +confidence noun B2 +confident adjective B1 +configuration noun C1 +confine verb C1 +confirm verb B1 +confirmation noun C1 +conflict noun B2 +conflict verb B2 +confront verb C1 +confrontation noun C1 +confuse verb B1 +confused adjective B1 +confusing adjective B2 +confusion noun B2 +congratulate verb C1 +congregation noun C1 +congressional adjective C1 +connect verb A2 +connected adjective A2 +connection noun B1 +conquer verb C1 +conscience noun C1 +conscious adjective B2 +consciousness noun C1 +consecutive adjective C1 +consensus noun C1 +consent noun C1 +consent verb C1 +consequence noun B1 +consequently adverb B2 +conservation noun B2 +conservative adjective B2 +conservative noun B2 +conserve verb C1 +consider verb A2 +considerable adjective B2 +considerably adverb B2 +consideration noun B2 +consist verb B1 +consistency noun C1 +consistent adjective B2 +consistently adverb B2 +consolidate verb C1 +conspiracy noun B2 +constant adjective B2 +constantly adverb B2 +constituency noun C1 +constitute verb C1 +constitution noun C1 +constitutional adjective C1 +constraint noun C1 +construct verb B2 +construction noun B2 +consult verb B2 +consultant noun B2 +consultation noun C1 +consume verb B1 +consumer noun B1 +consumption noun B2 +contact noun B1 +contact verb B1 +contain verb A2 +container noun B1 +contemplate verb C1 +contemporary adjective B2 +contempt noun C1 +contend verb C1 +contender noun C1 +content adjective C1 +content noun B1 +contention noun C1 +contest noun B2 +contest verb B2 +context noun A2 +continent noun A2 +continually adverb C1 +continue verb A2 +continuous adjective B1 +contract noun B2 +contract verb B2 +contractor noun C1 +contradiction noun C1 +contrary adjective C1 +contrary noun C1 +contrast noun B1 +contrast verb B1 +contribute verb B2 +contribution noun B2 +contributor noun C1 +control noun A2 +control verb A2 +controversial adjective B2 +controversy noun B2 +convenience noun B2 +convenient adjective B1 +convention noun B2 +conventional adjective B2 +conversation noun A1 +conversion noun C1 +convert verb B2 +convey verb B2 +convict verb C1 +conviction noun C1 +convince verb B1 +convinced adjective B2 +convincing adjective B2 +cook noun A2 +cook verb A1 +cooker noun A2 +cooking noun A1 +cool adjective A1 +cool verb B1 +cooperate verb C1 +cooperative adjective C1 +coordinate verb C1 +coordination noun C1 +coordinator noun C1 +cop noun C1 +cope verb B2 +copper noun C1 +copy noun A2 +copy verb A2 +copyright noun C1 +core adjective B2 +core noun B2 +corner noun A2 +corporate adjective B2 +corporation noun B2 +correct adjective A1 +correct verb A1 +correction noun C1 +correctly adverb A2 +correlate verb C1 +correlation noun C1 +correspond verb C1 +correspondence noun C1 +correspondent noun C1 +corresponding adjective C1 +corridor noun B2 +corrupt adjective C1 +corruption noun C1 +cost noun A1 +cost verb A1 +costly adjective C1 +costume noun B1 +cottage noun B1 +cotton noun B1 +could modal verb A1 +council noun B2 +councillor noun C1 +counselling noun C1 +counsellor noun C1 +count noun B1 +count verb A2 +counter noun B2 +counter verb C1 +counterpart noun C1 +countless adjective C1 +country noun A1 +countryside noun B1 +county noun B2 +coup noun C1 +couple noun A2 +courage noun B2 +course noun A1 +court noun B1 +courtesy noun C1 +cousin noun A1 +cover noun B1 +cover verb A2 +coverage noun B2 +covered adjective B1 +cow noun A1 +crack noun B2 +crack verb B2 +craft noun B2 +craft verb C1 +crash noun B2 +crash verb B2 +crawl verb C1 +crazy adjective A2 +cream adjective B1 +cream noun A1 +create verb A1 +creation noun B2 +creative adjective A2 +creativity noun B2 +creator noun C1 +creature noun B2 +credibility noun C1 +credible adjective C1 +credit noun A2 +credit verb B2 +creep verb C1 +crew noun B2 +crime noun A2 +criminal adjective B1 +criminal noun A2 +crisis noun B2 +criterion noun B2 +critic noun B2 +critical adjective B2 +critically adverb B2 +criticism noun B2 +criticize verb B2 +critique noun C1 +crop noun B2 +cross noun A2 +cross verb A2 +crowd noun A2 +crowded adjective A2 +crown noun C1 +crucial adjective B2 +crude adjective C1 +cruel adjective B1 +cruise noun B2 +cruise verb B2 +crush verb C1 +cry noun B2 +cry verb A2 +crystal noun C1 +cue noun B2 +cult adjective C1 +cult noun C1 +cultivate verb C1 +cultural adjective B1 +culture noun A1 +cup noun A1 +cupboard noun A2 +cure noun B2 +cure verb B2 +curiosity noun C1 +curious adjective B2 +curly adjective A2 +currency noun B1 +current adjective B1 +current noun B2 +currently adverb B1 +curriculum noun B2 +curtain noun B1 +curve noun B2 +curve verb B2 +curved adjective B2 +custody noun C1 +custom noun B1 +customer noun A1 +cut noun B1 +cut verb A1 +cute adjective B2 +cutting noun C1 +cycle noun A2 +cycle verb A2 +cynical adjective C1 +dad noun A1 +daily adjective A2 +daily adverb B1 +dairy adjective B2 +dairy noun B2 +dam noun C1 +damage noun B1 +damage verb B1 +damaging adjective C1 +dance noun A1 +dance verb A1 +dancer noun A1 +dancing noun A1 +danger noun A2 +dangerous adjective A1 +dare verb B2 +dark adjective A1 +dark noun A2 +darkness noun B2 +data noun A2 +database noun B2 +date noun A1 +date verb B2 +daughter noun A1 +dawn noun C1 +day noun A1 +dead adjective A2 +deadline noun B2 +deadly adjective B2 +deal noun B1 +deal verb A2 +dealer noun B2 +dear adjective A1 +dear exclamation A2 +death noun A2 +debate noun B2 +debate verb B2 +debris noun C1 +debt noun B2 +debut noun C1 +decade noun B1 +December noun A1 +decent adjective B2 +decide verb A1 +decision noun A2 +decision-making noun C1 +decisive adjective C1 +deck noun B2 +declaration noun C1 +declare verb B2 +decline noun B2 +decline verb B2 +decorate verb B1 +decoration noun B2 +decrease noun B2 +decrease verb B2 +dedicated adjective C1 +dedication noun C1 +deed noun C1 +deem verb C1 +deep adjective A2 +deep adverb B1 +deeply adverb B2 +default noun C1 +defeat noun B2 +defeat verb B2 +defect noun C1 +defence noun B2 +defend verb B2 +defender noun B2 +defensive adjective C1 +deficiency noun C1 +deficit noun C1 +define verb B1 +definite adjective B1 +definitely adverb A2 +definition noun B1 +defy verb C1 +degree noun A2 +delay noun B2 +delay verb B2 +delegate noun C1 +delegation noun C1 +delete verb B2 +deliberate adjective B2 +deliberately adverb B2 +delicate adjective C1 +delicious adjective A1 +delight noun B2 +delight verb B2 +delighted adjective B2 +deliver verb B1 +delivery noun B2 +demand noun B2 +demand verb B2 +democracy noun B2 +democratic adjective B2 +demon noun C1 +demonstrate verb B2 +demonstration noun B2 +denial noun C1 +denoun ce verb C1 +dense adjective C1 +density noun C1 +dentist noun A2 +deny verb B2 +depart verb B2 +department noun A2 +departure noun B1 +depend verb A2 +dependence noun C1 +dependent adjective B2 +depict verb C1 +deploy verb C1 +deployment noun C1 +deposit noun B2 +deposit verb C1 +depressed adjective B2 +depressing adjective B2 +depression noun B2 +deprive verb C1 +depth noun B2 +deputy noun C1 +derive verb B2 +descend verb C1 +descent noun C1 +describe verb A1 +description noun A1 +desert noun A2 +desert verb B2 +deserve verb B2 +design noun A1 +design verb A1 +designate verb C1 +designer noun A2 +desirable adjective C1 +desire noun B2 +desire verb B2 +desk noun A1 +desktop noun C1 +desperate adjective B2 +desperately adverb B2 +despite preposition B1 +destination noun B1 +destroy verb A2 +destruction noun B2 +destructive adjective C1 +detail noun A1 +detail verb B2 +detailed adjective B2 +detain verb C1 +detect verb B2 +detection noun C1 +detective noun A2 +detention noun C1 +deteriorate verb C1 +determination noun B2 +determine verb B1 +determined adjective B1 +devastate verb C1 +develop verb A2 +development noun B1 +device noun A2 +devil noun C1 +devise verb C1 +devote verb B2 +diagnose verb C1 +diagnosis noun C1 +diagram noun B1 +dialogue noun A1 +diamond noun B1 +diary noun A2 +dictate verb C1 +dictator noun C1 +dictionary noun A1 +die verb A1 +diet noun A1 +differ verb B2 +difference noun A1 +different adjective A1 +differentiate verb C1 +differently adverb A2 +difficult adjective A1 +difficulty noun B1 +dig verb B2 +digital adjective A2 +dignity noun C1 +dilemma noun C1 +dimension noun C1 +diminish verb C1 +dinner noun A1 +dip verb C1 +diplomat noun C1 +diplomatic adjective C1 +direct adjective A2 +direct adverb B1 +direct verb B1 +direction noun A2 +directly adverb B1 +director noun A2 +directory noun C1 +dirt noun B1 +dirty adjective A1 +disability noun B2 +disabled adjective B2 +disadvantage noun B1 +disagree verb A2 +disagreement noun B2 +disappear verb A2 +disappoint verb B2 +disappointed adjective B1 +disappointing adjective B1 +disappointment noun B2 +disaster noun A2 +disastrous adjective C1 +disc noun B2 +discard verb C1 +discharge verb C1 +discipline noun B2 +disclose verb C1 +disclosure noun C1 +discount noun B1 +discount verb B2 +discourage verb B2 +discourse noun C1 +discover verb A2 +discovery noun A2 +discretion noun C1 +discrimination noun C1 +discuss verb A1 +discussion noun A2 +disease noun A2 +dish noun A1 +dishonest adjective B2 +disk noun B2 +dislike noun B1 +dislike verb B1 +dismiss verb B2 +dismissal noun C1 +disorder noun B2 +displace verb C1 +display noun B2 +display verb B2 +disposal noun C1 +dispose verb C1 +dispute noun C1 +dispute verb C1 +disrupt verb C1 +disruption noun C1 +dissolve verb C1 +distance noun A2 +distant adjective B2 +distinct adjective B2 +distinction noun C1 +distinctive adjective C1 +distinguish verb B2 +distort verb C1 +distract verb B2 +distress noun C1 +distress verb C1 +distribute verb B2 +distribution noun B2 +district noun B2 +disturb verb B2 +disturbing adjective C1 +dive noun B2 +dive verb B2 +diverse adjective B2 +diversity noun B2 +divert verb C1 +divide noun B2 +divide verb B1 +divine adjective C1 +division noun B2 +divorce noun B2 +divorce verb B2 +divorced adjective A2 +do verb A1 +do auxiliary verb A1 +doctor noun A1 +doctrine noun C1 +document noun A2 +document verb B2 +documentary noun B1 +documentation noun C1 +dog noun A1 +dollar noun A1 +domain noun C1 +domestic adjective B2 +dominance noun C1 +dominant adjective B2 +dominate verb B2 +donate verb B1 +donation noun B2 +donor noun C1 +door noun A1 +dose noun C1 +dot noun B2 +double adjective A2 +double adverb B1 +double determiner A2 +double pronoun A2 +double verb A2 +doubt noun B1 +doubt verb B1 +down adverb A1 +down preposition A1 +download noun A2 +download verb A2 +downstairs adjective A2 +downstairs adverb A1 +downtown adjective B2 +downtown adverb B2 +downtown noun B2 +downwards adverb B2 +dozen determiner B2 +dozen noun B2 +draft noun B2 +draft verb B2 +drag verb B2 +drain verb C1 +drama noun A2 +dramatic adjective B2 +dramatically adverb B2 +draw verb A1 +drawing noun A2 +dream noun A2 +dream verb A2 +dress noun A1 +dress verb A1 +dressed adjective B1 +drift verb C1 +drink noun A1 +drink verb A1 +drive noun A2 +drive verb A1 +driver noun A1 +driving adjective C1 +driving noun A2 +drop noun B1 +drop verb A2 +drought noun B2 +drown verb C1 +drug noun A2 +drum noun B1 +drunk adjective B1 +dry adjective A2 +dry verb A2 +dual adjective C1 +dub verb C1 +due adjective B1 +dull adjective B2 +dumb adjective C1 +dump verb B2 +duo noun C1 +duration noun B2 +during preposition A1 +dust noun B1 +duty noun B1 +DVD noun A1 +dynamic adjective B2 +dynamic noun C1 +each adverb A1 +each determiner A1 +each pronoun A1 +eager adjective C1 +ear noun A1 +early adjective A1 +early adverb A1 +earn verb A2 +earnings noun C1 +earth noun A2 +earthquake noun B1 +ease noun C1 +ease verb C1 +easily adverb A2 +east adjective A1 +east adverb A1 +east noun A1 +eastern adjective B1 +easy adjective A1 +eat verb A1 +echo noun C1 +echo verb C1 +ecological adjective C1 +economic adjective B1 +economics noun B2 +economist noun B2 +economy noun B1 +edge noun B1 +edit verb B2 +edition noun B2 +editor noun B1 +editorial adjective B2 +educate verb B1 +educated adjective B1 +education noun A2 +educational adjective B1 +educator noun C1 +effect noun A2 +effective adjective B1 +effectively adverb B1 +effectiveness noun C1 +efficiency noun C1 +efficient adjective B2 +efficiently adverb B2 +effort noun B1 +egg noun A1 +ego noun C1 +eight number A1 +eighteen number A1 +eighty number A1 +either adverb A2 +either determiner A2 +either pronoun A2 +elaborate adjective C1 +elbow noun B2 +elderly adjective B2 +elect verb B2 +election noun B1 +electoral adjective C1 +electric adjective A2 +electrical adjective A2 +electricity noun A2 +electronic adjective A2 +electronics noun B2 +elegant adjective B2 +element noun B1 +elementary adjective B2 +elephant noun A1 +elevate verb C1 +eleven number A1 +eligible adjective C1 +eliminate verb B2 +elite noun C1 +else adverb A1 +elsewhere adverb B2 +email noun A1 +email verb A1 +embark verb C1 +embarrassed adjective B1 +embarrassing adjective B1 +embarrassment noun C1 +embassy noun C1 +embed verb C1 +embody verb C1 +embrace verb B2 +emerge verb B2 +emergence noun C1 +emergency noun B1 +emission noun B2 +emotion noun B1 +emotional adjective B2 +emotionally adverb B2 +emphasis noun B2 +emphasize verb B2 +empire noun B2 +empirical adjective C1 +employ verb A2 +employee noun A2 +employer noun A2 +employment noun B1 +empower verb C1 +empty adjective A2 +empty verb B1 +enable verb B2 +enact verb C1 +encompass verb C1 +encounter noun B2 +encounter verb B2 +encourage verb B1 +encouragement noun C1 +encouraging adjective C1 +end noun A1 +end verb A1 +endeavour noun C1 +ending noun A2 +endless adjective C1 +endorse verb C1 +endorsement noun C1 +endure verb C1 +enemy noun B1 +energy noun A2 +enforce verb C1 +enforcement noun C1 +engage verb B2 +engaged adjective B1 +engagement noun C1 +engaging adjective C1 +engine noun A2 +engineer noun A2 +engineering noun B1 +enhance verb B2 +enjoy verb A1 +enjoyable adjective B2 +enormous adjective A2 +enough adverb A1 +enough determiner A1 +enough pronoun A1 +enquire verb C1 +enquiry noun B2 +enrich verb C1 +enrol verb C1 +ensue verb C1 +ensure verb B2 +enter verb A2 +enterprise noun C1 +entertain verb B1 +entertaining adjective B2 +entertainment noun B1 +enthusiasm noun B2 +enthusiast noun C1 +enthusiastic adjective B2 +entire adjective B2 +entirely adverb B2 +entitle verb C1 +entity noun C1 +entrance noun B1 +entrepreneur noun B2 +entry noun B1 +envelope noun B2 +environment noun A2 +environmental adjective B1 +epidemic noun C1 +episode noun B1 +equal adjective B1 +equal noun B2 +equal verb B1 +equality noun C1 +equally adverb B1 +equation noun C1 +equip verb B2 +equipment noun A2 +equivalent adjective B2 +equivalent noun B2 +era noun B2 +erect verb C1 +error noun A2 +erupt verb B2 +escalate verb C1 +escape noun B1 +escape verb B1 +especially adverb A2 +essay noun A2 +essence noun C1 +essential adjective B1 +essentially adverb B2 +establish verb B2 +establishment noun C1 +estate noun B2 +estimate noun B2 +estimate verb B2 +eternal adjective C1 +ethic noun B2 +ethical adjective B2 +ethnic adjective B2 +euro noun A1 +evacuate verb C1 +evaluate verb B2 +evaluation noun B2 +even adjective B2 +even adverb A1 +evening noun A1 +event noun A1 +eventually adverb B1 +ever adverb A1 +every determiner A1 +everybody pronoun A1 +everyday adjective A2 +everyone pronoun A1 +everything pronoun A1 +everywhere adverb A2 +evidence noun A2 +evident adjective B2 +evil adjective B2 +evil noun B2 +evoke verb C1 +evolution noun B2 +evolutionary adjective C1 +evolve verb B2 +exact adjective A2 +exactly adverb A2 +exaggerate verb C1 +exam noun A1 +examination noun B2 +examine verb B1 +example noun A1 +exceed verb B2 +excellence noun C1 +excellent adjective A2 +except conjunction B1 +except preposition A2 +exception noun B2 +exceptional adjective C1 +excess adjective C1 +excess noun C1 +excessive adjective B2 +exchange noun B1 +exchange verb B1 +excited adjective A1 +excitement noun B1 +exciting adjective A1 +exclude verb B2 +exclusion noun C1 +exclusive adjective C1 +exclusively adverb C1 +excuse noun B2 +excuse verb B2 +execute verb C1 +execution noun C1 +executive adjective B2 +executive noun B2 +exercise noun A1 +exercise verb A1 +exert verb C1 +exhibit noun B2 +exhibit verb B2 +exhibition noun B1 +exile noun C1 +exist verb A2 +existence noun B2 +exit noun B2 +exit verb C1 +exotic adjective B2 +expand verb B1 +expansion noun B2 +expect verb A2 +expectation noun B2 +expected adjective B1 +expedition noun B1 +expenditure noun C1 +expense noun B2 +expensive adjective A1 +experience noun A2 +experience verb B1 +experienced adjective B1 +experiment noun A2 +experiment verb B1 +experimental adjective C1 +expert adjective A2 +expert noun A2 +expertise noun B2 +expire verb C1 +explain verb A1 +explanation noun A2 +explicit adjective C1 +explicitly adverb C1 +explode verb B1 +exploit verb B2 +exploitation noun C1 +exploration noun B2 +explore verb B1 +explosion noun B1 +explosive adjective C1 +explosive noun C1 +export noun B1 +export verb B1 +expose verb B2 +exposure noun B2 +express verb A2 +expression noun A2 +extend verb B2 +extension noun B2 +extensive adjective B2 +extensively adverb B2 +extent noun B2 +external adjective B2 +extra adjective A1 +extra adverb B1 +extra noun B1 +extract noun B2 +extract verb C1 +extraordinary adjective B2 +extreme adjective A2 +extreme noun B2 +extremely adverb A2 +extremist noun C1 +eye noun A1 +fabric noun B2 +fabulous adjective B2 +face noun A1 +face verb B1 +facilitate verb C1 +facility noun B2 +fact noun A1 +faction noun C1 +factor noun A2 +factory noun A2 +faculty noun C1 +fade verb C1 +fail verb A2 +failed adjective B2 +failure noun B2 +fair adjective A2 +fairly adverb B1 +fairness noun C1 +faith noun B2 +fake adjective B2 +fall noun A2 +fall verb A1 +false adjective A1 +fame noun B2 +familiar adjective B1 +family adjective A1 +family noun A1 +famous adjective A1 +fan noun A2 +fancy adjective B1 +fancy verb B1 +fantastic adjective A1 +fantasy noun B2 +far adjective B1 +far adverb A1 +fare noun B2 +farm noun A1 +farm verb A2 +farmer noun A1 +farming noun A2 +fascinating adjective B1 +fashion noun A2 +fashionable adjective B1 +fast adjective A1 +fast adverb A1 +fasten verb B1 +fat adjective A1 +fat noun A2 +fatal adjective C1 +fate noun C1 +father noun A1 +fault noun B2 +favour noun B1 +favour verb B2 +favourable adjective C1 +favourite adjective A1 +favourite noun A1 +fear noun A2 +fear verb B1 +feat noun C1 +feather noun B2 +feature noun A2 +feature verb B1 +February noun A1 +federal adjective B2 +fee noun B2 +feed noun B2 +feed verb A2 +feedback noun B2 +feel noun B2 +feel verb A1 +feeling noun A1 +fellow adjective B2 +female adjective A2 +female noun A2 +feminist adjective C1 +feminist noun C1 +fence noun B1 +festival noun A1 +fever noun B2 +few adjective A1 +few determiner A1 +few pronoun A1 +fibre noun C1 +fiction noun A2 +field noun A2 +fierce adjective C1 +fifteen number A1 +fifth ordinalnumber A1 +fifty number A1 +fight noun A2 +fight verb A2 +fighting noun B1 +figure noun A2 +figure verb B2 +file noun B1 +file verb B2 +fill verb A1 +film noun A1 +film verb A2 +film-maker noun C1 +filter noun C1 +filter verb C1 +final adjective A1 +final noun A2 +finally adverb A2 +finance noun B2 +finance verb B2 +financial adjective B1 +find verb A1 +finding noun B2 +fine adjective A1 +fine noun C1 +fine verb C1 +finger noun A2 +finish noun A2 +finish verb A1 +fire noun A1 +fire verb B1 +firearm noun C1 +firefighter noun B2 +firework noun B2 +firm adjective B2 +firm noun B2 +firmly adverb B2 +first adverb A1 +first determiner A1 +first noun A2 +first ordinalnumber A1 +firstly adverb A2 +fish noun A1 +fish verb A2 +fishing noun A2 +fit adjective A2 +fit noun C1 +fit verb A2 +fitness noun B1 +five number A1 +fix noun B2 +fix verb A2 +fixed adjective B1 +fixture noun C1 +flag noun B1 +flame noun B2 +flash noun B2 +flash verb B2 +flat adjective A2 +flat noun A1 +flavour noun B2 +flaw noun C1 +flawed adjective C1 +flee verb C1 +fleet noun C1 +flesh noun C1 +flexibility noun C1 +flexible adjective B2 +flight noun A1 +float verb B2 +flood noun B1 +flood verb B1 +floor noun A1 +flour noun B1 +flourish verb C1 +flow noun B1 +flow verb B1 +flower noun A1 +flu noun A2 +fluid noun C1 +fly noun A2 +fly verb A1 +flying adjective A2 +flying noun A2 +focus noun A2 +focus verb A2 +fold noun B2 +fold verb B1 +folding adjective B2 +folk adjective B1 +folk noun B1 +follow verb A1 +following adjective A2 +following noun B1 +following preposition B2 +fond adjective B2 +food noun A1 +fool noun B2 +foot noun A1 +footage noun C1 +football noun A1 +for preposition A1 +forbid verb B2 +force noun B1 +force verb B1 +forecast noun B2 +forecast verb B2 +foreign adjective A2 +foreigner noun C1 +forest noun A2 +forever adverb B1 +forge verb C1 +forget verb A1 +forgive verb B2 +fork noun A2 +form noun A1 +form verb A1 +formal adjective A2 +format noun B2 +formation noun B2 +former adjective B2 +formerly adverb B2 +formula noun C1 +formulate verb C1 +forth adverb C1 +forthcoming adjective C1 +fortunate adjective B2 +fortunately adverb A2 +fortune noun B2 +forty number A1 +forum noun B2 +forward adjective B2 +forward adverb A2 +fossil noun B2 +foster verb C1 +found verb B2 +foundation noun B2 +founder noun B2 +four number A1 +fourteen number A1 +fourth ordinalnumber A1 +fraction noun B2 +fragile adjective C1 +fragment noun B2 +frame noun B1 +frame verb B1 +framework noun B2 +franchise noun C1 +frankly adverb C1 +fraud noun B2 +free adjective A1 +free adverb A2 +free verb B2 +freedom noun B2 +freely adverb B2 +freeze verb B1 +frequency noun B2 +frequent adjective B2 +frequently adverb B1 +fresh adjective A2 +Friday noun A1 +fridge noun A2 +friend noun A1 +friendly adjective A1 +friendship noun B1 +frighten verb B1 +frightened adjective B1 +frightening adjective B1 +frog noun A2 +from preposition A1 +front adjective A1 +front noun A1 +frozen adjective B1 +fruit noun A1 +frustrated adjective C1 +frustrating adjective C1 +frustration noun C1 +fry verb B1 +fuel noun B1 +fuel verb B2 +fulfil verb B2 +full adjective A1 +full-time adjective B2 +full-time adverb B2 +fully adverb B2 +fun adjective A2 +fun noun A1 +function noun B1 +function verb B2 +functional adjective C1 +fund noun B2 +fund verb B2 +fundamental adjective B2 +fundamentally adverb B2 +funding noun B2 +fundraising noun C1 +funeral noun C1 +funny adjective A1 +fur noun B1 +furious adjective B2 +furniture noun A2 +further adjective A2 +further adverb B1 +furthermore adverb B2 +future adjective A2 +future noun A1 +gain noun B2 +gain verb B2 +gallery noun A2 +gallon noun C1 +gambling noun C1 +game noun A1 +gaming noun B2 +gang noun B2 +gap noun A2 +garage noun B1 +garden noun A1 +gas noun A2 +gate noun A2 +gather verb B1 +gathering noun C1 +gay adjective B2 +gaze noun C1 +gaze verb C1 +gear noun C1 +gender noun B2 +gene noun B2 +general adjective A2 +generally adverb B1 +generate verb B2 +generation noun B1 +generic adjective C1 +generous adjective B1 +genetic adjective B2 +genius noun B2 +genocide noun C1 +genre noun B2 +gentle adjective B1 +gentleman noun B1 +genuine adjective B2 +genuinely adverb B2 +geography noun A1 +gesture noun B2 +get verb A1 +ghost noun B1 +giant adjective B1 +giant noun B1 +gift noun A2 +gig noun B2 +girl noun A1 +girlfriend noun A1 +give verb A1 +glad adjective B1 +glance noun C1 +glance verb C1 +glass noun A1 +glimpse noun C1 +global adjective B1 +globalization noun B2 +globe noun B2 +glorious adjective C1 +glory noun C1 +glove noun B1 +go noun B1 +go verb A1 +goal noun A2 +god noun A2 +gold adjective A2 +gold noun A2 +golden adjective B2 +golf noun A2 +good adjective A1 +good noun A2 +goodbye exclamation A1 +goodbye noun A1 +goodness noun B2 +goods noun B1 +gorgeous adjective B2 +govern verb B2 +governance noun C1 +government noun A2 +governor noun B2 +grab verb B2 +grace noun C1 +grade noun B1 +grade verb B2 +gradually adverb B2 +graduate noun B1 +graduate verb B1 +grain noun B1 +grand adjective B2 +grandfather noun A1 +grandmother noun A1 +grandparent noun A1 +grant noun B2 +grant verb B2 +graphic adjective B2 +graphics noun B2 +grasp noun C1 +grasp verb C1 +grass noun A2 +grateful adjective B1 +grave adjective C1 +grave noun C1 +gravity noun C1 +great adjective A1 +greatly adverb B2 +green adjective A1 +green noun A1 +greenhouse noun B2 +greet verb A2 +grey adjective A1 +grey noun A1 +grid noun C1 +grief noun C1 +grin noun C1 +grin verb C1 +grind verb C1 +grip noun C1 +grip verb C1 +grocery noun B2 +gross adjective C1 +ground noun A2 +group noun A1 +grow verb A1 +growth noun B1 +guarantee noun B2 +guarantee verb B2 +guard noun B1 +guard verb B1 +guerrilla noun C1 +guess noun A1 +guess verb A1 +guest noun A2 +guidance noun C1 +guide noun A2 +guide verb A2 +guideline noun B2 +guilt noun C1 +guilty adjective B1 +guitar noun A1 +gun noun A2 +gut noun C1 +guy noun A2 +gym noun A1 +habit noun A2 +habitat noun B2 +hail verb C1 +hair noun A1 +half adverb A2 +half determiner A1 +half noun A1 +half pronoun A1 +halfway adverb C1 +hall noun A2 +halt noun C1 +halt verb C1 +hand noun A1 +hand verb B1 +handful noun C1 +handle noun B2 +handle verb B2 +handling noun C1 +handy adjective C1 +hang verb B1 +happen verb A1 +happily adverb A2 +happiness noun B1 +happy adjective A1 +harassment noun C1 +harbour noun B2 +hard adjective A1 +hard adverb A1 +hardly adverb B1 +hardware noun C1 +harm noun B2 +harm verb B2 +harmful adjective B2 +harmony noun C1 +harsh adjective C1 +harvest noun C1 +harvest verb C1 +hat noun A1 +hate noun B1 +hate verb A1 +hatred noun C1 +haunt verb C1 +have verb A1 +have auxiliary verb A2 +have to modal verb A1 +hazard noun C1 +he pronoun A1 +head noun A1 +head verb B1 +headache noun A2 +headline noun B1 +headquarters noun B2 +heal verb B2 +health noun A1 +healthcare noun B2 +healthy adjective A1 +hear verb A1 +hearing noun B2 +heart noun A2 +heat noun A2 +heat verb A2 +heating noun B1 +heaven noun B2 +heavily adverb B1 +heavy adjective A2 +heel noun B2 +height noun A2 +heighten verb C1 +helicopter noun B1 +hell noun B2 +hello exclamation A1 +hello noun A1 +helmet noun B2 +help noun A1 +help verb A1 +helpful adjective A2 +hence adverb B2 +her determiner A1 +her pronoun A1 +herb noun B2 +here adverb A1 +heritage noun C1 +hero noun A2 +hers pronoun A2 +herself pronoun A2 +hesitate verb B2 +hey exclamation A1 +hi exclamation A1 +hidden adjective B2 +hide verb A2 +hierarchy noun C1 +high adjective A1 +high adverb A2 +high noun B2 +high-profile adjective C1 +highlight noun B1 +highlight verb B1 +highly adverb B1 +highway noun B2 +hilarious adjective B2 +hill noun A2 +him pronoun A1 +himself pronoun A2 +hint noun C1 +hint verb C1 +hip noun B2 +hire noun B2 +hire verb B1 +his determiner A1 +his pronoun A2 +historian noun B2 +historic adjective B1 +historical adjective B1 +history noun A1 +hit noun A2 +hit verb A2 +hobby noun A1 +hockey noun A2 +hold noun B2 +hold verb A2 +hole noun A2 +holiday noun A1 +hollow adjective B2 +holy adjective B2 +home adjective A2 +home adverb A1 +home noun A1 +homeland noun C1 +homeless adjective B2 +homework noun A1 +honest adjective B1 +honesty noun B2 +honour noun B2 +honour verb B2 +hook noun B2 +hook verb C1 +hope noun A2 +hope verb A1 +hopeful adjective C1 +hopefully adverb B2 +horizon noun C1 +horn noun C1 +horrible adjective B1 +horror noun B1 +horse noun A1 +hospital noun A1 +host noun B1 +host verb B2 +hostage noun C1 +hostile adjective C1 +hostility noun C1 +hot adjective A1 +hotel noun A1 +hour noun A1 +house noun A1 +house verb B2 +household noun B2 +housing noun B2 +how adverb A1 +however adverb A1 +huge adjective A2 +human adjective A2 +human noun A2 +humanitarian adjective C1 +humanity noun C1 +humble adjective C1 +humorous adjective B2 +humour noun B2 +hundred number A1 +hunger noun B2 +hungry adjective A1 +hunt noun B2 +hunt verb B1 +hunting noun B2 +hurricane noun B1 +hurry noun B1 +hurry verb B1 +hurt adjective A2 +hurt noun B2 +hurt verb A2 +husband noun A1 +hydrogen noun C1 +hypothesis noun B2 +I pronoun A1 +ice noun A1 +ice cream noun A1 +icon noun B2 +ID noun B2 +idea noun A1 +ideal adjective A2 +ideal noun B2 +identical adjective B2 +identification noun C1 +identify verb A2 +identity noun B1 +ideological adjective C1 +ideology noun C1 +idiot noun C1 +if conjunction A1 +ignorance noun C1 +ignore verb B1 +ill adjective A2 +illegal adjective B1 +illness noun A2 +illusion noun B2 +illustrate verb B2 +illustration noun B2 +image noun A2 +imagery noun C1 +imaginary adjective B1 +imagination noun B2 +imagine verb A1 +immediate adjective B1 +immediately adverb A2 +immense adjective C1 +immigrant noun B1 +immigration noun B2 +imminent adjective C1 +immune adjective B2 +impact noun B1 +impact verb B1 +impatient adjective B2 +implement verb B2 +implementation noun C1 +implication noun B2 +imply verb B2 +import noun B1 +import verb B1 +importance noun B1 +important adjective A1 +impose verb B2 +impossible adjective A2 +impress verb B2 +impressed adjective B2 +impression noun B1 +impressive adjective B1 +imprison verb C1 +imprisonment noun C1 +improve verb A1 +improvement noun B1 +in adverb A1 +in preposition A1 +inability noun C1 +inadequate adjective C1 +inappropriate adjective C1 +incentive noun B2 +inch noun B2 +incidence noun C1 +incident noun B2 +inclined adjective C1 +include verb A1 +included adjective A2 +including preposition A2 +inclusion noun C1 +income noun B2 +incorporate verb B2 +incorrect adjective B2 +increase noun A2 +increase verb A2 +increasingly adverb B2 +incredible adjective A2 +incredibly adverb B1 +incur verb C1 +indeed adverb B1 +independence noun B2 +independent adjective A2 +index noun B2 +indicate verb B1 +indication noun B2 +indicator noun C1 +indictment noun C1 +indigenous adjective C1 +indirect adjective B1 +individual adjective A2 +individual noun A2 +indoor adjective B1 +indoors adverb B1 +induce verb C1 +indulge verb C1 +industrial adjective B2 +industry noun A2 +inequality noun C1 +inevitable adjective B2 +inevitably adverb B2 +infamous adjective C1 +infant noun C1 +infect verb C1 +infection noun B2 +infer verb B2 +inflation noun B2 +inflict verb C1 +influence noun B1 +influence verb B1 +influential adjective C1 +info noun B2 +inform verb B2 +informal adjective A2 +information noun A1 +infrastructure noun B2 +ingredient noun B1 +inhabitant noun B2 +inherent adjective C1 +inherit verb B2 +inhibit verb C1 +initial adjective B2 +initially adverb B2 +initiate verb C1 +initiative noun B2 +inject verb C1 +injection noun C1 +injure verb B1 +injured adjective B1 +injury noun A2 +injustice noun C1 +ink noun B2 +inmate noun C1 +inner adjective B2 +innocent adjective B1 +innovation noun B2 +innovative adjective B2 +input noun B2 +inquiry noun B2 +insect noun A2 +insert verb B2 +insertion noun C1 +inside adjective A2 +inside adverb A2 +inside noun A2 +inside preposition A2 +insider noun C1 +insight noun B2 +insist verb B2 +inspect verb C1 +inspection noun C1 +inspector noun B2 +inspiration noun C1 +inspire verb B2 +install verb B2 +installation noun B2 +instance noun B2 +instant adjective B2 +instantly adverb B2 +instead adverb A2 +instinct noun C1 +institute noun B2 +institution noun B2 +institutional adjective C1 +instruct verb C1 +instruction noun A2 +instructor noun A2 +instrument noun A2 +instrumental adjective C1 +insufficient adjective C1 +insult noun C1 +insult verb C1 +insurance noun B2 +intact adjective C1 +intake noun C1 +integral adjective C1 +integrate verb B2 +integrated adjective C1 +integration noun C1 +integrity noun C1 +intellectual adjective B2 +intellectual noun C1 +intelligence noun B1 +intelligent adjective A2 +intend verb B1 +intended adjective B2 +intense adjective B2 +intensify verb C1 +intensity noun C1 +intensive adjective C1 +intent noun C1 +intention noun B1 +interact verb B2 +interaction noun B2 +interactive adjective C1 +interest noun A1 +interest verb A1 +interested adjective A1 +interesting adjective A1 +interface noun C1 +interfere verb C1 +interference noun C1 +interim adjective C1 +interior adjective C1 +interior noun C1 +intermediate adjective C1 +internal adjective B2 +international adjective A2 +internet noun A1 +interpret verb B2 +interpretation noun B2 +interrupt verb B2 +interval noun B2 +intervene verb C1 +intervention noun C1 +interview noun A1 +interview verb A1 +intimate adjective C1 +into preposition A1 +intriguing adjective C1 +introduce verb A1 +introduction noun A2 +invade verb B2 +invasion noun B2 +invent verb A2 +invention noun A2 +invest verb B1 +investigate verb B1 +investigation noun B2 +investigator noun C1 +investment noun B2 +investor noun B2 +invisible adjective C1 +invitation noun A2 +invite verb A2 +invoke verb C1 +involve verb A2 +involved adjective B1 +involvement noun C1 +iron noun B1 +iron verb B1 +ironic adjective C1 +ironically adverb C1 +irony noun C1 +irrelevant adjective C1 +island noun A1 +isolate verb B2 +isolated adjective B2 +isolation noun C1 +issue noun B1 +issue verb B2 +IT noun B1 +it pronoun A1 +item noun A2 +its determiner A1 +itself pronoun A2 +jacket noun A1 +jail noun B2 +jail verb B2 +jam noun A2 +January noun A1 +jazz noun A2 +jeans noun A1 +jet noun B2 +jewellery noun A2 +job noun A1 +join verb A1 +joint adjective B2 +joint noun B2 +joke noun A2 +joke verb A2 +journal noun B1 +journalism noun B2 +journalist noun A2 +journey noun A1 +joy noun B2 +judge noun B1 +judge verb B1 +judgement noun B2 +judicial adjective C1 +juice noun A1 +July noun A1 +jump noun A2 +jump verb A2 +junction noun C1 +June noun A1 +junior adjective B2 +jurisdiction noun C1 +jury noun B2 +just adjective C1 +just adverb A1 +justice noun B2 +justification noun C1 +justify verb B2 +keen adjective B1 +keep verb A1 +key adjective A1 +key noun A1 +key verb B1 +keyboard noun B1 +kick noun B1 +kick verb B1 +kid noun A2 +kidnap verb C1 +kidney noun C1 +kill verb A2 +killing noun B1 +kilometre noun A1 +kind adjective B1 +kind noun A1 +king noun A2 +kingdom noun C1 +kiss noun B1 +kiss verb B1 +kit noun B2 +kitchen noun A1 +knee noun A2 +knife noun A2 +knock noun B1 +knock verb A2 +know verb A1 +knowledge noun A2 +lab noun A2 +label noun B1 +label verb B1 +laboratory noun B1 +labour noun B2 +lack noun B1 +lack verb B1 +lad noun C1 +ladder noun B2 +lady noun A2 +lake noun A2 +lamp noun A2 +land noun A1 +land verb A2 +landing noun B2 +landlord noun C1 +landmark noun C1 +landscape noun B2 +lane noun B2 +language noun A1 +lap noun C1 +laptop noun A2 +large adjective A1 +large-scale adjective C1 +largely adverb B2 +laser noun C1 +last adverb A2 +last determiner A1 +last noun A2 +last verb A2 +late adjective A1 +late adverb A1 +lately adverb B2 +later adjective A2 +later adverb A1 +latest adjective B1 +latest noun B2 +latter adjective C1 +latter noun C1 +laugh noun A1 +laugh verb A1 +laughter noun A2 +launch noun B2 +launch verb B2 +law noun A2 +lawn noun C1 +lawsuit noun C1 +lawyer noun A2 +lay verb B1 +layer noun B1 +layout noun C1 +lazy adjective A2 +lead noun B1 +lead verb A2 +leader noun A2 +leadership noun B2 +leading adjective B1 +leaf noun B1 +leaflet noun B2 +league noun B2 +leak noun C1 +leak verb C1 +lean verb B2 +leap noun C1 +leap verb C1 +learn verb A1 +learning noun A2 +least adverb A2 +least determiner A2 +least pronoun A2 +leather noun B1 +leave noun B2 +leave verb A1 +lecture noun A2 +lecture verb A2 +left adjective A1 +left adverb A1 +left noun A1 +leg noun A1 +legacy noun C1 +legal adjective B1 +legend noun B2 +legendary adjective C1 +legislation noun C1 +legislative adjective C1 +legislature noun C1 +legitimate adjective C1 +leisure noun B1 +lemon noun A2 +lend verb A2 +length noun B1 +lengthy adjective C1 +lens noun B2 +lesbian adjective C1 +less adverb A2 +less determiner A2 +less pronoun A2 +lesser adjective C1 +lesson noun A1 +let verb A1 +lethal adjective C1 +letter noun A1 +level adjective B1 +level noun A2 +level verb B2 +liable adjective C1 +liberal adjective C1 +liberal noun C1 +liberation noun C1 +liberty noun C1 +library noun A1 +licence noun B2 +license verb C1 +lie noun B1 +lie verb A1 +lie verb B1 +life noun A1 +lifelong adjective C1 +lifestyle noun A2 +lifetime noun B2 +lift noun A2 +lift verb A2 +light adjective A1 +light noun A1 +light verb A2 +lighting noun B2 +like noun B1 +like preposition A1 +like verb A1 +likelihood noun C1 +likely adjective A2 +likewise adverb B2 +limb noun C1 +limit noun B1 +limit verb B1 +limitation noun B2 +limited adjective B2 +line noun A1 +line verb B2 +line-up noun C1 +linear adjective C1 +linger verb C1 +link noun A2 +link verb A2 +lion noun A1 +lip noun B1 +liquid adjective B1 +liquid noun B1 +list noun A1 +list verb A1 +listen verb A1 +listener noun A2 +listing noun C1 +literacy noun C1 +literally adverb B2 +literary adjective B2 +literature noun B1 +litre noun B2 +litter noun B2 +little adjective A1 +little adverb A2 +little determiner A1 +little pronoun A1 +live adjective B1 +live adverb B1 +live verb A1 +lively adjective B2 +liver noun C1 +living adjective B1 +living noun B1 +load noun B2 +load verb B2 +loan noun B2 +lobby noun C1 +lobby verb C1 +local adjective A1 +local noun B1 +locate verb B1 +located adjective B1 +location noun B1 +lock noun A2 +lock verb A2 +log noun C1 +log verb C1 +logic noun C1 +logical adjective B2 +logo noun B2 +lonely adjective B1 +long adjective A1 +long adverb A1 +long-standing adjective C1 +long-term adjective B2 +long-term adverb B2 +long-time adjective C1 +look noun A2 +look verb A1 +loom verb C1 +loop noun C1 +loose adjective B2 +lord noun B2 +lorry noun A2 +lose verb A1 +loss noun B1 +lost adjective A2 +lot adverb A1 +lot determiner A1 +lot pronoun A1 +lottery noun B2 +loud adjective A2 +loud adverb A2 +loudly adverb A2 +love noun A1 +love verb A1 +lovely adjective A2 +low adjective A2 +low adverb A2 +low noun B2 +lower verb B2 +loyal adjective B2 +loyalty noun C1 +luck noun A2 +lucky adjective A2 +lunch noun A1 +lung noun B2 +luxury adjective B1 +luxury noun B1 +lyric noun B2 +machine noun A1 +machinery noun C1 +mad adjective B1 +magazine noun A1 +magic adjective B1 +magic noun B1 +magical adjective C1 +magistrate noun C1 +magnetic adjective C1 +magnificent adjective B2 +magnitude noun C1 +mail noun A2 +mail verb A2 +main adjective A1 +mainland noun C1 +mainly adverb B1 +mainstream adjective C1 +mainstream noun C1 +maintain verb B2 +maintenance noun C1 +major adjective A2 +majority noun B2 +make noun B2 +make verb A1 +make-up noun B2 +making noun B2 +male adjective A2 +male noun A2 +mall noun B1 +man noun A1 +manage verb A2 +management noun B1 +manager noun A2 +mandate noun C1 +mandatory adjective C1 +manifest verb C1 +manipulate verb C1 +manipulation noun C1 +manner noun A2 +manufacture verb B2 +manufacturing noun B2 +manuscript noun C1 +many determiner A1 +many pronoun A1 +map noun A1 +map verb B2 +marathon noun B2 +March noun A1 +march noun C1 +march verb C1 +margin noun B2 +marginal adjective C1 +marine adjective C1 +mark noun A2 +mark verb A2 +marker noun B2 +market noun A1 +market verb B1 +marketing noun B1 +marketplace noun C1 +marriage noun B1 +married adjective A1 +marry verb A2 +martial adjective B2 +mask noun C1 +mass adjective B2 +mass noun B2 +massacre noun C1 +massive adjective B2 +master noun B2 +master verb B2 +match noun A1 +match verb A1 +matching adjective B2 +mate noun B2 +mate verb B2 +material adjective B2 +material noun A2 +mathematical adjective C1 +mathematics noun A2 +maths noun A2 +matter noun A2 +matter verb A2 +mature adjective C1 +mature verb C1 +maximize verb C1 +maximum adjective B2 +maximum noun B2 +May noun A1 +may modal verb A2 +maybe adverb A1 +mayor noun B2 +me pronoun A1 +meal noun A1 +mean verb A1 +meaning noun A1 +meaningful adjective C1 +means noun B2 +meantime noun C1 +meanwhile adverb B1 +measure noun B1 +measure verb B1 +measurement noun B2 +meat noun A1 +mechanic noun B2 +mechanical adjective B2 +mechanism noun B2 +medal noun B2 +media noun A2 +medical adjective A2 +medication noun B2 +medicine noun A2 +medieval adjective C1 +meditation noun C1 +medium adjective B1 +medium noun B2 +meet verb A1 +meeting noun A1 +melody noun C1 +melt verb B2 +member noun A1 +membership noun B2 +memo noun C1 +memoir noun C1 +memorable adjective B2 +memorial noun C1 +memory noun A2 +mental adjective B1 +mention noun B1 +mention verb A2 +mentor noun C1 +menu noun A1 +merchant noun C1 +mercy noun C1 +mere adjective C1 +merely adverb C1 +merge verb C1 +merger noun C1 +merit noun C1 +mess noun B1 +message noun A1 +metal noun A2 +metaphor noun B2 +method noun A2 +methodology noun C1 +metre noun A1 +middle adjective A2 +middle noun A2 +midnight noun A1 +midst noun C1 +might modal verb A2 +migration noun C1 +mild adjective B1 +mile noun A1 +militant adjective C1 +militant noun C1 +military adjective B2 +military noun B2 +militia noun C1 +milk noun A1 +mill noun C1 +million number A1 +mind noun A2 +mind verb A2 +mine noun B1 +mine pronoun A2 +miner noun B2 +mineral noun B2 +minimal adjective C1 +minimize verb C1 +minimum adjective B2 +minimum noun B2 +mining noun C1 +minister noun B2 +ministry noun C1 +minor adjective B2 +minority noun B2 +minute adjective C1 +minute noun A1 +miracle noun C1 +mirror noun A2 +miserable adjective B2 +misery noun C1 +misleading adjective C1 +miss verb A1 +missile noun C1 +missing adjective A2 +mission noun B2 +mistake noun A1 +mistake verb B2 +mix noun B1 +mix verb B1 +mixed adjective B2 +mixture noun B1 +mob noun C1 +mobile adjective A2 +mobile noun A2 +mobility noun C1 +mobilize verb C1 +mode noun B2 +model noun A1 +model verb B2 +moderate adjective C1 +modern adjective A1 +modest adjective B2 +modification noun C1 +modify verb B2 +moment noun A1 +momentum noun C1 +Monday noun A1 +money noun A1 +monitor noun B2 +monitor verb B2 +monk noun C1 +monkey noun A2 +monopoly noun C1 +monster noun B2 +month noun A1 +monthly adjective B2 +monument noun B2 +mood noun B1 +moon noun A2 +moral adjective B2 +moral noun B2 +morality noun C1 +more adverb A1 +more determiner A1 +more pronoun A1 +moreover adverb B2 +morning noun A1 +mortgage noun B2 +mosque noun B2 +most adverb A1 +most determiner A1 +most pronoun A1 +mostly adverb A2 +mother noun A1 +motion noun B2 +motivate verb B2 +motivation noun B2 +motive noun C1 +motor adjective B2 +motor noun B2 +motorcycle noun A2 +motorist noun C1 +mount verb B2 +mountain noun A1 +mouse noun A1 +mouth noun A1 +move noun B1 +move verb A1 +movement noun A2 +movie noun A1 +moving adjective B2 +much adverb A1 +much determiner A1 +much pronoun A1 +mud noun B1 +multiple adjective B2 +multiply verb B2 +mum noun A1 +municipal adjective C1 +murder noun B1 +murder verb B1 +muscle noun B1 +museum noun A1 +music noun A1 +musical adjective A2 +musical noun B1 +musician noun A2 +must modal verb A1 +mutual adjective C1 +my determiner A1 +myself pronoun A2 +mysterious adjective B2 +mystery noun B1 +myth noun B2 +nail noun B1 +naked adjective B2 +name noun A1 +name verb A1 +namely adverb C1 +narrative adjective B1 +narrative noun B1 +narrow adjective A2 +narrow verb B2 +nasty adjective B2 +nation noun B1 +national adjective A2 +national noun B2 +nationwide adjective C1 +native adjective B1 +native noun B1 +natural adjective A1 +naturally adverb B1 +nature noun A2 +naval adjective C1 +navigation noun B2 +near adjective A1 +near adverb A1 +near preposition A1 +nearby adjective B2 +nearby adverb B2 +nearly adverb A2 +neat adjective B2 +necessarily adverb B1 +necessary adjective A2 +necessity noun B2 +neck noun A2 +need noun A2 +need verb A1 +need modal verb B1 +needle noun B1 +negative adjective A1 +negative noun B2 +neglect noun C1 +neglect verb C1 +negotiate verb B2 +negotiation noun B2 +neighbour noun A1 +neighbourhood noun B1 +neighbouring adjective C1 +neither adverb B1 +neither determiner A2 +neither pronoun A2 +nerve noun B2 +nervous adjective A2 +nest noun C1 +net adjective C1 +net noun B1 +network noun A2 +neutral adjective B2 +never adverb A1 +nevertheless adverb B2 +new adjective A1 +newly adverb B2 +news noun A1 +newsletter noun C1 +newspaper noun A1 +next adjective A1 +next adverb A1 +next noun B1 +next to preposition A1 +nice adjective A1 +niche noun C1 +night noun A1 +nightmare noun B2 +nine number A1 +nineteen number A1 +ninety number A1 +no determiner A1 +no exclamation A1 +no one pronoun A1 +noble adjective C1 +nobody pronoun A1 +nod verb C1 +noise noun A2 +noisy adjective A2 +nominate verb C1 +nomination noun C1 +nominee noun C1 +non-profit adjective C1 +none pronoun A2 +nonetheless adverb C1 +nonsense noun C1 +noon noun C1 +nor adverb B1 +nor conjunction B1 +norm noun B2 +normal adjective A2 +normal noun B1 +normally adverb A2 +north adjective A1 +north adverb A1 +north noun A1 +northern adjective B1 +nose noun A1 +not adverb A1 +notable adjective C1 +notably adverb C1 +note noun A1 +note verb B1 +notebook noun B2 +nothing pronoun A1 +notice noun A2 +notice verb A2 +notify verb C1 +notion noun B2 +notorious adjective C1 +novel adjective C1 +novel noun A2 +novelist noun B2 +November noun A1 +now adverb A1 +now conjunction B1 +nowadays adverb B2 +nowhere adverb A2 +nuclear adjective B1 +number noun A1 +number verb A2 +numerous adjective B2 +nurse noun A1 +nursery noun C1 +nursing noun B2 +nut noun A2 +nutrition noun B2 +o'clock adverb A1 +obesity noun B2 +obey verb B2 +object noun A1 +object verb B2 +objection noun C1 +objective adjective B2 +objective noun B2 +obligation noun B2 +oblige verb C1 +observation noun B2 +observe verb B2 +observer noun B2 +obsess verb C1 +obsession noun C1 +obstacle noun B2 +obtain verb B2 +obvious adjective B1 +obviously adverb B1 +occasion noun B1 +occasional adjective C1 +occasionally adverb B2 +occupation noun B2 +occupy verb B2 +occur verb B1 +occurrence noun C1 +ocean noun A2 +October noun A1 +odd adjective B1 +odds noun C1 +of preposition A1 +off adverb A1 +off preposition A1 +offence noun B2 +offend verb B2 +offender noun B2 +offensive adjective B2 +offer noun A2 +offer verb A2 +offering noun C1 +office noun A1 +officer noun A2 +official adjective B1 +official noun B2 +offspring noun C1 +often adverb A1 +oh exclamation A1 +oil noun A2 +OK adjective A1 +OK adverb A1 +OK exclamation A1 +old adjective A1 +old-fashioned adjective B1 +on adverb A1 +on preposition A1 +once adverb A1 +once conjunction B1 +one determiner A1 +one number A1 +one pronoun A1 +ongoing adjective B2 +onion noun A1 +online adjective A1 +online adverb A1 +only adjective A1 +only adverb A1 +onto preposition A2 +open adjective A1 +open verb A1 +opening noun B2 +openly adverb B2 +opera noun B2 +operate verb B2 +operation noun B1 +operational adjective C1 +operator noun B2 +opinion noun A1 +opponent noun B2 +opportunity noun A2 +oppose verb B2 +opposed adjective B2 +opposite adjective A1 +opposite adverb A1 +opposite noun A1 +opposite preposition A1 +opposition noun B2 +opt verb C1 +optical adjective C1 +optimism noun C1 +optimistic adjective B2 +option noun A2 +or conjunction A1 +oral adjective C1 +orange adjective A1 +orange noun A1 +orchestra noun B2 +order noun A1 +order verb A1 +ordinary adjective A2 +organ noun B2 +organic adjective B2 +organization noun A2 +organizational adjective C1 +organize verb A2 +organized adjective B1 +organizer noun B1 +orientation noun C1 +origin noun B2 +original adjective A2 +original noun B1 +originally adverb B1 +originate verb C1 +other adjective A1 +other pronoun A1 +otherwise adverb B2 +ought modal verb B1 +our determiner A1 +ours pronoun B1 +ourselves pronoun A2 +out adverb A1 +out preposition A1 +outbreak noun C1 +outcome noun B2 +outdoor adjective B1 +outdoors adverb B1 +outer adjective B2 +outfit noun B2 +outing noun C1 +outlet noun C1 +outline noun B2 +outline verb B2 +outlook noun C1 +output noun B2 +outrage noun C1 +outrage verb C1 +outside adjective A2 +outside adverb A1 +outside noun A2 +outside preposition A2 +outsider noun C1 +outstanding adjective B2 +oven noun A2 +over adverb A1 +over preposition A1 +overall adjective B2 +overall adverb B2 +overcome verb B2 +overlook verb C1 +overly adverb C1 +overnight adverb B2 +overseas adjective B2 +overseas adverb B2 +oversee verb C1 +overturn verb C1 +overwhelm verb C1 +overwhelming adjective C1 +owe verb B2 +own adjective A1 +own pronoun A1 +own verb A2 +owner noun A2 +ownership noun B2 +oxygen noun B2 +pace noun B2 +pace verb B2 +pack noun B1 +pack verb A2 +package noun B1 +package verb B2 +packet noun B2 +pad noun C1 +page noun A1 +pain noun A2 +painful adjective B1 +paint noun A1 +paint verb A1 +painter noun A2 +painting noun A1 +pair noun A1 +palace noun A2 +pale adjective B1 +palm noun B2 +pan noun B1 +panel noun B2 +panic noun B2 +pants noun A2 +paper noun A1 +parade noun B2 +paragraph noun A1 +parallel adjective B2 +parallel noun B2 +parameter noun C1 +parent noun A1 +parental adjective C1 +parish noun C1 +park noun A1 +park verb A1 +parking noun A2 +parliament noun B2 +parliamentary adjective C1 +part noun A1 +part-time adjective B2 +partial adjective C1 +partially adverb C1 +participant noun B2 +participate verb B1 +participation noun B2 +particular adjective A2 +particularly adverb B1 +partly adverb B2 +partner noun A1 +partnership noun B2 +party noun A1 +pass noun B1 +pass verb A2 +passage noun B2 +passenger noun A2 +passing noun C1 +passion noun B1 +passionate adjective B2 +passive adjective C1 +passport noun A1 +password noun B2 +past adjective A1 +past adverb A2 +past noun A1 +past preposition A1 +pastor noun C1 +patch noun C1 +patent noun C1 +path noun B1 +pathway noun C1 +patience noun B2 +patient adjective B2 +patient noun A2 +patrol noun C1 +patrol verb C1 +patron noun C1 +pattern noun A2 +pause noun B2 +pause verb B2 +pay noun A2 +pay verb A1 +payment noun B1 +peace noun A2 +peaceful adjective B1 +peak noun C1 +peasant noun C1 +peculiar adjective C1 +peer noun B2 +pen noun A1 +penalty noun B2 +pencil noun A1 +penny noun A2 +pension noun B2 +people noun A1 +pepper noun A1 +per preposition A2 +per cent adjective A2 +per cent adverb A2 +per cent noun A2 +perceive verb B2 +percentage noun B1 +perception noun B2 +perfect adjective A1 +perfectly adverb B1 +perform verb A2 +performance noun B1 +perhaps adverb A2 +period noun A1 +permanent adjective B2 +permanently adverb B2 +permission noun A2 +permit noun B2 +permit verb B2 +persist verb C1 +persistent adjective C1 +person noun A1 +personal adjective A1 +personality noun A2 +personally adverb B1 +personnel noun C1 +perspective noun B2 +persuade verb B1 +pet noun A2 +petition noun C1 +petrol noun A2 +phase noun B2 +phenomenon noun B2 +philosopher noun C1 +philosophical adjective C1 +philosophy noun B2 +phone noun A1 +phone verb A1 +photo noun A1 +photograph noun A1 +photograph verb A2 +photographer noun B1 +photography noun B1 +phrase noun A1 +physical adjective A2 +physician noun C1 +physics noun A2 +piano noun A1 +pick noun B2 +pick verb A2 +picture noun A1 +picture verb B2 +piece noun A1 +pig noun A1 +pile noun B2 +pile verb B2 +pill noun B2 +pilot noun A2 +pin noun B1 +pin verb B1 +pink adjective A1 +pink noun A1 +pioneer noun C1 +pioneer verb C1 +pipe noun B1 +pipeline noun C1 +pirate noun C1 +pit noun C1 +pitch noun B2 +pity noun B2 +place noun A1 +place verb B1 +placement noun B2 +plain adjective B2 +plan noun A1 +plan verb A1 +plane noun A1 +planet noun A2 +planning noun B1 +plant noun A1 +plant verb A2 +plastic adjective A2 +plastic noun A2 +plate noun A2 +platform noun A2 +play noun A1 +play verb A1 +player noun A1 +plea noun C1 +plead verb C1 +pleasant adjective B1 +please exclamation A1 +please verb A2 +pleased adjective A2 +pleasure noun B1 +pledge noun C1 +pledge verb C1 +plenty pronoun B1 +plot noun B1 +plot verb B2 +plug noun C1 +plug verb C1 +plunge verb C1 +plus adjective B2 +plus conjunction B2 +plus noun B2 +plus preposition B1 +pocket noun A2 +poem noun B1 +poet noun B1 +poetry noun B1 +point noun A1 +point verb B1 +pointed adjective B2 +poison noun B1 +poison verb B1 +poisonous adjective B1 +pole noun C1 +police noun A1 +policeman noun A1 +policy noun B1 +polite adjective A2 +political adjective B1 +politician noun B1 +politics noun B1 +poll noun C1 +pollution noun A2 +pond noun C1 +pool noun A1 +poor adjective A1 +pop adjective A2 +pop noun A2 +pop verb C1 +popular adjective A1 +popularity noun B2 +population noun A2 +port noun B1 +portfolio noun C1 +portion noun B2 +portrait noun B1 +portray verb C1 +pose verb B2 +position noun A2 +position verb B2 +positive adjective A1 +positive noun B2 +possess verb B2 +possession noun A2 +possibility noun A2 +possible adjective A1 +possibly adverb B1 +post noun A1 +post verb A1 +post-war adjective C1 +poster noun A2 +postpone verb C1 +pot noun B1 +potato noun A1 +potential adjective B2 +potential noun B2 +potentially adverb B2 +pound noun A1 +pour verb B1 +poverty noun B1 +powder noun B1 +power noun A2 +power verb B2 +powerful adjective B1 +practical adjective B1 +practice noun A1 +practise verb A1 +practitioner noun C1 +praise noun B2 +praise verb B2 +pray verb B1 +prayer noun B1 +preach verb C1 +precede verb B2 +precedent noun C1 +precious adjective B2 +precise adjective B2 +precisely adverb B2 +precision noun C1 +predator noun C1 +predecessor noun C1 +predict verb A2 +predictable adjective B2 +prediction noun B1 +predominantly adverb C1 +prefer verb A1 +preference noun B2 +pregnancy noun C1 +pregnant adjective B2 +prejudice noun C1 +preliminary adjective C1 +premier adjective C1 +premise noun C1 +premium noun C1 +preparation noun B2 +prepare verb A1 +prepared adjective B1 +prescribe verb C1 +prescription noun C1 +presence noun B2 +present adjective A1 +present noun A1 +present verb A2 +presentation noun B1 +presently adverb C1 +preservation noun C1 +preserve verb B2 +preside verb C1 +presidency noun C1 +president noun A2 +presidential adjective C1 +press noun B1 +press verb B1 +pressure noun B1 +prestigious adjective C1 +presumably adverb C1 +presume verb C1 +pretend verb B1 +pretty adjective A1 +pretty adverb A1 +prevail verb C1 +prevalence noun C1 +prevent verb A2 +prevention noun C1 +previous adjective B1 +previously adverb B1 +prey noun C1 +price noun A1 +price verb B2 +pride noun B2 +priest noun B1 +primarily adverb B2 +primary adjective B1 +prime adjective B2 +prince noun B1 +princess noun B1 +principal adjective B2 +principal noun C1 +principle noun B2 +print noun B2 +print verb A2 +printer noun A2 +printing noun B1 +prior adjective B2 +priority noun B2 +prison noun A2 +prisoner noun B1 +privacy noun B2 +private adjective B1 +privatization noun C1 +privilege noun C1 +prize noun A2 +probability noun B2 +probable adjective B2 +probably adverb A1 +probe noun C1 +probe verb C1 +problem noun A1 +problematic adjective C1 +procedure noun B2 +proceed verb B2 +proceeding noun C1 +proceeds noun C1 +process noun A2 +process verb B2 +processing noun C1 +processor noun C1 +proclaim verb C1 +produce noun B2 +produce verb A2 +producer noun B1 +product noun A1 +production noun B1 +productive adjective C1 +productivity noun C1 +profession noun B1 +professional adjective A2 +professional noun B2 +professor noun A2 +profile noun A2 +profit noun B1 +profitable adjective C1 +profound adjective C1 +program noun A2 +program verb B1 +programme noun A1 +programming noun B2 +progress noun A2 +progress verb B2 +progressive adjective B2 +prohibit verb B2 +project noun A1 +project verb B2 +projection noun C1 +prominent adjective C1 +promise noun A2 +promise verb A2 +promising adjective B2 +promote verb B1 +promotion noun B2 +prompt verb B2 +pronoun ce verb A2 +pronoun ced adjective C1 +proof noun B2 +propaganda noun C1 +proper adjective B1 +properly adverb B1 +property noun B1 +proportion noun B2 +proposal noun B2 +propose verb B2 +proposition noun C1 +prosecute verb C1 +prosecution noun C1 +prosecutor noun C1 +prospect noun B2 +prospective adjective C1 +prosperity noun C1 +protect verb A2 +protection noun B2 +protective adjective C1 +protein noun B2 +protest noun B1 +protest verb B1 +protester noun B2 +protocol noun C1 +proud adjective B1 +prove verb B1 +provide verb A2 +province noun C1 +provincial adjective C1 +provision noun C1 +provoke verb C1 +psychiatric adjective C1 +psychological adjective B2 +psychologist noun B2 +psychology noun B2 +pub noun A2 +public adjective A2 +public noun A2 +publication noun B2 +publicity noun B2 +publish verb A2 +publishing noun B2 +pull noun B1 +pull verb A2 +pulse noun C1 +pump noun C1 +pump verb C1 +punch noun C1 +punch verb C1 +punish verb B1 +punishment noun B1 +punk noun B2 +pupil noun B2 +purchase noun B2 +purchase verb B2 +pure adjective B2 +purely adverb B2 +purple adjective A1 +purple noun A1 +purpose noun A2 +pursue verb B2 +pursuit noun B2 +push noun B1 +push verb A2 +put verb A1 +puzzle noun B2 +qualification noun B1 +qualified adjective B1 +qualify verb B1 +quality noun A2 +quantity noun A2 +quarter noun A1 +queen noun A2 +query noun C1 +quest noun C1 +question noun A1 +question verb A2 +questionnaire noun B2 +queue noun B1 +queue verb B1 +quick adjective A1 +quickly adverb A1 +quiet adjective A1 +quietly adverb A2 +quit verb B1 +quite adverb A1 +quota noun C1 +quotation noun B1 +quote noun B1 +quote verb B1 +race noun A2 +race verb A2 +racial adjective B2 +racing noun B1 +racism noun B2 +racist adjective B2 +racist noun B2 +radar noun C1 +radiation noun B2 +radical adjective C1 +radio noun A1 +rage noun C1 +raid noun C1 +raid verb C1 +rail noun B2 +railway noun A2 +rain noun A1 +rain verb A1 +raise verb A2 +rally noun C1 +rally verb C1 +random adjective B2 +range noun B1 +range verb B2 +rank noun B2 +rank verb B2 +ranking noun C1 +rape noun C1 +rape verb C1 +rapid adjective B2 +rapidly adverb B2 +rare adjective B1 +rarely adverb B1 +rat noun B2 +rate noun A2 +rate verb B2 +rather adverb A2 +rating noun B2 +ratio noun C1 +rational adjective C1 +raw adjective B2 +ray noun C1 +reach noun B2 +reach verb A2 +react verb A2 +reaction noun B1 +read verb A1 +reader noun A1 +readily adverb C1 +reading noun A1 +ready adjective A1 +real adjective A1 +realistic adjective B2 +reality noun B1 +realization noun C1 +realize verb A2 +really adverb A1 +realm noun C1 +rear adjective C1 +rear noun C1 +reason noun A1 +reasonable adjective B2 +reasonably adverb B2 +reasoning noun C1 +reassure verb C1 +rebel noun C1 +rebellion noun C1 +rebuild verb B2 +recall verb B2 +receipt noun B1 +receive verb A2 +receiver noun B2 +recent adjective A2 +recently adverb A2 +reception noun A2 +recession noun B2 +recipe noun A2 +recipient noun C1 +reckon verb B2 +recognition noun B2 +recognize verb A2 +recommend verb A2 +recommendation noun B1 +reconstruction noun C1 +record noun A2 +record verb A2 +recording noun A2 +recount verb C1 +recover verb B2 +recovery noun B2 +recruit noun B2 +recruit verb B2 +recruitment noun B2 +recycle verb A2 +red adjective A1 +red noun A1 +reduce verb A2 +reduction noun B2 +refer verb A2 +referee noun B2 +reference noun B1 +referendum noun C1 +reflect verb B1 +reflection noun C1 +reform noun C1 +reform verb C1 +refuge noun C1 +refugee noun B2 +refusal noun C1 +refuse verb A2 +regain verb C1 +regard noun B2 +regard verb B2 +regardless adverb C1 +regime noun C1 +region noun A2 +regional adjective B2 +register noun B2 +register verb B2 +registration noun B2 +regret noun B2 +regret verb B2 +regular adjective A2 +regularly adverb B1 +regulate verb B2 +regulation noun B2 +regulator noun C1 +regulatory adjective C1 +rehabilitation noun C1 +reign noun C1 +reign verb C1 +reinforce verb B2 +reject verb B1 +rejection noun C1 +relate verb B1 +related adjective B1 +relation noun B1 +relationship noun A2 +relative adjective B1 +relative noun B1 +relatively adverb B2 +relax verb A1 +relaxed adjective B1 +relaxing adjective B1 +release noun B1 +release verb B1 +relevance noun C1 +relevant adjective B2 +reliability noun C1 +reliable adjective B1 +relief noun B2 +relieve verb B2 +relieved adjective B2 +religion noun B1 +religious adjective B1 +reluctant adjective C1 +rely verb B2 +remain verb B1 +remainder noun C1 +remains noun C1 +remark noun B2 +remark verb B2 +remarkable adjective B2 +remarkably adverb B2 +remedy noun C1 +remember verb A1 +remind verb B1 +reminder noun C1 +remote adjective B1 +removal noun C1 +remove verb A2 +render verb C1 +renew verb C1 +renowned adjective C1 +rent noun B1 +rent verb B1 +rental noun C1 +repair noun B1 +repair verb A2 +repeat noun B1 +repeat verb A1 +repeated adjective B1 +replace verb A2 +replacement noun C1 +reply noun A2 +reply verb A2 +report noun A1 +report verb A2 +reportedly adverb C1 +reporter noun A2 +reporting noun B2 +represent verb B1 +representation noun C1 +representative adjective B2 +representative noun B2 +reproduce verb C1 +reproduction noun C1 +republic noun C1 +reputation noun B2 +request noun A2 +request verb B1 +require verb B1 +requirement noun B2 +rescue noun B2 +rescue verb B2 +research noun A2 +research verb A2 +researcher noun A2 +resemble verb C1 +reservation noun B1 +reserve noun B2 +reserve verb B2 +reside verb C1 +residence noun C1 +resident adjective B2 +resident noun B2 +residential adjective C1 +residue noun C1 +resign verb B2 +resignation noun C1 +resist verb B2 +resistance noun C1 +resolution noun B2 +resolve verb B2 +resort noun B2 +resource noun B1 +respect noun B1 +respect verb B1 +respective adjective C1 +respectively adverb C1 +respond verb A2 +response noun A2 +responsibility noun B1 +responsible adjective B1 +rest noun A2 +rest verb A2 +restaurant noun A1 +restoration noun C1 +restore verb B2 +restraint noun C1 +restrict verb B2 +restriction noun B2 +result noun A1 +result verb B1 +resume verb C1 +retail noun B2 +retain verb B2 +retire verb B1 +retired adjective B1 +retirement noun B2 +retreat noun C1 +retreat verb C1 +retrieve verb C1 +return noun A1 +return verb A1 +reveal verb B2 +revelation noun C1 +revenge noun C1 +revenue noun B2 +reverse adjective C1 +reverse noun C1 +reverse verb C1 +review noun A2 +review verb A2 +revise verb B1 +revision noun B2 +revival noun C1 +revive verb C1 +revolution noun B2 +revolutionary adjective C1 +reward noun B2 +reward verb B2 +rhetoric noun C1 +rhythm noun B2 +rice noun A1 +rich adjective A1 +rid verb B2 +ride noun A2 +ride verb A1 +ridiculous adjective B2 +rifle noun C1 +right adjective A1 +right adverb A1 +right noun A1 +ring noun A2 +ring verb A2 +riot noun C1 +rip verb C1 +rise noun B1 +rise verb A2 +risk noun B1 +risk verb B1 +risky adjective B2 +ritual noun C1 +rival adjective B2 +rival noun B2 +river noun A1 +road noun A1 +rob verb B2 +robbery noun B2 +robot noun B1 +robust adjective C1 +rock noun A2 +rock verb C1 +rocket noun B2 +rod noun C1 +role noun A2 +roll noun B1 +roll verb B1 +romance noun B2 +romantic adjective B1 +roof noun A2 +room noun A1 +root noun B2 +rope noun B1 +rose noun B2 +rotate verb C1 +rotation noun C1 +rough adjective B1 +roughly adverb B2 +round adjective A2 +round adverb A2 +round noun B2 +round preposition A2 +route noun A2 +routine adjective B2 +routine noun A1 +row noun B1 +royal adjective B1 +rub verb B2 +rubber adjective B2 +rubber noun B2 +rubbish noun A2 +rude adjective A2 +rugby noun B1 +ruin noun B2 +ruin verb B2 +rule noun A1 +rule verb B1 +ruling noun C1 +rumour noun C1 +run noun A2 +run verb A1 +runner noun A2 +running noun A2 +rural adjective B2 +rush noun B2 +rush verb B2 +sack verb C1 +sacred adjective C1 +sacrifice noun C1 +sacrifice verb C1 +sad adjective A1 +sadly adverb A2 +safe adjective A2 +safety noun B1 +sail noun B1 +sail verb A2 +sailing noun A2 +sailor noun B1 +saint noun C1 +sake noun C1 +salad noun A1 +salary noun A2 +sale noun A2 +salt noun A1 +same adjective A1 +same adverb A1 +same pronoun A1 +sample noun B1 +sample verb B2 +sanction noun C1 +sand noun B1 +sandwich noun A1 +satellite noun B2 +satisfaction noun B2 +satisfied adjective B2 +satisfy verb B2 +Saturday noun A1 +sauce noun A2 +save verb A2 +saving noun B2 +say noun C1 +say verb A1 +scale noun B2 +scan verb B1 +scandal noun B2 +scare noun B2 +scare verb B2 +scared adjective A2 +scary adjective A2 +scattered adjective C1 +scenario noun B2 +scene noun A2 +sceptical adjective C1 +schedule noun A2 +schedule verb B2 +scheme noun B2 +scholar noun B2 +scholarship noun B2 +school noun A1 +science noun A1 +scientific adjective B1 +scientist noun A1 +scope noun C1 +score noun A2 +score verb A2 +scratch noun B2 +scratch verb B2 +scream noun B2 +scream verb B2 +screen noun A2 +screen verb B2 +screening noun B2 +screw noun C1 +screw verb C1 +script noun B1 +scrutiny noun C1 +sculpture noun B1 +sea noun A1 +seal noun C1 +seal verb C1 +search noun A2 +search verb A2 +season noun A2 +seat noun A2 +seat verb B2 +second adverb A2 +second determiner A1 +second noun A1 +second ordinalnumber A1 +secondary adjective B1 +secondly adverb A2 +secret adjective A2 +secret noun A2 +secretary noun A2 +section noun A1 +sector noun B2 +secular adjective C1 +secure adjective B2 +secure verb B2 +security noun B1 +see verb A1 +seed noun B1 +seek verb B2 +seeker noun B2 +seem linking verb A2 +seemingly adverb C1 +segment noun C1 +seize verb C1 +seldom adverb C1 +select verb B2 +selection noun B2 +selective adjective C1 +self noun B2 +sell verb A1 +seminar noun B2 +senator noun C1 +send verb A1 +senior adjective B2 +sensation noun C1 +sense noun A2 +sense verb B2 +sensible adjective B1 +sensitive adjective B2 +sensitivity noun C1 +sentence noun A1 +sentence verb B2 +sentiment noun C1 +separate adjective A2 +separate verb B1 +separation noun C1 +September noun A1 +sequence noun B2 +serial adjective C1 +series noun A2 +serious adjective A2 +seriously adverb B1 +servant noun B1 +serve verb A2 +service noun A2 +session noun B2 +set noun B1 +set verb B1 +set-up noun C1 +setting noun B1 +settle verb B2 +settlement noun C1 +settler noun B2 +seven number A1 +seventeen number A1 +seventy number A1 +several determiner A2 +several pronoun A2 +severe adjective B2 +severely adverb B2 +sex noun B1 +sexual adjective B1 +sexuality noun C1 +sexy adjective B2 +shade noun B2 +shadow noun B2 +shake noun B1 +shake verb A2 +shall modal verb A2 +shallow adjective B2 +shame noun B2 +shape noun A2 +shape verb B2 +shaped adjective B2 +share noun B1 +share verb A1 +shareholder noun C1 +sharp adjective B1 +shatter verb C1 +she pronoun A1 +shed verb C1 +sheep noun A1 +sheer adjective C1 +sheet noun A2 +shelf noun B1 +shell noun B1 +shelter noun B2 +shelter verb B2 +shift noun B1 +shift verb B2 +shine verb B1 +shiny adjective B1 +ship noun A2 +ship verb B2 +shipping noun C1 +shirt noun A1 +shock noun B2 +shock verb B2 +shocked adjective B2 +shocking adjective B2 +shoe noun A1 +shoot noun C1 +shoot verb B1 +shooting noun B2 +shop noun A1 +shop verb A1 +shopping noun A1 +shore noun B2 +short adjective A1 +short-term adjective B2 +shortage noun B2 +shortly adverb B2 +shot noun B2 +should modal verb A1 +shoulder noun A2 +shout noun A2 +shout verb A2 +show noun A1 +show verb A1 +shower noun A1 +shrink verb C1 +shrug verb C1 +shut adjective A2 +shut verb A2 +shy adjective B1 +sibling noun B2 +sick adjective A1 +side noun A2 +sigh noun C1 +sigh verb C1 +sight noun B1 +sign noun A2 +sign verb A2 +signal noun B1 +signal verb B1 +signature noun B2 +significance noun B2 +significant adjective B2 +significantly adverb B2 +silence noun B2 +silent adjective B1 +silk noun B2 +silly adjective B1 +silver adjective A2 +silver noun A2 +similar adjective A1 +similarity noun B1 +similarly adverb B1 +simple adjective A2 +simply adverb B1 +simulate verb C1 +simulation noun C1 +simultaneously adverb C1 +sin noun C1 +since adverb B1 +since conjunction A2 +since preposition A2 +sincere adjective B2 +sing verb A1 +singer noun A1 +singing noun A2 +single adjective A2 +single noun A2 +sink verb B1 +sir noun A2 +sister noun A1 +sit verb A1 +site noun A2 +situated adjective C1 +situation noun A1 +six number A1 +sixteen number A1 +sixty number A1 +size noun A2 +sketch noun C1 +ski adjective A2 +ski noun A2 +ski verb A2 +skiing noun A2 +skill noun A1 +skilled adjective B2 +skin noun A2 +skip verb C1 +skirt noun A1 +skull noun B2 +sky noun A2 +slam verb C1 +slap verb C1 +slash verb C1 +slave noun B2 +slavery noun C1 +sleep noun A2 +sleep verb A1 +slice noun B1 +slice verb B1 +slide noun B2 +slide verb B2 +slight adjective B2 +slightly adverb B1 +slip verb B2 +slogan noun B2 +slope noun B2 +slope verb B2 +slot noun C1 +slow adjective A1 +slow verb B1 +slowly adverb A2 +small adjective A1 +smart adjective B1 +smartphone noun A2 +smash verb C1 +smell noun A2 +smell verb A2 +smile noun A2 +smile verb A2 +smoke noun A2 +smoke verb A2 +smoking noun A2 +smooth adjective B1 +snake noun A1 +snap verb C1 +snow noun A1 +snow verb A1 +so adverb A1 +so conjunction A1 +so-called adjective B2 +soak verb C1 +soap noun A2 +soar verb C1 +soccer noun A2 +social adjective A2 +socialist adjective C1 +society noun A2 +sock noun A2 +soft adjective A2 +software noun B1 +soil noun B1 +solar adjective B2 +soldier noun A2 +sole adjective C1 +solely adverb C1 +solicitor noun C1 +solid adjective B1 +solid noun B1 +solidarity noun C1 +solo adjective C1 +solo noun C1 +solution noun A2 +solve verb A2 +some determiner A1 +some pronoun A1 +somebody pronoun A1 +somehow adverb B2 +someone pronoun A1 +something pronoun A1 +sometime adverb B2 +sometimes adverb A1 +somewhat adverb B2 +somewhere adverb A2 +somewhere pronoun A2 +son noun A1 +song noun A1 +soon adverb A1 +sophisticated adjective B2 +sorry adjective A1 +sorry exclamation A1 +sort noun A2 +sort verb B1 +soul noun B2 +sound adjective C1 +sound noun A1 +sound verb A1 +soup noun A1 +source noun A2 +south adjective A1 +south adverb A1 +south noun A1 +southern adjective B1 +sovereignty noun C1 +space noun A1 +spam noun C1 +span noun C1 +span verb C1 +spare adjective B2 +spare verb C1 +spark verb C1 +speak verb A1 +speaker noun A2 +special adjective A1 +specialist adjective B2 +specialist noun B2 +specialize verb B2 +specialized adjective C1 +species noun B2 +specific adjective A2 +specifically adverb B1 +specification noun C1 +specify verb B2 +specimen noun C1 +spectacle noun C1 +spectacular adjective B2 +spectator noun B2 +spectrum noun C1 +speculate verb B2 +speculation noun B2 +speech noun A2 +speed noun A2 +speed verb B2 +spell noun C1 +spell verb A1 +spelling noun A1 +spend verb A1 +spending noun B1 +sphere noun C1 +spice noun B2 +spicy adjective B1 +spider noun A2 +spill verb B2 +spin noun C1 +spin verb C1 +spine noun C1 +spirit noun B1 +spiritual adjective B2 +spite noun B2 +split noun B2 +split verb B2 +spoil verb B2 +spoken adjective B1 +spokesman noun B2 +spokesperson noun B2 +spokeswoman noun B2 +sponsor noun B2 +sponsor verb B2 +sponsorship noun B2 +spoon noun A2 +sport noun A1 +sporting adjective B2 +spot noun B1 +spot verb B2 +spotlight noun C1 +spouse noun C1 +spread noun B2 +spread verb B1 +spring noun A1 +spring verb B2 +spy noun C1 +spy verb C1 +squad noun C1 +square adjective A2 +square noun A2 +squeeze verb C1 +stab verb C1 +stability noun C1 +stabilize verb C1 +stable adjective B2 +stadium noun B1 +staff noun B1 +stage noun A2 +stage verb B2 +stair noun A2 +stake noun C1 +stall noun B2 +stamp noun A2 +stance noun B2 +stand noun B2 +stand verb A1 +standard adjective B1 +standard noun B1 +standing adjective C1 +star noun A1 +star verb A2 +stare verb B2 +stark adjective C1 +start noun A2 +start verb A1 +starve verb B2 +state adjective B1 +state noun A2 +state verb B1 +statement noun A1 +station noun A1 +statistic noun B1 +statistical adjective C1 +statue noun B1 +status noun B2 +stay noun A2 +stay verb A1 +steadily adverb B2 +steady adjective B2 +steal verb A2 +steam noun B2 +steel noun B2 +steep adjective B2 +steer verb C1 +stem noun C1 +stem verb C1 +step noun A2 +step verb B2 +stereotype noun C1 +stick noun B1 +stick verb B1 +sticky adjective B2 +stiff adjective B2 +still adjective B1 +still adverb A1 +stimulate verb B2 +stimulus noun C1 +stir verb C1 +stock noun B2 +stomach noun A2 +stone noun A2 +stop noun A1 +stop verb A1 +storage noun C1 +store noun A2 +store verb B1 +storm noun A2 +story noun A1 +straight adjective A2 +straight adverb A2 +straightforward adjective C1 +strain noun C1 +strand noun C1 +strange adjective A2 +stranger noun B1 +strategic adjective C1 +strategy noun A2 +stream noun B2 +street noun A1 +strength noun B1 +strengthen verb B2 +stress noun A2 +stress verb A2 +stretch noun B2 +stretch verb B2 +strict adjective B2 +strictly adverb B2 +strike noun B2 +strike verb B2 +striking adjective C1 +string noun B1 +strip noun C1 +strip verb C1 +strive verb C1 +stroke noun B2 +strong adjective A1 +strongly adverb B1 +structural adjective C1 +structure noun A2 +structure verb B2 +struggle noun B2 +struggle verb B2 +student noun A1 +studio noun B1 +study noun A1 +study verb A1 +stuff noun B1 +stuff verb B2 +stumble verb C1 +stun verb C1 +stunning adjective B2 +stupid adjective A2 +style noun A1 +subject adjective B2 +subject noun A1 +submission noun C1 +submit verb B2 +subscriber noun C1 +subscription noun C1 +subsequent adjective B2 +subsequently adverb B2 +subsidy noun C1 +substance noun B1 +substantial adjective C1 +substantially adverb C1 +substitute noun C1 +substitute verb C1 +substitution noun C1 +subtle adjective C1 +suburb noun B2 +suburban adjective C1 +succeed verb A2 +success noun A1 +successful adjective A2 +successfully adverb B1 +succession noun C1 +successive adjective C1 +successor noun C1 +such determiner A2 +such pronoun A2 +suck verb C1 +sudden adjective B1 +suddenly adverb A2 +sue verb C1 +suffer verb B1 +suffering noun B2 +sufficient adjective B2 +sufficiently adverb B2 +sugar noun A1 +suggest verb A2 +suggestion noun A2 +suicide noun C1 +suit noun A2 +suit verb B1 +suitable adjective B1 +suite noun C1 +sum noun B2 +sum verb B2 +summarize verb B1 +summary noun B1 +summer noun A1 +summit noun C1 +sun noun A1 +Sunday noun A1 +super adjective B2 +superb adjective C1 +superior adjective C1 +supermarket noun A1 +supervise verb C1 +supervision noun C1 +supervisor noun C1 +supplement noun C1 +supplement verb C1 +supply noun B1 +supply verb B1 +support noun A2 +support verb A2 +supporter noun B1 +supportive adjective C1 +suppose verb A2 +supposedly adverb C1 +suppress verb C1 +supreme adjective C1 +sure adjective A1 +sure adverb A2 +surely adverb B1 +surface noun B1 +surge noun C1 +surge verb C1 +surgeon noun B2 +surgery noun B2 +surgical adjective C1 +surplus noun C1 +surprise noun A2 +surprise verb A2 +surprised adjective A2 +surprising adjective A2 +surrender verb C1 +surround verb B2 +surrounding adjective B2 +surveillance noun C1 +survey noun A2 +survey verb B2 +survival noun B2 +survive verb B1 +survivor noun B2 +suspect noun B2 +suspect verb B2 +suspend verb B2 +suspension noun C1 +suspicion noun C1 +suspicious adjective C1 +sustain verb C1 +sustainable adjective B2 +swallow verb B2 +swear verb B2 +sweater noun A1 +sweep verb B2 +sweet adjective A2 +sweet noun A2 +swim noun B1 +swim verb A1 +swimming noun A1 +swing noun C1 +swing verb C1 +switch noun B2 +switch verb B1 +sword noun C1 +symbol noun A2 +symbolic adjective C1 +sympathetic adjective B2 +sympathy noun B2 +symptom noun B1 +syndrome noun C1 +synthesis noun C1 +system noun A2 +systematic adjective C1 +T-shirt noun A1 +table noun A1 +tablet noun A2 +tackle noun C1 +tackle verb B2 +tactic noun C1 +tactical adjective C1 +tag noun B2 +tag verb B2 +tail noun B1 +take verb A1 +tale noun B2 +talent noun B1 +talented adjective B1 +talk noun A2 +talk verb A1 +tall adjective A1 +tank noun B2 +tap noun B2 +tap verb B2 +tape noun B1 +target noun A2 +target verb B2 +task noun A2 +taste noun A2 +taste verb A2 +tax noun B1 +tax verb B1 +taxi noun A1 +taxpayer noun C1 +tea noun A1 +teach verb A1 +teacher noun A1 +teaching noun A2 +team noun A1 +tear noun B2 +tear verb B2 +technical adjective B1 +technique noun B1 +technological adjective B2 +technology noun A2 +teenage adjective A2 +teenager noun A1 +teens noun B2 +telephone noun A1 +telephone verb A1 +television noun A1 +tell verb A1 +temperature noun A2 +temple noun B2 +temporarily adverb B2 +temporary adjective B2 +tempt verb C1 +ten number A1 +tenant noun C1 +tend verb B1 +tendency noun B2 +tender adjective C1 +tennis noun A1 +tension noun B2 +tent noun B1 +tenure noun C1 +term noun A2 +term verb B2 +terminal adjective C1 +terminal noun B2 +terminate verb C1 +terms noun B2 +terrain noun C1 +terrible adjective A1 +terribly adverb B2 +terrific adjective C1 +terrify verb B2 +territory noun B2 +terror noun B2 +terrorism noun B2 +terrorist noun B2 +test noun A1 +test verb A1 +testify verb C1 +testimony noun C1 +testing noun B2 +text noun A1 +text verb A2 +textbook noun B2 +texture noun C1 +than conjunction A1 +than preposition A1 +thank verb A1 +thankfully adverb C1 +thanks exclamation A1 +thanks noun A1 +that adverb B1 +that conjunction A1 +that determiner A1 +that pronoun A1 +the definite articleA1 +theatre noun A1 +theatrical adjective C1 +theft noun B2 +their determiner A1 +theirs pronoun B1 +them pronoun A1 +theme noun B1 +themselves pronoun A2 +then adverb A1 +theology noun C1 +theoretical adjective C1 +theory noun B1 +therapist noun B2 +therapy noun B2 +there adverb A1 +thereafter adverb C1 +thereby adverb C1 +therefore adverb B1 +thesis noun B2 +they pronoun A1 +thick adjective A2 +thief noun A2 +thin adjective A2 +thing noun A1 +think verb A1 +thinking noun A2 +third noun A2 +third ordinalnumber A1 +thirsty adjective A1 +thirteen number A1 +thirty number A1 +this adverb B1 +this determiner A1 +this pronoun A1 +thorough adjective B2 +thoroughly adverb B2 +though adverb B1 +though conjunction B1 +thought noun A2 +thought-provoking adjective C1 +thoughtful adjective C1 +thousand number A1 +thread noun C1 +threat noun B2 +threaten verb B2 +three number A1 +threshold noun C1 +thrilled adjective C1 +thrive verb C1 +throat noun B1 +through adverb A1 +through preposition A1 +throughout adverb B1 +throughout preposition B1 +throw verb A2 +thumb noun B2 +Thursday noun A1 +thus adverb B2 +ticket noun A1 +tide noun C1 +tidy adjective A2 +tidy verb A2 +tie noun A2 +tie verb A2 +tight adjective B1 +tighten verb C1 +till conjunction B1 +till preposition B1 +timber noun C1 +time noun A1 +time verb B2 +timely adjective C1 +timing noun B2 +tin noun B1 +tiny adjective B1 +tip noun A2 +tip verb B1 +tired adjective A1 +tissue noun B2 +title noun A1 +title verb B2 +to infinitive markerA1 +to preposition A1 +tobacco noun C1 +today adverb A1 +today noun A1 +toe noun B1 +together adverb A1 +toilet noun A1 +tolerance noun C1 +tolerate verb C1 +toll noun C1 +tomato noun A1 +tomorrow adverb A1 +tomorrow noun A1 +ton noun B2 +tone noun B2 +tongue noun B1 +tonight adverb A1 +tonight noun A1 +tonne noun B2 +too adverb A1 +tool noun A2 +tooth noun A1 +top adjective A2 +top noun A2 +top verb C1 +topic noun A1 +torture noun C1 +torture verb C1 +toss verb C1 +total adjective B1 +total noun B1 +total verb C1 +totally adverb B1 +touch noun B1 +touch verb A2 +tough adjective B2 +tour noun A2 +tour verb B1 +tourism noun A2 +tourist noun A1 +tournament noun B2 +towards preposition A2 +towel noun A2 +tower noun A2 +town noun A1 +toxic adjective C1 +toy adjective A2 +toy noun A2 +trace noun C1 +trace verb B2 +track noun A2 +track verb B2 +trade noun B1 +trade verb B1 +trademark noun C1 +trading noun B2 +tradition noun A2 +traditional adjective A2 +traffic noun A1 +tragedy noun B2 +tragic adjective B2 +trail noun C1 +trail verb C1 +trailer noun C1 +train noun A1 +train verb A2 +trainer noun A2 +training noun A2 +trait noun B2 +transaction noun C1 +transcript noun C1 +transfer noun B2 +transfer verb B2 +transform verb B2 +transformation noun C1 +transit noun C1 +transition noun B2 +translate verb B1 +translation noun B1 +transmission noun C1 +transmit verb B2 +transparency noun C1 +transparent adjective C1 +transport noun A2 +transport verb B1 +transportation noun B2 +trap noun B2 +trap verb B2 +trauma noun C1 +travel noun A1 +travel verb A1 +traveller noun A2 +treasure noun B2 +treat verb B1 +treatment noun B1 +treaty noun C1 +tree noun A1 +tremendous adjective C1 +trend noun B1 +trial noun B2 +tribal adjective C1 +tribe noun B2 +tribunal noun C1 +tribute noun C1 +trick noun B1 +trick verb B1 +trigger noun C1 +trigger verb B2 +trillion number B2 +trio noun C1 +trip noun A1 +trip verb B2 +triumph noun C1 +troop noun B2 +trophy noun C1 +tropical adjective B2 +trouble noun A2 +trouble verb B2 +troubled adjective C1 +trousers noun A1 +truck noun A2 +true adjective A1 +truly adverb B2 +trust noun B2 +trust verb B2 +trustee noun C1 +truth noun B1 +try noun B2 +try verb A1 +tsunami noun B2 +tube noun B1 +Tuesday noun A1 +tuition noun C1 +tune noun B2 +tunnel noun B2 +turn noun A1 +turn verb A1 +turnout noun C1 +turnover noun C1 +TV noun A1 +twelve number A1 +twenty number A1 +twice adverb A1 +twin adjective A2 +twin noun A2 +twist noun C1 +twist verb C1 +two number A1 +type noun A1 +type verb B1 +typical adjective A2 +typically adverb B1 +tyre noun B1 +ugly adjective B1 +ultimate adjective B2 +ultimately adverb B2 +umbrella noun A1 +unable adjective B1 +unacceptable adjective B2 +uncertainty noun B2 +uncle noun A1 +uncomfortable adjective B1 +unconscious adjective B2 +under adverb A1 +under preposition A1 +undergo verb B2 +undergraduate noun C1 +underground adjective A2 +underground adverb A2 +underlying adjective C1 +undermine verb C1 +understand verb A1 +understanding noun A2 +undertake verb B2 +underwear noun B1 +undoubtedly adverb C1 +unemployed adjective B1 +unemployment noun B1 +unexpected adjective B2 +unfair adjective B1 +unfold verb B2 +unfortunate adjective B2 +unfortunately adverb A2 +unhappy adjective A2 +uniform noun A2 +unify verb C1 +union noun B1 +unique adjective B2 +unit noun A2 +unite verb B2 +united adjective A2 +unity noun B2 +universal adjective B2 +universe noun B2 +university noun A1 +unknown adjective B2 +unless conjunction B1 +unlike preposition B1 +unlikely adjective B1 +unnecessary adjective B1 +unpleasant adjective B1 +unprecedented adjective C1 +until conjunction A1 +until preposition A1 +unusual adjective A2 +unveil verb C1 +up adverb A1 +up preposition A1 +upcoming adjective C1 +update noun B1 +update verb B1 +upgrade noun C1 +upgrade verb C1 +uphold verb C1 +upon preposition B1 +upper adjective B2 +upset adjective B1 +upset verb B1 +upstairs adjective A2 +upstairs adverb A1 +upwards adverb B2 +urban adjective B2 +urge verb B2 +urgent adjective B2 +us pronoun A1 +usage noun B2 +use noun A2 +use verb A1 +used adjective B1 +used to modal verb A2 +useful adjective A1 +useless adjective B2 +user noun A2 +usual adjective A2 +usually adverb A1 +utility noun C1 +utilize verb C1 +utterly adverb C1 +vacation noun A1 +vacuum noun C1 +vague adjective C1 +valid adjective B2 +validity noun C1 +valley noun A2 +valuable adjective B1 +value noun B1 +value verb B2 +van noun A2 +vanish verb C1 +variable adjective C1 +variable noun C1 +variation noun B2 +varied adjective C1 +variety noun A2 +various adjective B1 +vary verb B2 +vast adjective B2 +vegetable noun A1 +vehicle noun A2 +vein noun C1 +venture noun C1 +venture verb C1 +venue noun B2 +verb al adjective C1 +verdict noun C1 +verify verb C1 +verse noun C1 +version noun B1 +versus preposition C1 +vertical adjective B2 +very adjective B2 +very adverb A1 +vessel noun C1 +veteran noun C1 +via preposition B2 +viable adjective C1 +vibrant adjective C1 +vice noun C1 +vicious adjective C1 +victim noun B1 +victory noun B2 +video noun A1 +view noun A2 +view verb B1 +viewer noun B1 +viewpoint noun B2 +village noun A1 +villager noun C1 +violate verb C1 +violation noun C1 +violence noun B2 +violent adjective B1 +virtual adjective B2 +virtue noun C1 +virus noun A2 +visa noun B2 +visible adjective B2 +vision noun B2 +visit noun A1 +visit verb A1 +visitor noun A1 +visual adjective B2 +vital adjective B2 +vitamin noun B2 +vocal adjective C1 +voice noun A2 +volume noun B2 +voluntary adjective B2 +volunteer noun B1 +volunteer verb B1 +vote noun B1 +vote verb B1 +voting noun B2 +vow verb C1 +vulnerability noun C1 +vulnerable adjective C1 +wage noun B2 +wait noun A2 +wait verb A1 +waiter noun A1 +wake verb A1 +walk noun A1 +walk verb A1 +wall noun A1 +wander verb B2 +want verb A1 +war noun A2 +ward noun C1 +warehouse noun C1 +warfare noun C1 +warm adjective A1 +warm verb B1 +warming noun B2 +warn verb B1 +warning noun B1 +warrant noun C1 +warrant verb C1 +warrior noun C1 +wash noun A2 +wash verb A1 +washing noun A2 +waste adjective B1 +waste noun B1 +waste verb B1 +watch noun A1 +watch verb A1 +water noun A1 +water verb B1 +wave noun A2 +wave verb B1 +way adverb B2 +way noun A1 +we pronoun A1 +weak adjective A2 +weaken verb C1 +weakness noun B2 +wealth noun B2 +wealthy adjective B2 +weapon noun B1 +wear verb A1 +weather noun A1 +weave verb C1 +web noun A2 +website noun A1 +wedding noun A2 +Wednesday noun A1 +weed noun C1 +week noun A1 +weekend noun A1 +weekly adjective B2 +weigh verb B1 +weight noun A2 +weird adjective B2 +welcome adjective A1 +welcome exclamation A1 +welcome noun A2 +welcome verb A1 +welfare noun B2 +well adjective A1 +well adverb A1 +well exclamation A1 +well noun C1 +well-being noun C1 +west adjective A1 +west adverb A1 +west noun A1 +western adjective B1 +wet adjective A2 +what determiner A1 +what pronoun A1 +whatever adverb C1 +whatever determiner B1 +whatever pronoun B1 +whatsoever adverb C1 +wheat noun B2 +wheel noun A2 +when adverb A1 +when conjunction A1 +when pronoun A1 +whenever conjunction B1 +where adverb A1 +where conjunction A1 +whereas conjunction B2 +whereby adverb C1 +wherever conjunction B2 +whether conjunction B1 +which determiner A1 +which pronoun A1 +while conjunction A2 +while noun B1 +whilst conjunction C1 +whip verb C1 +whisper noun B2 +whisper verb B2 +white adjective A1 +white noun A1 +who pronoun A1 +whoever pronoun B2 +whole adjective A2 +whole noun B1 +wholly adverb C1 +whom pronoun B2 +whose determiner A2 +whose pronoun A2 +why adverb A1 +wide adjective A2 +widely adverb B2 +widen verb C1 +widespread adjective B2 +widow noun C1 +width noun C1 +wife noun A1 +wild adjective A2 +wildlife noun B2 +will noun B1 +will modal verb A1 +willing adjective B2 +willingness noun C1 +win noun B1 +win verb A1 +wind noun A2 +wind verb B2 +window noun A1 +wine noun A1 +wing noun B1 +winner noun A2 +winter noun A1 +wipe verb C1 +wire noun B2 +wisdom noun B2 +wise adjective B2 +wish noun A2 +wish verb A2 +wit noun C1 +with preposition A1 +withdraw verb B2 +withdrawal noun C1 +within preposition B1 +without preposition A1 +witness noun B2 +witness verb B2 +woman noun A1 +wonder noun B1 +wonder verb B1 +wonderful adjective A1 +wood noun A2 +wooden adjective A2 +wool noun B1 +word noun A1 +work noun A1 +work verb A1 +worker noun A1 +workforce noun B2 +working adjective A2 +workout noun C1 +workplace noun B2 +workshop noun B2 +world noun A1 +worldwide adjective B1 +worldwide adverb B1 +worm noun B2 +worried adjective A2 +worry noun B1 +worry verb A2 +worse adjective A2 +worse adverb B1 +worse noun B2 +worship noun C1 +worship verb C1 +worst adjective A2 +worst adverb B1 +worst noun B2 +worth adjective B1 +worth noun B2 +worthwhile adjective C1 +worthy adjective C1 +would modal verb A1 +wound noun B2 +wound verb B2 +wow exclamation A2 +wrap verb B2 +wrist noun B2 +write verb A1 +writer noun A1 +writing noun A1 +written adjective B1 +wrong adjective A1 +wrong adverb B1 +wrong noun B2 +yard noun B1 +yeah exclamation A1 +year noun A1 +yell verb C1 +yellow adjective A1 +yellow noun A1 +yes exclamation A1 +yesterday adverb A1 +yesterday noun A1 +yet adverb A2 +yet conjunction B2 +yield noun C1 +yield verb C1 +you pronoun A1 +young adjective A1 +young noun B1 +youngster noun C1 +your determiner A1 +yours pronoun A2 +yourself pronoun A1 +youth noun B1 +zero number A2 +zone noun B2 diff --git a/app/difficulty.py b/app/difficulty.py index cb93768..39d4a50 100644 --- a/app/difficulty.py +++ b/app/difficulty.py @@ -7,7 +7,7 @@ import pickle import math -from wordfreqCMD import remove_punctuation, freq, sort_in_descending_order, sort_in_ascending_order +from wordfreqCMD import remove_punctuation, freq, sort_in_descending_order, sort_in_ascending_order, map_percentages_to_levels import snowballstemmer @@ -18,6 +18,7 @@ def load_record(pickle_fname): return d +ENGLISH_WORD_DIFFICULTY_DICT = {} def convert_test_type_to_difficulty_level(d): """ 对原本的单词库中的单词进行难度评级 @@ -39,8 +40,10 @@ def convert_test_type_to_difficulty_level(d): elif 'BBC' in d[k]: result[k] = 8 - return result # {'apple': 4, ...} + global ENGLISH_WORD_DIFFICULTY_DICT + ENGLISH_WORD_DIFFICULTY_DICT = result + return result # {'apple': 4, ...} def get_difficulty_level_for_user(d1, d2): """ @@ -49,7 +52,11 @@ def get_difficulty_level_for_user(d1, d2): 在d2的后面添加单词,没有新建一个新的字典 """ # TODO: convert_test_type_to_difficulty_level() should not be called every time. Each word's difficulty level should be pre-computed. - d2 = convert_test_type_to_difficulty_level(d2) # 根据d2的标记评级{'apple': 4, 'abandon': 4, ...} + if ENGLISH_WORD_DIFFICULTY_DICT == {}: + d2 = convert_test_type_to_difficulty_level(d2) # 根据d2的标记评级{'apple': 4, 'abandon': 4, ...} + else: + d2 = ENGLISH_WORD_DIFFICULTY_DICT + stemmer = snowballstemmer.stemmer('english') for k in d1: # 用户的词 @@ -87,30 +94,58 @@ def revert_dict(d): return d2 -def user_difficulty_level(d_user, d): +def user_difficulty_level(d_user, d, calc_func=0): + ''' + two ways to calculate difficulty_level + set calc_func!=0 to use sqrt, otherwise use weighted average + ''' + if calc_func != 0: + # calculation function 1: sqrt + d_user2 = revert_dict(d_user) # key is date, and value is a list of words added in that date + geometric = 0 + count = 0 + for date in sorted(d_user2.keys(), + reverse=True): # most recently added words are more important while determining user's level + lst = d_user2[date] # a list of words + lst2 = [] # a list of tuples, (word, difficulty level) + for word in lst: + if word in d: + lst2.append((word, d[word])) + + lst3 = sort_in_ascending_order(lst2) # easiest tuple first + # print(lst3) + for t in lst3: + word = t[0] + hard = t[1] + # print('WORD %s HARD %4.2f' % (word, hard)) + geometric = geometric + math.log(hard) + count += 1 + return math.exp(geometric / max(count, 1)) + + # calculation function 2: weighted average d_user2 = revert_dict(d_user) # key is date, and value is a list of words added in that date - count = 0 - geometric = 1 - for date in sorted(d_user2.keys(), - reverse=True): # most recently added words are more important while determining user's level + count = {} # number of all kinds of words + percentages = {} # percentages of all kinds of difficulties + total = 0 # total words + for date in d_user2.keys(): lst = d_user2[date] # a list of words - lst2 = [] # a list of tuples, (word, difficulty level) for word in lst: if word in d: - lst2.append((word, d[word])) + if d[word] not in count: + count[d[word]] = 0 + count[d[word]] += 1 + total += 1 - lst3 = sort_in_ascending_order(lst2) # easiest tuple first - # print(lst3) - for t in lst3: - word = t[0] - hard = t[1] - # print('WORD %s HARD %4.2f' % (word, hard)) - geometric = geometric * (hard) - count += 1 - if count >= 10: - return geometric ** (1 / count) + if total == 0: + return 1 + for k in count.keys(): + percentages[k] = count[k] / total + weight = map_percentages_to_levels(percentages) + sum = 0 + for k in weight.keys(): + sum += weight[k] * k + return sum - return geometric ** (1 / max(count, 1)) def text_difficulty_level(s, d): diff --git a/app/main.py b/app/main.py index 4e3f829..c39f0b7 100644 --- a/app/main.py +++ b/app/main.py @@ -1,24 +1,29 @@ -#! /usr/bin/python3 -# -*- coding: utf-8 -*- - ########################################################################### # Copyright 2019 (C) Hui Lan # Written permission must be obtained from the author for commercial uses. ########################################################################### -from flask import escape +from flask import abort, jsonify +from markupsafe import escape +from collections import Counter from Login import * from Article import * import Yaml from user_service import userService from account_service import accountService from admin_service import adminService, ADMIN_NAME +from api_service import apiService +import os +from translate import * + + app = Flask(__name__) -app.secret_key = 'lunch.time!' +app.secret_key = os.urandom(32) # 将蓝图注册到Lab app app.register_blueprint(userService) app.register_blueprint(accountService) app.register_blueprint(adminService) +app.register_blueprint(apiService) path_prefix = '/var/www/wordfreq/wordfreq/' path_prefix = './' # comment this line in deployment @@ -55,6 +60,11 @@ def appears_in_test(word, d): return ','.join(d[word]) +def good_word(word): + return len(word) < len('Pneumonoultramicroscopicsilicovolcanoconiosis') \ + and Counter(word).most_common(1)[0][1] <= 4 + + @app.route("/mark", methods=['GET', 'POST']) def mark_word(): ''' @@ -80,10 +90,23 @@ def mainpage(): 根据GET或POST方法来返回不同的主界面 :return: 主界面 ''' + + article_text = get_all_articles() + texts = [item['text'] for item in article_text] + oxford_words = load_oxford_words(oxford_words_path) + + # 提取所有单词 + all_words = [] + for text in texts: + words = re.findall(r'\b\w+\b', text.lower()) + all_words.extend(words) + oxford_word_count = sum(1 for word in all_words if word in oxford_words) + ratio = calculate_ratio(oxford_word_count, len(all_words)) + if request.method == 'POST': # when we submit a form content = escape(request.form['content']) f = WordFreq(content) - lst = f.get_freq() + lst = [ t for t in f.get_freq() if good_word(t[0]) ] # only keep normal words # save history d = load_freq_history(path_prefix + 'static/frequency/frequency.p') lst_history = pickle_idea.dict2lst(d) @@ -103,7 +126,17 @@ def mainpage(): d_len=d_len, lst=lst, yml=Yaml.yml, - number_of_essays=number_of_essays) + number_of_essays=number_of_essays, + ratio = ratio) + +@app.route("/translate", methods=['POST']) +def translate_word(): + data = request.get_json() + word = data.get('word', '') + from_lang = data.get('from_lang', 'en') # 假设默认源语言是英语 + to_lang = data.get('to_lang', 'zh') # 假设默认目标语言是中文 + result = translate(word, from_lang, to_lang) + return jsonify({'translation': result}) if __name__ == '__main__': diff --git a/app/model/__init__.py b/app/model/__init__.py index 9526313..f5256a2 100644 --- a/app/model/__init__.py +++ b/app/model/__init__.py @@ -1,7 +1,7 @@ from pony.orm import * db = Database() -db.bind("sqlite", "../static/wordfreqapp.db", create_db=True) # bind sqlite file +db.bind("sqlite", "../db/wordfreqapp.db", create_db=True) # bind sqlite file class User(db.Entity): diff --git a/app/model/article.py b/app/model/article.py index a3b4bf7..bf19ded 100644 --- a/app/model/article.py +++ b/app/model/article.py @@ -7,7 +7,7 @@ def add_article(content, source="manual_input", level="5", question="No question Article( text=content, source=source, - date=datetime.now().strftime("%-d %b %Y"), # format style of `5 Oct 2022` + date=datetime.now().strftime("%d %b %Y"), # format style of `5 Oct 2022` level=level, question=question, ) @@ -32,3 +32,17 @@ def get_page_articles(num, size): x for x in Article.select().order_by(desc(Article.article_id)).page(num, size) ] + + +def get_all_articles(): + articles = [] + with db_session: + for article in Article.select(): + articles.append(article.to_dict()) + return articles + + +def get_article_by_id(article_id): + with db_session: + article = Article.get(article_id=article_id) + return [article.to_dict()] diff --git a/app/pickle_idea.py b/app/pickle_idea.py index 45bd19a..d4fe991 100644 --- a/app/pickle_idea.py +++ b/app/pickle_idea.py @@ -6,6 +6,7 @@ # Purpose: dictionary & pickle as a simple means of database. # Task: incorporate the functions into wordfreqCMD.py such that it will also show cumulative frequency. +import os import pickle from datetime import datetime @@ -55,11 +56,13 @@ def save_frequency_to_pickle(d, pickle_fname): f.close() def unfamiliar(path,word): - f = open(path,"rb") - dic = pickle.load(f) - dic[word] += [datetime.now().strftime('%Y%m%d%H%M')] - fp = open(path,"wb") - pickle.dump(dic,fp) + if not os.path.exists(path): + return None + with open(path,"rb") as f: + dic = pickle.load(f) + dic[word] += [datetime.now().strftime('%Y%m%d%H%M')] + with open(path,"wb") as fp: + pickle.dump(dic,fp) def familiar(path,word): f = open(path,"rb") diff --git a/app/pickle_idea2.py b/app/pickle_idea2.py index 0da55bc..b5716bf 100644 --- a/app/pickle_idea2.py +++ b/app/pickle_idea2.py @@ -64,7 +64,6 @@ def load_record(pickle_fname): def save_frequency_to_pickle(d, pickle_fname): f = open(pickle_fname, 'wb') - exclusion_lst = ['one', 'no', 'has', 'had', 'do', 'that', 'have', 'by', 'not', 'but', 'we', 'this', 'my', 'him', 'so', 'or', 'as', 'are', 'it', 'from', 'with', 'be', 'can', 'for', 'an', 'if', 'who', 'whom', 'whose', 'which', 'the', 'to', 'a', 'of', 'and', 'you', 'i', 'he', 'she', 'they', 'me', 'was', 'were', 'is', 'in', 'at', 'on', 'their', 'his', 'her', 's', 'said', 'all', 'did', 'been', 'w'] d2 = {} for k in d: if not k in exclusion_lst and not k.isnumeric() and not len(k) < 2: @@ -73,6 +72,7 @@ def save_frequency_to_pickle(d, pickle_fname): f.close() +exclusion_lst = ['one', 'no', 'has', 'had', 'do', 'that', 'have', 'by', 'not', 'but', 'we', 'this', 'my', 'him', 'so', 'or', 'as', 'are', 'it', 'from', 'with', 'be', 'can', 'for', 'an', 'if', 'who', 'whom', 'whose', 'which', 'the', 'to', 'a', 'of', 'and', 'you', 'i', 'he', 'she', 'they', 'me', 'was', 'were', 'is', 'in', 'at', 'on', 'their', 'his', 'her', 's', 'said', 'all', 'did', 'been', 'w'] if __name__ == '__main__': diff --git a/app/static/config.yml b/app/static/config.yml index 285f31f..7e681fe 100644 --- a/app/static/config.yml +++ b/app/static/config.yml @@ -2,13 +2,14 @@ css: item: - ../static/css/bootstrap.css - + - ../static/css/highlighted.css # 全局引入的js文件地址 js: head: # 在页面加载之前加载 - ../static/js/jquery.js - ../static/js/read.js - ../static/js/word_operation.js + - ../static/js/checkboxes.js bottom: # 在页面加载完之后加载 - ../static/js/fillword.js - ../static/js/highlight.js diff --git a/app/static/css/button.css b/app/static/css/button.css new file mode 100644 index 0000000..9953857 --- /dev/null +++ b/app/static/css/button.css @@ -0,0 +1,37 @@ +/* 按钮(上一篇,下一篇)样式 */ +.pagination { + padding: 20px; + max-width: 600px; +} + +.arrow { + margin-right: 15px; + display: flex; + align-items: center; + background: #007BFF; /* 按钮背景颜色 */ + border: none; + color: #FFF; /* 按钮文字颜色 */ + padding: 5px 12px; + font-size: 20px; + border-radius: 5px; + transition: background-color 0.3s ease; +} + +.arrow i { + margin: 0 5px; +} + +.arrow:hover { + background-color: #0056b3; /* 按钮悬停时的背景颜色 */ + cursor: pointer; +} + +.arrow:focus { + outline: none; + box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.5); +} + +/* 为首页时按钮(Pre Article)的背景颜色 */ +.gray-background { + background-color: #6c757d !important; +} diff --git a/app/static/css/highlighted.css b/app/static/css/highlighted.css new file mode 100644 index 0000000..167f595 --- /dev/null +++ b/app/static/css/highlighted.css @@ -0,0 +1,5 @@ + +.highlighted { + color: red; + font-weight: normal; +} \ No newline at end of file diff --git a/app/static/css/slide-unlock.css b/app/static/css/slide-unlock.css new file mode 100644 index 0000000..2816ebb --- /dev/null +++ b/app/static/css/slide-unlock.css @@ -0,0 +1,52 @@ + +#slider { + margin: 20px auto; + width: 200px; + height: 40px; + position: relative; + border-radius: 5px; + background-color: #dae2d0; + overflow: hidden; + text-align: center; + user-select: none; + -moz-user-select: none; + -webkit-user-select: none; +} + +#slider_bg { + position: absolute; + left: 0; + top: 0; + height: 100%; + background-color: #7AC23C; + z-index: 1; +} + +#label { + width: 46px; + position: absolute; + left: 0; + top: 0; + height: 38px; + line-height: 38px; + border: 1px solid #cccccc; + background: #fff; + z-index: 3; + cursor: move; + color: #ff9e77; + font-size: 16px; + font-weight: 900; +} + +#labelTip { + position: absolute; + left: 0; + width: 100%; + height: 100%; + font-size: 13px; + font-family: 'Microsoft Yahei', serif; + color: #787878; + line-height: 38px; + text-align: center; + z-index: 2; +} diff --git a/app/static/js/checkboxes.js b/app/static/js/checkboxes.js new file mode 100644 index 0000000..297df55 --- /dev/null +++ b/app/static/js/checkboxes.js @@ -0,0 +1,5 @@ +function toggleCheckboxSelection(checkStatus) { + // used in userpage_post.html + const checkBoxes = document.getElementsByName('marked'); + checkBoxes.forEach((checkbox) => { checkbox.checked = checkStatus;} ); +} diff --git a/app/static/js/fillword.js b/app/static/js/fillword.js index b967633..3e88107 100644 --- a/app/static/js/fillword.js +++ b/app/static/js/fillword.js @@ -1,5 +1,5 @@ -let isRead = true; -let isChoose = true; +let isRead = localStorage.getItem('readChecked') !== 'false'; // default to true +let isChoose = localStorage.getItem('chooseChecked') !== 'false'; function getWord() { return window.getSelection ? window.getSelection() : document.selection.createRange().text; @@ -8,24 +8,45 @@ function getWord() { function fillInWord() { let word = getWord(); if (isRead) Reader.read(word, inputSlider.value); - if (!isChoose) return; + if (!isChoose) { + if(isHighlight){ + const element = document.getElementById("selected-words3"); + element.value = element.value + " " + word; + } + return; + } const element = document.getElementById("selected-words"); + localStorage.setItem('nowWords', element.value); element.value = element.value + " " + word; + localStorage.setItem('selectedWords', element.value); } -document.getElementById("text-content").addEventListener("click", fillInWord, false); +if (document.getElementById("text-content")) { + document.getElementById("text-content").addEventListener("click", fillInWord, false); +} const sliderValue = document.getElementById("rangeValue"); const inputSlider = document.getElementById("rangeComponent"); -inputSlider.oninput = () => { - let value = inputSlider.value; - sliderValue.textContent = value + '×'; -}; + +if (inputSlider) { + inputSlider.oninput = () => { + let value = inputSlider.value; + sliderValue.textContent = value + '×'; + }; +} function onReadClick() { isRead = !isRead; + localStorage.setItem('readChecked', isRead); } function onChooseClick() { isChoose = !isChoose; + localStorage.setItem('chooseChecked', isChoose); } + +// 如果网页刷新,停止播放声音 +if (performance.getEntriesByType("navigation")[0].type == "reload") { + Reader.stopRead(); +} + diff --git a/app/static/js/highlight.js b/app/static/js/highlight.js index 0cea31a..7a1df5d 100644 --- a/app/static/js/highlight.js +++ b/app/static/js/highlight.js @@ -1,4 +1,4 @@ -let isHighlight = true; +let isHighlight = localStorage.getItem('highlightChecked') !== 'false'; // default to true function cancelBtnHandler() { cancelHighlighting(); @@ -9,75 +9,113 @@ function cancelBtnHandler() { } function showBtnHandler() { - document.getElementById("text-content").removeEventListener("click", fillInWord2, false); - document.getElementById("text-content").removeEventListener("touchstart", fillInWord2, false); - document.getElementById("text-content").addEventListener("click", fillInWord, false); - document.getElementById("text-content").addEventListener("touchstart", fillInWord, false); - highLight(); + if (document.getElementById("text-content")) { + document.getElementById("text-content").removeEventListener("click", fillInWord2, false); + document.getElementById("text-content").removeEventListener("touchstart", fillInWord2, false); + document.getElementById("text-content").addEventListener("click", fillInWord, false); + document.getElementById("text-content").addEventListener("touchstart", fillInWord, false); + highLight(); + } +} +function replaceWords(str, word) { + let count = 0; + + const regex = new RegExp(`(^|\\s)${word}(?=\\s|$)`, 'g'); + + let result = str.replace(regex, (match, p1) => { + count++; + // p1 保留前导空格(如果有),仅第一个匹配保留,后续匹配替换为空字符串 + return count === 1 ? match : p1; + }); + + return result; +} + +function countWords(str, word) { + // 使用正则表达式匹配目标单词的整个单词边界情况,包括前后空格、行首和行尾 + const regex = new RegExp(`(^|\\s)${word}(?=\\s|$)`, 'g'); + let match; + let count = 0; + + // 迭代匹配所有符合条件的单词 + while ((match = regex.exec(str)) !== null) { + count++; + } + + return count; +} +//用于替换单词 +function replaceAllWords(str, word, replacement) { + const regex = new RegExp(`(^|\\s)${word}(?=\\s|$)`, 'gi'); + let result = str.replace(regex, (match, p1) => { + return p1 + replacement; + }); + + return result; } function getWord() { - return window.getSelection ? window.getSelection() : document.selection.createRange().text; + return window.getSelection ? window.getSelection().toString() : document.selection.createRange().text; } function highLight() { if (!isHighlight) return; - let articleContent = document.getElementById("article").innerText; //将原来的.innerText改为.innerHtml,使用innerText会把原文章中所包含的
标签去除,导致处理后的文章内容失去了原来的格式 + let word = (getWord() + "").trim().replace(/[.,\/#!$%\^&\*;:{}=\-_`~()]/g, ""); + let articleContent = document.getElementById("article").innerHTML; // innerHTML保留HTML标签来保持部分格式,且适配不同的浏览器 let pickedWords = document.getElementById("selected-words"); // words picked to the text area let dictionaryWords = document.getElementById("selected-words2"); // words appearing in the user's new words list - let allWords = ""; //初始化allWords的值,避免进入判断后编译器认为allWords未初始化的问题 - if(dictionaryWords != null){//增加一个判断,检查生词本里面是否为空,如果为空,allWords只添加选中的单词 - allWords = pickedWords.value + " " + dictionaryWords.value; - } - else{ - allWords = pickedWords.value + " "; - } - const list = allWords.split(" ");//将所有的生词放入一个list中,用于后续处理 - for (let i = 0; i < list.length; ++i) { - list[i] = list[i].replace(/(^\s*)|(\s*$)/g, ""); //消除单词两边的空字符 - list[i] = list[i].replace('|', ""); - list[i] = list[i].replace('?', ""); - if (list[i] !== "" && "".indexOf(list[i]) === -1 && "".indexOf(list[i]) === -1) { - //将文章中所有出现该单词word的地方改为:"" + word + ""。 正则表达式RegExp()中,"\\b"代表单词边界匹配。 + let allWords = dictionaryWords === null ? pickedWords.value + " " : pickedWords.value + " " + dictionaryWords.value; + let highlightWords = document.getElementById("selected-words3"); + allWords = highlightWords == null ? allWords : allWords + " " + highlightWords.value; + const list = allWords.split(" "); // 将所有的生词放入一个list中 + if(word !== null && word !== "" && word !== " "){ + if(localStorage.getItem("nowWords").indexOf(word) !== -1 || localStorage.getItem("nowWords").indexOf(word.toLowerCase()) !== -1){ + articleContent = articleContent.replace(new RegExp('' + word + '', "g"), word); - //修改代码 - let articleContent_fb = articleContent; //文章副本 - while(articleContent_fb.toLowerCase().indexOf(list[i].toLowerCase()) !== -1 && list[i]!=""){ - //找到副本中和list[i]匹配的第一个单词(第一种匹配情况),并赋值给list[i]。 - const index = articleContent_fb.toLowerCase().indexOf(list[i].toLowerCase()); - list[i] = articleContent_fb.substring(index, index + list[i].length); - - articleContent_fb = articleContent_fb.substring(index + list[i].length); // 使用副本中list[i]之后的子串替换掉副本 - articleContent = articleContent.replace(new RegExp("\\b"+list[i]+"\\b","g"),"" + list[i] + ""); - } + let count=countWords(pickedWords.value,word) + let currentWords=localStorage.getItem("nowWords")+" "+word + localStorage.setItem("nowWords",currentWords) +// + if(count>0){ + if(count==1){ + localStorage.setItem("nowWords",replaceWords(currentWords,word)) + }else{ + localStorage.setItem("nowWords",replaceAllWords(currentWords,word,"")) } } + + + pickedWords.value = localStorage.getItem("nowWords") + document.getElementById("article").innerHTML = articleContent; + return; + } + } + let totalSet = new Set(); + for (let i = 0; i < list.length; ++i) { + list[i] = list[i].replace(/(^\W*)|(\W*$)/g, ""); // 消除单词两边的非单词字符 + list[i] = list[i].replace('|', ""); + list[i] = list[i].replace('?', ""); + if (list[i] != "" && !totalSet.has(list[i])) { + // 返回所有匹配单词的集合, 正则表达式RegExp()中, "\b"匹配一个单词的边界, g 表示全局匹配, i 表示对大小写不敏感。 + let matches = new Set(articleContent.match(new RegExp("\\b" + list[i] + "\\b", "gi"))); + totalSet = new Set([...totalSet, ...matches]); + } + } + // 删除所有的""标签,防止标签发生嵌套 + articleContent = articleContent.replace(new RegExp('',"gi"), "") + articleContent = articleContent.replace(new RegExp("","gi"), ""); + // 将文章中所有出现该单词word的地方改为:"" + word + ""。 + for (let word of totalSet) { + articleContent = articleContent.replace(new RegExp("\\b" + word + "\\b", "g"), "" + word + ""); + } document.getElementById("article").innerHTML = articleContent; + addClickEventToHighlightedWords(); } function cancelHighlighting() { - let articleContent = document.getElementById("article").innerText;//将原来的.innerText改为.innerHtml,原因同上 - let pickedWords = document.getElementById("selected-words"); - const dictionaryWords = document.getElementById("selected-words2"); - const list = pickedWords.value.split(" "); - if (pickedWords != null) { - for (let i = 0; i < list.length; ++i) { - list[i] = list[i].replace(/(^\s*)|(\s*$)/g, ""); - if (list[i] !== "") { //原来判断的代码中,替换的内容为“list[i]”这个字符串,这明显是错误的,我们需要替换的是list[i]里的内容 - articleContent = articleContent.replace(new RegExp(""+list[i]+"", "g"), list[i]); - } - } - } - if (dictionaryWords != null) { - let list2 = pickedWords.value.split(" "); - for (let i = 0; i < list2.length; ++i) { - list2 = dictionaryWords.value.split(" "); - list2[i] = list2[i].replace(/(^\s*)|(\s*$)/g, ""); - if (list2[i] !== "") { //原来代码中,替换的内容为“list[i]”这个字符串,这明显是错误的,我们需要替换的是list[i]里的内容 - articleContent = articleContent.replace(new RegExp(""+list2[i]+"", "g"), list2[i]); - } - } - } + let articleContent = document.getElementById("article").innerHTML; + articleContent = articleContent.replace(new RegExp('',"gi"), "") + articleContent = articleContent.replace(new RegExp("","gi"), ""); document.getElementById("article").innerHTML = articleContent; } @@ -97,6 +135,62 @@ function toggleHighlighting() { isHighlight = true; highLight(); } + localStorage.setItem('highlightChecked', isHighlight); +} + +function showWordMeaning(event) { + const word = event.target.innerText.trim().replace(/[.,\/#!$%\^&\*;:{}=\-_`~()]/g, "").toLowerCase(); + const apiUrl = '/translate'; + const rect = event.target.getBoundingClientRect(); + const tooltipX = rect.left + window.scrollX; + const tooltipY = rect.top + window.scrollY + rect.height; + // 发送POST请求 + fetch(apiUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ word: word }), // 发送的JSON数据 + }) + .then(response => { + if (!response.ok) { + throw new Error('Network response was not ok'); + } + return response.json(); // 解析JSON响应 + }) + .then(data => { + // 假设data.translation是翻译结果 + const tooltip = document.getElementById('tooltip'); + if (!tooltip) { + console.error('Tooltip element not found'); + return; + } + + tooltip.textContent = data.translation || '没有找到该单词的中文意思'; + tooltip.style.left = `${tooltipX}px`; + tooltip.style.top = `${tooltipY}px`; + tooltip.style.display = 'block'; + tooltip.style.position = 'absolute'; + tooltip.style.background = 'yellow'; + + // 可以在这里添加点击事件监听器来隐藏tooltip,但注意避免内存泄漏 + document.addEventListener('click', function handler(e) { + if (!tooltip.contains(e.target)) { + tooltip.style.display = 'none'; + document.removeEventListener('click', handler); + } + }); + }) + .catch(error => { + console.error('There was a problem with your fetch operation:', error); + }); +} + +function addClickEventToHighlightedWords() { + const highlightedWords = document.querySelectorAll('.highlighted'); + highlightedWords.forEach(word => { + word.addEventListener('click', showWordMeaning); + }); } showBtnHandler(); diff --git a/app/static/js/jquery-1.12.1.min.js b/app/static/js/jquery-1.12.1.min.js new file mode 100644 index 0000000..a5195a3 --- /dev/null +++ b/app/static/js/jquery-1.12.1.min.js @@ -0,0 +1,5 @@ +/*! jQuery v1.12.1 | (c) jQuery Foundation | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="1.12.1",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(!l.ownFirst)for(b in a)return k.call(a,b);for(b in a);return void 0===b||k.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(h)return h.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=e.call(arguments,2),d=function(){return a.apply(b||this,c.concat(e.call(arguments)))},d.guid=a.guid=a.guid||n.guid++,d):void 0},now:function(){return+new Date},support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(P," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}if(f=d.getElementById(e[2]),f&&f.parentNode){if(f.id!==e[2])return A.find(a);this.length=1,this[0]=f}return this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||(e=n.uniqueSort(e)),D.test(a)&&(e=e.reverse())),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=!0,c||j.disable(),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.addEventListener?(d.removeEventListener("DOMContentLoaded",K),a.removeEventListener("load",K)):(d.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(d.addEventListener||"load"===a.event.type||"complete"===d.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll)a.setTimeout(n.ready);else if(d.addEventListener)d.addEventListener("DOMContentLoaded",K),a.addEventListener("load",K);else{d.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&d.documentElement}catch(e){}c&&c.doScroll&&!function f(){if(!n.isReady){try{c.doScroll("left")}catch(b){return a.setTimeout(f,50)}J(),n.ready()}}()}return I.promise(b)},n.ready.promise();var L;for(L in n(l))break;l.ownFirst="0"===L,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c,e;c=d.getElementsByTagName("body")[0],c&&c.style&&(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",l.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(e))}),function(){var a=d.createElement("div");l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}a=null}();var M=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b},N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0; +}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(M(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f}}function S(a,b,c){if(M(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=void 0)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},Z=/^(?:checkbox|radio)$/i,$=/<([\w:-]+)/,_=/^$|\/(?:java|ecma)script/i,aa=/^\s+/,ba="abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video";function ca(a){var b=ba.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}!function(){var a=d.createElement("div"),b=d.createDocumentFragment(),c=d.createElement("input");a.innerHTML="
a",l.leadingWhitespace=3===a.firstChild.nodeType,l.tbody=!a.getElementsByTagName("tbody").length,l.htmlSerialize=!!a.getElementsByTagName("link").length,l.html5Clone="<:nav>"!==d.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,b.appendChild(c),l.appendChecked=c.checked,a.innerHTML="",l.noCloneChecked=!!a.cloneNode(!0).lastChild.defaultValue,b.appendChild(a),c=d.createElement("input"),c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),a.appendChild(c),l.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!!a.addEventListener,a[n.expando]=1,l.attributes=!a.getAttribute(n.expando)}();var da={option:[1,""],legend:[1,"
","
"],area:[1,"",""],param:[1,"",""],thead:[1,"","
"],tr:[2,"","
"],col:[2,"","
"],td:[3,"","
"],_default:l.htmlSerialize?[0,"",""]:[1,"X
","
"]};da.optgroup=da.option,da.tbody=da.tfoot=da.colgroup=da.caption=da.thead,da.th=da.td;function ea(a,b){var c,d,e=0,f="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,ea(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function fa(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}var ga=/<|&#?\w+;/,ha=/r;r++)if(g=a[r],g||0===g)if("object"===n.type(g))n.merge(q,g.nodeType?[g]:g);else if(ga.test(g)){i=i||p.appendChild(b.createElement("div")),j=($.exec(g)||["",""])[1].toLowerCase(),m=da[j]||da._default,i.innerHTML=m[1]+n.htmlPrefilter(g)+m[2],f=m[0];while(f--)i=i.lastChild;if(!l.leadingWhitespace&&aa.test(g)&&q.push(b.createTextNode(aa.exec(g)[0])),!l.tbody){g="table"!==j||ha.test(g)?""!==m[1]||ha.test(g)?0:i:i.firstChild,f=g&&g.childNodes.length;while(f--)n.nodeName(k=g.childNodes[f],"tbody")&&!k.childNodes.length&&g.removeChild(k)}n.merge(q,i.childNodes),i.textContent="";while(i.firstChild)i.removeChild(i.firstChild);i=p.lastChild}else q.push(b.createTextNode(g));i&&p.removeChild(i),l.appendChecked||n.grep(ea(q,"input"),ia),r=0;while(g=q[r++])if(d&&n.inArray(g,d)>-1)e&&e.push(g);else if(h=n.contains(g.ownerDocument,g),i=ea(p.appendChild(g),"script"),h&&fa(i),c){f=0;while(g=i[f++])_.test(g.type||"")&&c.push(g)}return i=null,p}!function(){var b,c,e=d.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b]=c in a)||(e.setAttribute(c,"t"),l[b]=e.attributes[c].expando===!1);e=null}();var ka=/^(?:input|select|textarea)$/i,la=/^key/,ma=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,na=/^(?:focusinfocus|focusoutblur)$/,oa=/^([^.]*)(?:\.(.+)|)/;function pa(){return!0}function qa(){return!1}function ra(){try{return d.activeElement}catch(a){}}function sa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)sa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=qa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return"undefined"==typeof n||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(G)||[""],h=b.length;while(h--)f=oa.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=oa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,e,f){var g,h,i,j,l,m,o,p=[e||d],q=k.call(b,"type")?b.type:b,r=k.call(b,"namespace")?b.namespace.split("."):[];if(i=m=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!na.test(q+n.event.triggered)&&(q.indexOf(".")>-1&&(r=q.split("."),q=r.shift(),r.sort()),h=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=r.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:n.makeArray(c,[b]),l=n.event.special[q]||{},f||!l.trigger||l.trigger.apply(e,c)!==!1)){if(!f&&!l.noBubble&&!n.isWindow(e)){for(j=l.delegateType||q,na.test(j+q)||(i=i.parentNode);i;i=i.parentNode)p.push(i),m=i;m===(e.ownerDocument||d)&&p.push(m.defaultView||m.parentWindow||a)}o=0;while((i=p[o++])&&!b.isPropagationStopped())b.type=o>1?j:l.bindType||q,g=(n._data(i,"events")||{})[b.type]&&n._data(i,"handle"),g&&g.apply(i,c),g=h&&i[h],g&&g.apply&&M(i)&&(b.result=g.apply(i,c),b.result===!1&&b.preventDefault());if(b.type=q,!f&&!b.isDefaultPrevented()&&(!l._default||l._default.apply(p.pop(),c)===!1)&&M(e)&&h&&e[q]&&!n.isWindow(e)){m=e[h],m&&(e[h]=null),n.event.triggered=q;try{e[q]()}catch(s){}n.event.triggered=void 0,m&&(e[h]=m)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.rnamespace||a.rnamespace.test(g.namespace))&&(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]","i"),va=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,wa=/\s*$/g,Aa=ca(d),Ba=Aa.appendChild(d.createElement("div"));function Ca(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function Da(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function Ea(a){var b=ya.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Fa(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Ga(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(Da(b).text=a.text,Ea(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&Z.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}function Ha(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&xa.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(o&&(k=ja(b,a[0].ownerDocument,!1,a,d),e=k.firstChild,1===k.childNodes.length&&(k=e),e||d)){for(i=n.map(ea(k,"script"),Da),h=i.length;o>m;m++)g=k,m!==p&&(g=n.clone(g,!0,!0),h&&n.merge(i,ea(g,"script"))),c.call(a[m],g,m);if(h)for(j=i[i.length-1].ownerDocument,n.map(i,Ea),m=0;h>m;m++)g=i[m],_.test(g.type||"")&&!n._data(g,"globalEval")&&n.contains(j,g)&&(g.src?n._evalUrl&&n._evalUrl(g.src):n.globalEval((g.text||g.textContent||g.innerHTML||"").replace(za,"")));k=e=null}return a}function Ia(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(ea(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&fa(ea(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(va,"<$1>")},clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!ua.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(Ba.innerHTML=a.outerHTML,Ba.removeChild(f=Ba.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=ea(f),h=ea(a),g=0;null!=(e=h[g]);++g)d[g]&&Ga(e,d[g]);if(b)if(c)for(h=h||ea(a),d=d||ea(f),g=0;null!=(e=h[g]);g++)Fa(e,d[g]);else Fa(a,f);return d=ea(f,"script"),d.length>0&&fa(d,!i&&ea(a,"script")),d=h=e=null,f},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.attributes,m=n.event.special;null!=(d=a[h]);h++)if((b||M(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k||"undefined"==typeof d.removeAttribute?d[i]=void 0:d.removeAttribute(i),c.push(f))}}}),n.fn.extend({domManip:Ha,detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return Y(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||d).createTextNode(a))},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(ea(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return Y(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(ta,""):void 0;if("string"==typeof a&&!wa.test(a)&&(l.htmlSerialize||!ua.test(a))&&(l.leadingWhitespace||!aa.test(a))&&!da[($.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ea(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(ea(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],f=n(a),h=f.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(f[d])[b](c),g.apply(e,c.get());return this.pushStack(e)}});var Ja,Ka={HTML:"block",BODY:"block"};function La(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function Ma(a){var b=d,c=Ka[a];return c||(c=La(a,b),"none"!==c&&c||(Ja=(Ja||n("