');
+ for (const job of this._task.jobs) {
+ const link = `${baseURL}?id=${job.id}`;
+ jobsContainer.append($(` | ${link} |
`));
}
this._UI.append($(`
@@ -304,6 +296,7 @@ class DashboardView {
this._maxUploadCount = metaData.max_upload_count;
this._baseURL = metaData.base_url;
this._sharePath = metaData.share_path;
+ this._params = {};
this._setupList();
this._setupTaskSearch();
@@ -313,114 +306,105 @@ class DashboardView {
_setupList() {
const dashboardList = $('#dashboardList');
const dashboardPagination = $('#dashboardPagination');
-
const baseURL = this._baseURL;
- let overlay = null;
- dashboardPagination.pagination({
- dataSource: `/api/v1/tasks${window.location.search}`,
- locator: 'results',
- alias: {
- pageNumber: 'page',
- },
- totalNumberLocator: function(response) {
- return response.count;
- },
- ajax: {
- beforeSend() {
- overlay = showOverlay('Loading..');
- },
- },
- callback: function(pageList) {
- if (overlay) {
+
+ const defaults = {
+ totalPages: 1,
+ visiblePages: 7,
+ onPageClick: async (_, page) => {
+ dashboardPagination.css({
+ visibility: 'hidden',
+ });
+
+ const overlay = showOverlay('Loading..');
+ dashboardList.empty();
+
+ let tasks = null;
+ try {
+ tasks = await window.cvat.tasks.get(Object.assign({}, {
+ page,
+ }, this._params));
+ } catch (exception) {
+ let { message } = exception;
+ if (exception instanceof window.cvat.exceptions.ServerError) {
+ message += ` Code: ${exception.code}`;
+ }
+ showMessage(message);
+ return;
+ } finally {
overlay.remove();
- overlay = null;
}
- dashboardList.empty();
- for (let details of pageList) {
- const detailsCopy = JSON.parse(JSON.stringify(details));
- const taskView = new TaskView(detailsCopy, () => {
- // on delete task callback
- details.removed = true
- }, () => {
- // on update task callback
- $.get(`/api/v1/tasks/${details.id}`).done((taskData) => {
- Object.assign(details, taskData);
- taskView.init(details);
- }).fail((errorData) => {
- const message = `Can not get task from server. Showed info may be obsolete. Code: ${errorData.status}. ` +
- `Message: ${errorData.responseText || errorData.statusText}`;
- showMessage(message);
- })
- });
+
+ let startPage = dashboardPagination.twbsPagination('getCurrentPage');
+ if (!Number.isInteger(startPage)) {
+ startPage = 1;
+ }
+
+ dashboardPagination.twbsPagination('destroy');
+ dashboardPagination.twbsPagination(Object.assign({}, defaults, {
+ totalPages: Math.max(1, Math.ceil(tasks.count / 10)),
+ startPage,
+ initiateStartPageClick: false,
+ }));
+
+ for (const task of tasks) {
+ const taskView = new TaskView(task);
dashboardList.append(taskView.render(baseURL));
}
+ dashboardPagination.css({
+ 'margin-left': (window.screen.width - dashboardPagination.width()) / 2,
+ visibility: 'visible',
+ });
+
window.dispatchEvent(new CustomEvent('dashboardReady', {
- detail: JSON.parse(JSON.stringify(pageList))
+ detail: tasks,
}));
+ },
+ };
- const pages = $('.paginationjs-pages');
- pages.css('margin-left', (window.screen.width - pages.width()) / 2);
- }
- });
+ dashboardPagination.twbsPagination(defaults);
}
_setupTaskSearch() {
+ const dashboardPagination = $('#dashboardPagination');
const searchInput = $('#dashboardSearchInput');
const searchSubmit = $('#dashboardSearchSubmit');
searchInput.on('keypress', (e) => {
- if (e.keyCode != 13) {
+ if (e.keyCode !== 13) {
return;
}
- const params = {};
+ this._params = {};
const search = e.target.value.replace(/\s+/g, ' ').replace(/\s*:+\s*/g, ':').trim();
- for (let field of ['name', 'mode', 'owner', 'assignee', 'status', 'id']) {
- for (let param of search.split(' and ')) {
+ for (const field of ['name', 'mode', 'owner', 'assignee', 'status', 'id']) {
+ for (let param of search.split(/[\s]+and[\s]+|[\s]+AND[\s]+/)) {
if (param.includes(':')) {
param = param.split(':');
if (param[0] === field && param[1]) {
- params[field] = param[1];
+ [, this._params[field]] = param;
}
}
}
}
- if (!Object.keys(params).length && search.length) {
- params['search'] = search;
+ if ('id' in this._params) {
+ this._params.id = +this._params.id;
}
- if (Object.keys(params).length) {
- const searchParams = new URLSearchParams();
- for (let key in params) {
- searchParams.set(key, params[key]);
- }
- window.location.search = searchParams.toString();
- } else {
- window.location.search = '';
+ if (!Object.keys(this._params).length) {
+ this._params.search = search;
}
+
+ dashboardPagination.twbsPagination('show', 1);
});
- searchSubmit.on('click', function() {
- let e = $.Event('keypress');
+ searchSubmit.on('click', () => {
+ const e = $.Event('keypress');
e.keyCode = 13;
searchInput.trigger(e);
});
-
- const searchParams = new URLSearchParams(window.location.search.substring(1));
- if (searchParams.get('all')) {
- searchInput.prop('value', searchParams.get('all'));
- } else {
- let search = '';
- for (let field of ['name', 'mode', 'owner', 'assignee', 'status']) {
- const fieldVal = searchParams.get(field);
- if (fieldVal) {
- search += `${field}: ${fieldVal} and `;
- }
- }
- searchInput.prop('value', search.slice(0, -5));
- }
}
_setupCreateDialog() {
@@ -544,13 +528,61 @@ class DashboardView {
let frameFilter = '';
let files = [];
+ function updateSelectedFiles() {
+ switch (files.length) {
+ case 0:
+ filesLabel.text('No Files');
+ break;
+ case 1:
+ filesLabel.text(typeof (files[0]) === 'string' ? files[0] : files[0].name);
+ break;
+ default:
+ filesLabel.text(`${files.length} files`);
+ }
+ }
+
+
+ function validateName() {
+ const math = name.match('[a-zA-Z0-9_]+');
+ return math !== null;
+ }
+
+ function validateLabels() {
+ try {
+ const result = LabelsInfo.deserialize(labels);
+ return result.length;
+ } catch (error) {
+ return false;
+ }
+ }
+
+ function validateBugTracker() {
+ return !bugTrackerLink || !!bugTrackerLink.match(/^http[s]?/);
+ }
+
+ function validateSegmentSize() {
+ return (segmentSize >= 100 && segmentSize <= 50000);
+ }
+
+ function validateOverlapSize() {
+ return (overlapSize >= 0 && overlapSize <= segmentSize - 1);
+ }
+
dashboardCreateTaskButton.on('click', () => {
$('#dashboardCreateModal').removeClass('hidden');
});
- nameInput.on('change', (e) => name = e.target.value);
- bugTrackerInput.on('change', (e) => bugTrackerLink = e.target.value.trim());
- labelsInput.on('change', (e) => labels = e.target.value);
+ nameInput.on('change', (e) => {
+ name = e.target.value;
+ });
+
+ bugTrackerInput.on('change', (e) => {
+ bugTrackerLink = e.target.value.trim();
+ });
+
+ labelsInput.on('change', (e) => {
+ labels = e.target.value;
+ });
localSourceRadio.on('click', () => {
if (source === 'local') {
@@ -573,46 +605,44 @@ class DashboardView {
selectFiles.on('click', () => {
if (source === 'local') {
localFileSelector.click();
- }
- else {
+ } else {
shareBrowseTree.jstree('refresh');
shareFileSelector.removeClass('hidden');
shareBrowseTree.jstree({
core: {
- data: async function (obj, callback) {
- let url = '/api/v1/server/share';
+ async data(obj, callback) {
+ const directory = obj.id === '#' ? '' : `${obj.id}/`;
- if (obj.id != '#') {
- url += `?directory=${obj.id.substr(2)}`;
- }
-
- const response = await $.get(url);
- const files = Array.from(response, (element) => {
- return {
- id: `${obj.id}/${element.name}`,
+ let shareFiles = await window.cvat.server.share(directory);
+ shareFiles = Array.from(shareFiles, (element) => {
+ const shareFileInfo = {
+ id: `${directory}${element.name}`,
children: element.type === 'DIR',
text: element.name,
icon: element.type === 'DIR' ? 'jstree-folder' : 'jstree-file',
- }
+ };
+
+ return shareFileInfo;
});
- callback.call(this, files);
- }
+ callback.call(this, shareFiles);
+ },
},
plugins: ['checkbox', 'sort'],
});
}
});
- localFileSelector.on('change', function(e) {
- files = e.target.files;
+ localFileSelector.on('change', (e) => {
+ const localFiles = e.target.files;
+ files = localFiles;
updateSelectedFiles();
});
cancelBrowseServer.on('click', () => shareFileSelector.addClass('hidden'));
submitBrowseServer.on('click', () => {
if (!createModal.hasClass('hidden')) {
- files = Array.from(shareBrowseTree.jstree(true).get_selected(), (el) => el.substr(2));
+ files = Array.from(shareBrowseTree.jstree(true).get_selected());
cancelBrowseServer.click();
updateSelectedFiles();
}
@@ -633,7 +663,7 @@ class DashboardView {
const value = Math.clamp(
+segmentSizeInput.prop('value'),
+segmentSizeInput.prop('min'),
- +segmentSizeInput.prop('max')
+ +segmentSizeInput.prop('max'),
);
segmentSizeInput.prop('value', value);
@@ -644,7 +674,7 @@ class DashboardView {
const value = Math.clamp(
+overlapSizeInput.prop('value'),
+overlapSizeInput.prop('min'),
- +overlapSizeInput.prop('max')
+ +overlapSizeInput.prop('max'),
);
overlapSizeInput.prop('value', value);
@@ -655,7 +685,7 @@ class DashboardView {
const value = Math.clamp(
+imageQualityInput.prop('value'),
+imageQualityInput.prop('min'),
- +imageQualityInput.prop('max')
+ +imageQualityInput.prop('max'),
);
imageQualityInput.prop('value', value);
@@ -684,32 +714,32 @@ class DashboardView {
frameFilter = frameFilterInput.prop('value');
});
- submitCreate.on('click', () => {
+ submitCreate.on('click', async () => {
if (!validateName(name)) {
taskMessage.css('color', 'red');
taskMessage.text('Bad task name');
return;
}
- if (!validateLabels(labels)) {
+ if (!validateLabels()) {
taskMessage.css('color', 'red');
taskMessage.text('Bad labels specification');
return;
}
- if (!validateSegmentSize(segmentSize)) {
+ if (!validateSegmentSize()) {
taskMessage.css('color', 'red');
taskMessage.text('Segment size out of range');
return;
}
- if (!validateBugTracker(bugTrackerLink)) {
+ if (!validateBugTracker()) {
taskMessage.css('color', 'red');
taskMessage.text('Bad bag tracker link');
return;
}
- if (!validateOverlapSize(overlapSize, segmentSize)) {
+ if (!validateOverlapSize()) {
taskMessage.css('color', 'red');
taskMessage.text('Overlap size must be positive and not more then segment size');
return;
@@ -726,16 +756,20 @@ class DashboardView {
taskMessage.text('No files specified for the task');
return;
}
- else if (files.length > window.maxUploadCount && source === 'local') {
+
+ if (files.length > window.maxUploadCount && source === 'local') {
taskMessage.css('color', 'red');
taskMessage.text('Too many files were specified. Please use share to upload');
return;
}
- else if (source === 'local') {
+
+ if (source === 'local') {
let commonSize = 0;
- for (let file of files) {
+
+ for (const file of files) {
commonSize += file.size;
}
+
if (commonSize > window.maxUploadSize) {
taskMessage.css('color', 'red');
taskMessage.text('Too big files size. Please use share to upload');
@@ -744,20 +778,17 @@ class DashboardView {
}
const description = {
- name: name,
+ name,
labels: LabelsInfo.deserialize(labels),
- image_quality: compressQuality
- }
+ image_quality: compressQuality,
+ z_order: zOrder,
+ bug_tracker: bugTrackerLink,
+ };
- if (bugTrackerLink) {
- description.bug_tracker = bugTrackerLink;
- }
- if (zOrder) {
- description.z_order = zOrder;
- }
if (customSegmentSize.prop('checked')) {
description.segment_size = segmentSize;
}
+
if (customOverlapSize.prop('checked')) {
description.overlap = overlapSize;
}
@@ -771,103 +802,39 @@ class DashboardView {
description.frame_filter = frameFilter;
}
- function cleanupTask(tid) {
- $.ajax({
- url: `/api/v1/tasks/${tid}`,
- type: 'DELETE'
- });
- }
-
- submitCreate.prop('disabled', true);
- $.ajax({
- url: '/api/v1/tasks',
- type: 'POST',
- data: JSON.stringify(description),
- contentType: 'application/json'
- }).done((taskData) => {
- taskMessage.css('color', 'green');
- taskMessage.text('Task has been created. Uploading the data..');
-
- const batchOfFiles = new FormData();
- for (let j = 0; j < files.length; j++) {
- if (source === "local") {
- batchOfFiles.append(`client_files[${j}]`, files[j]);
- } else {
- batchOfFiles.append(`server_files[${j}]`, files[j]);
- }
+ try {
+ let task = new window.cvat.classes.Task(description);
+ if (source === 'local') {
+ task.clientFiles = Array.from(files);
+ } else {
+ task.serverFiles = Array.from(files);
}
-
- $.ajax({
- url: `/api/v1/tasks/${taskData.id}/data`,
- type: 'POST',
- data: batchOfFiles,
- contentType: false,
- processData: false
- }).done(() => {
- taskMessage.text('The data has been sent. Task is being created..');
-
- requestCreatingStatus(taskData.id, (status) => {
- taskMessage.css('color', 'blue');
- taskMessage.text(status);
- }, () => {
- const decorators = DashboardView.decorators('createTask');
- let idx = 0;
-
- function next() {
- const decorator = decorators[idx++];
- if (decorator) {
- decorator(taskData, next, () => {
- submitCreate.prop('disabled', false);
- cleanupTask(tid);
- });
- } else {
- window.location.reload();
- }
- }
-
- next();
- }, (errorMessage) => {
- submitCreate.prop('disabled', false);
- taskMessage.css('color', 'red');
- taskMessage.text(errorMessage);
- cleanupTask(taskData.id);
- });
- }).fail((errorData) => {
- const message = `Can not put the data for the task. Code: ${errorData.status}. ` +
- `Message: ${errorData.responseText || errorData.statusText}`;
- taskMessage.css('color', 'red');
+ submitCreate.attr('disabled', true);
+ cancelCreate.attr('disabled', true);
+ task = await task.save((message) => {
+ taskMessage.css('color', 'green');
taskMessage.text(message);
- submitCreate.prop('disabled', false);
- cleanupTask(taskData.id);
});
- }).fail((errorData) => {
- const message = `Task has not been created. Code: ${errorData.status}. ` +
- `Message: ${errorData.responseText || errorData.statusText}`;
+ window.location.reload();
+ } catch (exception) {
+ let { message } = exception;
+ if (exception instanceof window.cvat.exceptions.ServerError) {
+ message += ` Code: ${exception.code}`;
+ }
taskMessage.css('color', 'red');
taskMessage.text(message);
- submitCreate.prop('disabled', false);
- cleanupTask(taskData.id);
- });
+ submitCreate.attr('disabled', false);
+ cancelCreate.attr('disabled', false);
+ }
});
cancelCreate.on('click', () => createModal.addClass('hidden'));
}
}
-DashboardView.decorators = (action) => {
- DashboardView._decorators = DashboardView._decorators || {};
- return DashboardView._decorators[action] || [];
-}
-
-DashboardView.registerDecorator = (action, decorator) => {
- DashboardView._decorators = DashboardView._decorators || {};
- DashboardView._decorators[action] = DashboardView._decorators[action] || [];
- DashboardView._decorators[action].push(decorator);
-}
-
-
// DASHBOARD ENTRYPOINT
window.addEventListener('DOMContentLoaded', () => {
+ window.cvat.config.backendAPI = `${window.location.origin}/api/v1`;
$.when(
// TODO: Use REST API in order to get meta
$.get('/dashboard/meta'),
@@ -875,16 +842,15 @@ window.addEventListener('DOMContentLoaded', () => {
).then((metaData, taskData) => {
try {
new DashboardView(metaData[0], taskData[0]);
- }
- catch(exception) {
+ } catch (exception) {
$('#content').empty();
const message = `Can not build CVAT dashboard. Exception: ${exception}.`;
showMessage(message);
}
}).fail((errorData) => {
$('#content').empty();
- const message = `Can not build CVAT dashboard. Code: ${errorData.status}. ` +
- `Message: ${errorData.responseText || errorData.statusText}`;
+ const message = `Can not build CVAT dashboard. Code: ${errorData.status}. `
+ + `Message: ${errorData.responseText || errorData.statusText}`;
showMessage(message);
}).always(() => {
$('#loadingOverlay').remove();
diff --git a/cvat/apps/dashboard/templates/dashboard/dashboard.html b/cvat/apps/dashboard/templates/dashboard/dashboard.html
index 7722dc74..1fa55ea5 100644
--- a/cvat/apps/dashboard/templates/dashboard/dashboard.html
+++ b/cvat/apps/dashboard/templates/dashboard/dashboard.html
@@ -16,7 +16,7 @@
{{ block.super }}
-
+
{% for css_file in css_3rdparty %}
{% endfor %}
@@ -25,7 +25,7 @@
{% block head_js_3rdparty %}
{{ block.super }}
-
+
{% for js_file in js_3rdparty %}
{% endfor %}
@@ -33,6 +33,7 @@
{% block head_js_cvat %}
{{ block.super }}
+
@@ -57,9 +58,8 @@
-
+
+
diff --git a/cvat/apps/engine/admin.py b/cvat/apps/engine/admin.py
index 55786f89..a7b11099 100644
--- a/cvat/apps/engine/admin.py
+++ b/cvat/apps/engine/admin.py
@@ -56,7 +56,7 @@ class SegmentAdmin(admin.ModelAdmin):
class TaskAdmin(admin.ModelAdmin):
date_hierarchy = 'updated_date'
- readonly_fields = ('size', 'created_date', 'updated_date', 'overlap', 'flipped')
+ readonly_fields = ('size', 'created_date', 'updated_date', 'overlap')
list_display = ('name', 'mode', 'owner', 'assignee', 'created_date', 'updated_date')
search_fields = ('name', 'mode', 'owner__username', 'owner__first_name',
'owner__last_name', 'owner__email', 'assignee__username', 'assignee__first_name',
diff --git a/cvat/apps/engine/annotation.py b/cvat/apps/engine/annotation.py
index d0fb0211..68a62c50 100644
--- a/cvat/apps/engine/annotation.py
+++ b/cvat/apps/engine/annotation.py
@@ -1227,13 +1227,6 @@ class TaskAnnotation:
overlap = self.db_task.overlap
self._merge_data(annotation.data, start_frame, overlap)
- @staticmethod
- def _flip_shape(shape, im_w, im_h):
- for x in range(0, len(shape["points"]), 2):
- y = x + 1
- shape["points"][x] = im_w - shape["points"][x]
- shape["points"][y] = im_w - shape["points"][y]
-
def dump(self, file_path, scheme, host, query_params):
db_task = self.db_task
db_segments = db_task.segment_set.all().prefetch_related('job_set')
@@ -1252,7 +1245,6 @@ class TaskAnnotation:
("mode", db_task.mode),
("overlap", str(db_task.overlap)),
("bugtracker", db_task.bug_tracker),
- ("flipped", str(db_task.flipped)),
("created", str(timezone.localtime(db_task.created_date))),
("updated", str(timezone.localtime(db_task.updated_date))),
("start_frame", str(db_task.start_frame)),
@@ -1332,9 +1324,6 @@ class TaskAnnotation:
]))
for shape in shapes.get(frame, []):
- if db_task.flipped:
- self._flip_shape(shape, im_w, im_h)
-
db_label = db_label_by_id[shape["label_id"]]
dump_data = OrderedDict([
@@ -1415,8 +1404,6 @@ class TaskAnnotation:
dumper.open_track(dump_data)
for shape in TrackManager.get_interpolated_shapes(
track, 0, db_task.size):
- if db_task.flipped:
- self._flip_shape(shape, im_w, im_h)
dump_data = OrderedDict([
("frame", str(db_task.start_frame + shape["frame"] * db_task.get_frame_step())),
diff --git a/cvat/apps/engine/migrations/0020_remove_task_flipped.py b/cvat/apps/engine/migrations/0020_remove_task_flipped.py
new file mode 100644
index 00000000..1c09cea2
--- /dev/null
+++ b/cvat/apps/engine/migrations/0020_remove_task_flipped.py
@@ -0,0 +1,125 @@
+# Generated by Django 2.1.7 on 2019-06-18 11:08
+
+from django.db import migrations
+from django.conf import settings
+
+from cvat.apps.engine.task import get_image_meta_cache
+from cvat.apps.engine.models import Job, ShapeType
+
+from PIL import Image
+
+import os
+
+
+def _flip_shape(shape, size):
+ if shape.type == ShapeType.RECTANGLE:
+ shape.points = [
+ shape.points[2], # xbr -> xtl
+ shape.points[3], # ybr -> ytl
+ shape.points[0], # xtl -> xbr
+ shape.points[1] # ytl -> ybr
+ ]
+
+ for x in range(0, len(shape.points), 2):
+ y = x + 1
+ shape.points[x] = size['width'] - shape.points[x]
+ shape.points[y] = size['height'] - shape.points[y]
+
+
+def frame_path(db_task, frame):
+ task_dirname = os.path.join(settings.DATA_ROOT, str(db_task.id))
+ d1 = str(int(frame) // 10000)
+ d2 = str(int(frame) // 100)
+ path = os.path.join(task_dirname, 'data', d1, d2, str(frame) + '.jpg')
+ return path
+
+
+def _get_image_meta_cache_path(self):
+ task_dirname = os.path.join(settings.DATA_ROOT, str(self.id))
+ return os.path.join(task_dirname, "image_meta.cache")
+
+
+def forwards_func(apps, schema_editor):
+ Task = apps.get_model('engine', 'Task')
+
+ # class methods unavailable in the class which got via get_model()
+ # nevertheless it is needed for us to use the function get_image_meta_cache()
+ setattr(Task, 'get_image_meta_cache_path', _get_image_meta_cache_path)
+
+ print('Getting flipped tasks...')
+ db_flipped_tasks = Task.objects.prefetch_related(
+ 'image_set',
+ ).filter(flipped=True).all()
+
+ print('Conversion started...')
+ for db_task in db_flipped_tasks:
+ print('Processing task {}...'.format(db_task.id))
+ db_image_by_frame = {}
+ if db_task.mode == 'annotation':
+ db_image_by_frame = {db_image.frame: {'width': db_image.width, 'height': db_image.height}
+ for db_image in db_task.image_set.all()}
+ else:
+ im_meta_data = get_image_meta_cache(db_task)['original_size']
+ db_image_by_frame = {
+ 0: {
+ 'width': im_meta_data[0]['width'],
+ 'height': im_meta_data[0]['height']
+ }
+ }
+
+
+ def get_size(frame):
+ if frame in db_image_by_frame:
+ return db_image_by_frame[frame]
+ else:
+ return db_image_by_frame[0]
+
+ db_jobs = Job.objects.select_related('segment').prefetch_related(
+ 'labeledshape_set',
+ 'labeledtrack_set',
+ 'labeledtrack_set__trackedshape_set').filter(segment__task_id=db_task.id).all()
+
+ for db_job in db_jobs:
+ db_shapes = db_job.labeledshape_set.all()
+ db_tracks = db_job.labeledtrack_set.all()
+ for db_shape in db_shapes:
+ _flip_shape(db_shape, get_size(db_shape.frame))
+ db_shape.save()
+
+ for db_track in db_tracks:
+ db_shapes = db_track.trackedshape_set.all()
+ for db_shape in db_shapes:
+ _flip_shape(db_shape, get_size(db_shape.frame))
+ db_shape.save()
+
+ for db_task in db_flipped_tasks:
+ for frame in range(db_task.size):
+ path = frame_path(db_task, frame)
+ if os.path.islink(path):
+ path = os.path.realpath(path)
+
+ try:
+ image = Image.open(path)
+ image = image.transpose(Image.ROTATE_180)
+ image.save(path)
+ except IOError as ex:
+ print('Error of handling the frame {}'.format(frame))
+ print(ex)
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engine', '0019_frame_selection'),
+ ]
+
+ operations = [
+ migrations.RunPython(
+ forwards_func
+ ),
+
+ migrations.RemoveField(
+ model_name='task',
+ name='flipped',
+ ),
+ ]
diff --git a/cvat/apps/engine/models.py b/cvat/apps/engine/models.py
index 6a410d92..8d45849e 100644
--- a/cvat/apps/engine/models.py
+++ b/cvat/apps/engine/models.py
@@ -48,7 +48,6 @@ class Task(models.Model):
# Zero means that there are no limits (default)
segment_size = models.PositiveIntegerField(default=0)
z_order = models.BooleanField(default=False)
- flipped = models.BooleanField(default=False)
image_quality = models.PositiveSmallIntegerField(default=50)
start_frame = models.PositiveIntegerField(default=0)
stop_frame = models.PositiveIntegerField(default=0)
diff --git a/cvat/apps/engine/serializers.py b/cvat/apps/engine/serializers.py
index 85103449..41b54fff 100644
--- a/cvat/apps/engine/serializers.py
+++ b/cvat/apps/engine/serializers.py
@@ -187,7 +187,7 @@ class TaskSerializer(WriteOnceMixin, serializers.ModelSerializer):
model = models.Task
fields = ('url', 'id', 'name', 'size', 'mode', 'owner', 'assignee',
'bug_tracker', 'created_date', 'updated_date', 'overlap',
- 'segment_size', 'z_order', 'flipped', 'status', 'labels', 'segments',
+ 'segment_size', 'z_order', 'status', 'labels', 'segments',
'image_quality', 'start_frame', 'stop_frame', 'frame_filter')
read_only_fields = ('size', 'mode', 'created_date', 'updated_date',
'status')
@@ -232,7 +232,6 @@ class TaskSerializer(WriteOnceMixin, serializers.ModelSerializer):
instance.bug_tracker = validated_data.get('bug_tracker',
instance.bug_tracker)
instance.z_order = validated_data.get('z_order', instance.z_order)
- instance.flipped = validated_data.get('flipped', instance.flipped)
instance.image_quality = validated_data.get('image_quality',
instance.image_quality)
instance.start_frame = validated_data.get('start_frame', instance.start_frame)
diff --git a/cvat/apps/engine/static/engine/js/annotationParser.js b/cvat/apps/engine/static/engine/js/annotationParser.js
index 447055c4..6ea4d340 100644
--- a/cvat/apps/engine/static/engine/js/annotationParser.js
+++ b/cvat/apps/engine/static/engine/js/annotationParser.js
@@ -16,7 +16,6 @@ class AnnotationParser {
this._parser = new DOMParser();
this._startFrame = job.start;
this._stopFrame = job.stop;
- this._flipped = job.flipped;
this._im_meta = job.image_meta_data;
this._labelsInfo = labelsInfo;
}
@@ -43,15 +42,6 @@ class AnnotationParser {
throw Error(message);
}
- if (this._flipped) {
- [xtl, ytl, xbr, ybr] = [
- imWidth - xbr,
- imWidth - xtl,
- imHeight - ybr,
- imHeight - ytl,
- ];
- }
-
const occluded = box.getAttribute('occluded');
const zOrder = box.getAttribute('z_order') || '0';
return [[xtl, ytl, xbr, ybr], +occluded, +zOrder];
@@ -70,11 +60,6 @@ class AnnotationParser {
+ `y=${point.y}. Point out of range ${imWidth}x${imHeight}`;
throw Error(message);
}
-
- if (this._flipped) {
- point.x = imWidth - point.x;
- point.y = imHeight - point.y;
- }
}
points = points.reduce((acc, el) => {
diff --git a/cvat/apps/engine/static/engine/js/annotationUI.js b/cvat/apps/engine/static/engine/js/annotationUI.js
index 1044fb25..ef3b96dd 100644
--- a/cvat/apps/engine/static/engine/js/annotationUI.js
+++ b/cvat/apps/engine/static/engine/js/annotationUI.js
@@ -371,7 +371,6 @@ function setupMenu(job, task, shapeCollectionModel,
$('#statFrames').text(`[${window.cvat.player.frames.start}-${window.cvat.player.frames.stop}]`);
$('#statOverlap').text(task.overlap);
$('#statZOrder').text(task.z_order);
- $('#statFlipped').text(task.flipped);
$('#statTaskStatus').prop('value', job.status).on('change', async (e) => {
try {
const jobCopy = JSON.parse(JSON.stringify(job));
diff --git a/cvat/apps/engine/static/engine/js/cvat.js b/cvat/apps/engine/static/engine/js/cvat.js
new file mode 100644
index 00000000..9f54af53
--- /dev/null
+++ b/cvat/apps/engine/static/engine/js/cvat.js
@@ -0,0 +1,22 @@
+!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=78)}([function(e,t){e.exports="object"==typeof window&&window&&window.Math==Math?window:"object"==typeof self&&self&&self.Math==Math?self:Function("return this")()},function(e,t,n){var r=n(23)("wks"),o=n(46),i=n(0).Symbol,a=n(85);e.exports=function(e){return r[e]||(r[e]=a&&i[e]||(a?i:o)("Symbol."+e))}},function(e,t,n){var r=n(6);e.exports=function(e){if(!r(e))throw TypeError(String(e)+" is not an object");return e}},function(e,t,n){"use strict";var r=n(69),o=n(114),i=Object.prototype.toString;function a(e){return"[object Array]"===i.call(e)}function s(e){return null!==e&&"object"==typeof e}function c(e){return"[object Function]"===i.call(e)}function u(e,t){if(null!=e)if("object"!=typeof e&&(e=[e]),a(e))for(var n=0,r=e.length;n=t.length?(e.target=void 0,{value:void 0,done:!0}):"keys"==n?{value:r,done:!1}:"values"==n?{value:t[r],done:!1}:{value:[r,t[r]],done:!1}},"values"),i.Arguments=i.Array,o("keys"),o("values"),o("entries")},function(e,t,n){"use strict";var r,o,i,a="Promise",s=n(17),c=n(0),u=n(11),l=n(6),f=n(26),p=n(38),d=n(13),h=n(84),v=n(87),g=n(88),b=n(53).set,m=n(89),w=n(90),y=n(91),x=n(56),S=n(92),O=n(55),j=n(1)("species"),k=n(15),E=n(50),A=k.get,T=k.set,P=k.getterFor(a),I=c.Promise,R=c.TypeError,C=c.document,L=c.process,N=c.fetch,$=L&&L.versions,_=$&&$.v8||"",M=x.f,F=M,U="process"==d(L),B=!!(C&&C.createEvent&&c.dispatchEvent),z=E(a,function(){var e=I.resolve(1),t=function(){},n=(e.constructor={})[j]=function(e){e(t,t)};return!((U||"function"==typeof PromiseRejectionEvent)&&(!s||e.finally)&&e.then(t)instanceof n&&0!==_.indexOf("6.6")&&-1===O.indexOf("Chrome/66"))}),D=z||!v(function(e){I.all(e).catch(function(){})}),W=function(e){var t;return!(!l(e)||"function"!=typeof(t=e.then))&&t},q=function(e,t,n){if(!t.notified){t.notified=!0;var r=t.reactions;m(function(){for(var o=t.value,i=1==t.state,a=0,s=function(n){var r,a,s,c=i?n.ok:n.fail,u=n.resolve,l=n.reject,f=n.domain;try{c?(i||(2===t.rejection&&X(e,t),t.rejection=1),!0===c?r=o:(f&&f.enter(),r=c(o),f&&(f.exit(),s=!0)),r===n.promise?l(R("Promise-chain cycle")):(a=W(r))?a.call(r,u,l):u(r)):l(o)}catch(e){f&&!s&&f.exit(),l(e)}};r.length>a;)s(r[a++]);t.reactions=[],t.notified=!1,n&&!t.rejection&&J(e,t)})}},G=function(e,t,n){var r,o;B?((r=C.createEvent("Event")).promise=t,r.reason=n,r.initEvent(e,!1,!0),c.dispatchEvent(r)):r={promise:t,reason:n},(o=c["on"+e])?o(r):"unhandledrejection"===e&&y("Unhandled promise rejection",n)},J=function(e,t){b.call(c,function(){var n,r=t.value;if(V(t)&&(n=S(function(){U?L.emit("unhandledRejection",r,e):G("unhandledrejection",e,r)}),t.rejection=U||V(t)?2:1,n.error))throw n.value})},V=function(e){return 1!==e.rejection&&!e.parent},X=function(e,t){b.call(c,function(){U?L.emit("rejectionHandled",e):G("rejectionhandled",e,t.value)})},K=function(e,t,n,r){return function(o){e(t,n,o,r)}},H=function(e,t,n,r){t.done||(t.done=!0,r&&(t=r),t.value=n,t.state=2,q(e,t,!0))},Y=function(e,t,n,r){if(!t.done){t.done=!0,r&&(t=r);try{if(e===n)throw R("Promise can't be resolved itself");var o=W(n);o?m(function(){var r={done:!1};try{o.call(n,K(Y,e,r,t),K(H,e,r,t))}catch(n){H(e,r,n,t)}}):(t.value=n,t.state=1,q(e,t,!1))}catch(n){H(e,{done:!1},n,t)}}};z&&(I=function(e){p(this,I,a),f(e),r.call(this);var t=A(this);try{e(K(Y,this,t),K(H,this,t))}catch(e){H(this,t,e)}},(r=function(e){T(this,{type:a,done:!1,notified:!1,parent:!1,reactions:[],rejection:!1,state:0,value:void 0})}).prototype=n(57)(I.prototype,{then:function(e,t){var n=P(this),r=M(g(this,I));return r.ok="function"!=typeof e||e,r.fail="function"==typeof t&&t,r.domain=U?L.domain:void 0,n.parent=!0,n.reactions.push(r),0!=n.state&&q(this,n,!1),r.promise},catch:function(e){return this.then(void 0,e)}}),o=function(){var e=new r,t=A(e);this.promise=e,this.resolve=K(Y,e,t),this.reject=K(H,e,t)},x.f=M=function(e){return e===I||e===i?new o(e):F(e)},s||"function"!=typeof N||u({global:!0,enumerable:!0,forced:!0},{fetch:function(e){return w(I,N.apply(c,arguments))}})),u({global:!0,wrap:!0,forced:z},{Promise:I}),n(20)(I,a,!1,!0),n(93)(a),i=n(58).Promise,u({target:a,stat:!0,forced:z},{reject:function(e){var t=M(this);return t.reject.call(void 0,e),t.promise}}),u({target:a,stat:!0,forced:s||z},{resolve:function(e){return w(s&&this===i?I:this,e)}}),u({target:a,stat:!0,forced:D},{all:function(e){var t=this,n=M(t),r=n.resolve,o=n.reject,i=S(function(){var n=[],i=0,a=1;h(e,function(e){var s=i++,c=!1;n.push(void 0),a++,t.resolve(e).then(function(e){c||(c=!0,n[s]=e,--a||r(n))},o)}),--a||r(n)});return i.error&&o(i.value),n.promise},race:function(e){var t=this,n=M(t),r=n.reject,o=S(function(){h(e,function(e){t.resolve(e).then(n.resolve,r)})});return o.error&&r(o.value),n.promise}})},function(e,t,n){var r=n(0),o=n(31).f,i=n(7),a=n(14),s=n(34),c=n(47),u=n(50);e.exports=function(e,t){var n,l,f,p,d,h=e.target,v=e.global,g=e.stat;if(n=v?r:g?r[h]||s(h,{}):(r[h]||{}).prototype)for(l in t){if(p=t[l],f=e.noTargetGet?(d=o(n,l))&&d.value:n[l],!u(v?l:h+(g?".":"#")+l,e.forced)&&void 0!==f){if(typeof p==typeof f)continue;c(p,f)}(e.sham||f&&f.sham)&&i(p,"sham",!0),a(n,l,p,e)}}},function(e,t,n){var r=n(8),o=n(44),i=n(2),a=n(32),s=Object.defineProperty;t.f=r?s:function(e,t,n){if(i(e),t=a(t,!0),i(n),o)try{return s(e,t,n)}catch(e){}if("get"in n||"set"in n)throw TypeError("Accessors not supported");return"value"in n&&(e[t]=n.value),e}},function(e,t){var n={}.toString;e.exports=function(e){return n.call(e).slice(8,-1)}},function(e,t,n){var r=n(0),o=n(7),i=n(4),a=n(34),s=n(45),c=n(15),u=c.get,l=c.enforce,f=String(s).split("toString");n(23)("inspectSource",function(e){return s.call(e)}),(e.exports=function(e,t,n,s){var c=!!s&&!!s.unsafe,u=!!s&&!!s.enumerable,p=!!s&&!!s.noTargetGet;"function"==typeof n&&("string"!=typeof t||i(n,"name")||o(n,"name",t),l(n).source=f.join("string"==typeof t?t:"")),e!==r?(c?!p&&e[t]&&(u=!0):delete e[t],u?e[t]=n:o(e,t,n)):u?e[t]=n:a(t,n)})(Function.prototype,"toString",function(){return"function"==typeof this&&u(this).source||s.call(this)})},function(e,t,n){var r,o,i,a=n(79),s=n(6),c=n(7),u=n(4),l=n(35),f=n(36),p=n(0).WeakMap;if(a){var d=new p,h=d.get,v=d.has,g=d.set;r=function(e,t){return g.call(d,e,t),t},o=function(e){return h.call(d,e)||{}},i=function(e){return v.call(d,e)}}else{var b=l("state");f[b]=!0,r=function(e,t){return c(e,b,t),t},o=function(e){return u(e,b)?e[b]:{}},i=function(e){return u(e,b)}}e.exports={set:r,get:o,has:i,enforce:function(e){return i(e)?o(e):r(e,{})},getterFor:function(e){return function(t){var n;if(!s(t)||(n=o(t)).type!==e)throw TypeError("Incompatible receiver, "+e+" required");return n}}}},function(e,t,n){var r=n(100),o=n(9),i=n(0),a=n(7),s=n(1),c=s("iterator"),u=s("toStringTag"),l=o.values;for(var f in r){var p=i[f],d=p&&p.prototype;if(d){if(d[c]!==l)try{a(d,c,l)}catch(e){d[c]=l}if(d[u]||a(d,u,f),r[f])for(var h in o)if(d[h]!==o[h])try{a(d,h,o[h])}catch(e){d[h]=o[h]}}}},function(e,t){e.exports=!1},function(e,t){e.exports=function(e){if(null==e)throw TypeError("Can't call method on "+e);return e}},function(e,t){e.exports={}},function(e,t,n){var r=n(12).f,o=n(4),i=n(1)("toStringTag");e.exports=function(e,t,n){e&&!o(e=n?e:e.prototype,i)&&r(e,i,{configurable:!0,value:t})}},function(e,t){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},function(e,t,n){var r=n(43),o=n(18);e.exports=function(e){return r(o(e))}},function(e,t,n){var r=n(0),o=n(34),i=r["__core-js_shared__"]||o("__core-js_shared__",{});(e.exports=function(e,t){return i[e]||(i[e]=void 0!==t?t:{})})("versions",[]).push({version:"3.0.1",mode:n(17)?"pure":"global",copyright:"© 2019 Denis Pushkarev (zloirock.ru)"})},function(e,t,n){var r=n(25),o=Math.min;e.exports=function(e){return e>0?o(r(e),9007199254740991):0}},function(e,t){var n=Math.ceil,r=Math.floor;e.exports=function(e){return isNaN(e=+e)?0:(e>0?r:n)(e)}},function(e,t){e.exports=function(e){if("function"!=typeof e)throw TypeError(String(e)+" is not a function");return e}},function(e,t,n){var r=n(26);e.exports=function(e,t,n){if(r(e),void 0===t)return e;switch(n){case 0:return function(){return e.call(t)};case 1:return function(n){return e.call(t,n)};case 2:return function(n,r){return e.call(t,n,r)};case 3:return function(n,r,o){return e.call(t,n,r,o)}}return function(){return e.apply(t,arguments)}}},function(e,t,n){var r=n(86),o=n(1)("iterator"),i=n(19);e.exports=function(e){if(null!=e)return e[o]||e["@@iterator"]||i[r(e)]}},function(e,t,n){n(95),n(9),n(10),n(16),(()=>{const{PluginError:t}=n(66),r=[];e.exports=class{static async apiWrapper(e,...n){const r=await window.cvat.plugins.list.implementation();for(const o of r){const r=o.functions.filter(t=>t.callback===e)[0];if(r&&r.enter)try{await r.enter.call(this,o,...n)}catch(e){throw e instanceof t?e:new t(`Exception in plugin ${o.name}: ${e.toString()}`)}}let o=await e.implementation.call(this,...n);for(const i of r){const r=i.functions.filter(t=>t.callback===e)[0];if(r&&r.leave)try{o=await r.leave.call(this,i,o,...n)}catch(e){throw e instanceof t?e:new t(`Exception in plugin ${i.name}: ${e.toString()}`)}}return o}static async register(e){const n=[];if("object"!=typeof e)throw new t(`Plugin should be an object, but got "${typeof e}"`);if(!("name"in e)||"string"!=typeof e.name)throw new t('Plugin must contain a "name" field and it must be a string');if(!("description"in e)||"string"!=typeof e.description)throw new t('Plugin must contain a "description" field and it must be a string');if("functions"in e)throw new t('Plugin must not contain a "functions" field');!function e(t,r){const o={};for(const n in t)Object.prototype.hasOwnProperty.call(t,n)&&("object"==typeof t[n]?Object.prototype.hasOwnProperty.call(r,n)&&e(t[n],r[n]):["enter","leave"].includes(n)&&"function"==typeof r&&(t[n],1)&&(o.callback=r,o[n]=t[n]));Object.keys(o).length&&n.push(o)}(e,{cvat:window.cvat}),Object.defineProperty(e,"functions",{value:n,writable:!1}),r.push(e)}static async list(){return r}}})()},function(e,t,n){var r=n(18);e.exports=function(e){return Object(r(e))}},function(e,t,n){var r=n(8),o=n(42),i=n(21),a=n(22),s=n(32),c=n(4),u=n(44),l=Object.getOwnPropertyDescriptor;t.f=r?l:function(e,t){if(e=a(e),t=s(t,!0),u)try{return l(e,t)}catch(e){}if(c(e,t))return i(!o.f.call(e,t),e[t])}},function(e,t,n){var r=n(6);e.exports=function(e,t){if(!r(e))return e;var n,o;if(t&&"function"==typeof(n=e.toString)&&!r(o=n.call(e)))return o;if("function"==typeof(n=e.valueOf)&&!r(o=n.call(e)))return o;if(!t&&"function"==typeof(n=e.toString)&&!r(o=n.call(e)))return o;throw TypeError("Can't convert object to primitive value")}},function(e,t,n){var r=n(6),o=n(0).document,i=r(o)&&r(o.createElement);e.exports=function(e){return i?o.createElement(e):{}}},function(e,t,n){var r=n(0),o=n(7);e.exports=function(e,t){try{o(r,e,t)}catch(n){r[e]=t}return t}},function(e,t,n){var r=n(23)("keys"),o=n(46);e.exports=function(e){return r[e]||(r[e]=o(e))}},function(e,t){e.exports={}},function(e,t){e.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},function(e,t){e.exports=function(e,t,n){if(!(e instanceof t))throw TypeError("Incorrect "+(n?n+" ":"")+"invocation");return e}},function(e,t){(()=>{const t={clientID:+Date.now().toString().substr(-6),projID:void 0,taskID:void 0,jobID:void 0,location:void 0};e.exports=t})()},function(e,t,n){var r=n(25),o=n(18);e.exports=function(e,t,n){var i,a,s=String(o(e)),c=r(t),u=s.length;return c<0||c>=u?n?"":void 0:(i=s.charCodeAt(c))<55296||i>56319||c+1===u||(a=s.charCodeAt(c+1))<56320||a>57343?n?s.charAt(c):i:n?s.slice(c,c+2):a-56320+(i-55296<<10)+65536}},function(e,t,n){"use strict";(function(t){var r=n(3),o=n(117),i={"Content-Type":"application/x-www-form-urlencoded"};function a(e,t){!r.isUndefined(e)&&r.isUndefined(e["Content-Type"])&&(e["Content-Type"]=t)}var s,c={adapter:("undefined"!=typeof XMLHttpRequest?s=n(70):void 0!==t&&(s=n(70)),s),transformRequest:[function(e,t){return o(t,"Content-Type"),r.isFormData(e)||r.isArrayBuffer(e)||r.isBuffer(e)||r.isStream(e)||r.isFile(e)||r.isBlob(e)?e:r.isArrayBufferView(e)?e.buffer:r.isURLSearchParams(e)?(a(t,"application/x-www-form-urlencoded;charset=utf-8"),e.toString()):r.isObject(e)?(a(t,"application/json;charset=utf-8"),JSON.stringify(e)):e}],transformResponse:[function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(e){}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,validateStatus:function(e){return e>=200&&e<300}};c.headers={common:{Accept:"application/json, text/plain, */*"}},r.forEach(["delete","get","head"],function(e){c.headers[e]={}}),r.forEach(["post","put","patch"],function(e){c.headers[e]=r.merge(i)}),e.exports=c}).call(this,n(116))},function(e,t,n){"use strict";var r={}.propertyIsEnumerable,o=Object.getOwnPropertyDescriptor,i=o&&!r.call({1:2},1);t.f=i?function(e){var t=o(this,e);return!!t&&t.enumerable}:r},function(e,t,n){var r=n(5),o=n(13),i="".split;e.exports=r(function(){return!Object("z").propertyIsEnumerable(0)})?function(e){return"String"==o(e)?i.call(e,""):Object(e)}:Object},function(e,t,n){e.exports=!n(8)&&!n(5)(function(){return 7!=Object.defineProperty(n(33)("div"),"a",{get:function(){return 7}}).a})},function(e,t,n){e.exports=n(23)("native-function-to-string",Function.toString)},function(e,t){var n=0,r=Math.random();e.exports=function(e){return"Symbol(".concat(void 0===e?"":e,")_",(++n+r).toString(36))}},function(e,t,n){var r=n(4),o=n(80),i=n(31),a=n(12);e.exports=function(e,t){for(var n=o(t),s=a.f,c=i.f,u=0;uc;)r(s,n=t[c++])&&(~i(u,n)||u.push(n));return u}},function(e,t){t.f=Object.getOwnPropertySymbols},function(e,t,n){var r=n(5),o=/#|\.prototype\./,i=function(e,t){var n=s[a(e)];return n==u||n!=c&&("function"==typeof t?r(t):!!t)},a=i.normalize=function(e){return String(e).replace(o,".").toLowerCase()},s=i.data={},c=i.NATIVE="N",u=i.POLYFILL="P";e.exports=i},function(e,t,n){var r=n(19),o=n(1)("iterator"),i=Array.prototype;e.exports=function(e){return void 0!==e&&(r.Array===e||i[o]===e)}},function(e,t,n){var r=n(2);e.exports=function(e,t,n,o){try{return o?t(r(n)[0],n[1]):t(n)}catch(t){var i=e.return;throw void 0!==i&&r(i.call(e)),t}}},function(e,t,n){var r,o,i,a=n(0),s=n(13),c=n(27),u=n(54),l=n(33),f=a.setImmediate,p=a.clearImmediate,d=a.process,h=a.MessageChannel,v=a.Dispatch,g=0,b={},m=function(){var e=+this;if(b.hasOwnProperty(e)){var t=b[e];delete b[e],t()}},w=function(e){m.call(e.data)};f&&p||(f=function(e){for(var t=[],n=1;arguments.length>n;)t.push(arguments[n++]);return b[++g]=function(){("function"==typeof e?e:Function(e)).apply(void 0,t)},r(g),g},p=function(e){delete b[e]},"process"==s(d)?r=function(e){d.nextTick(c(m,e,1))}:v&&v.now?r=function(e){v.now(c(m,e,1))}:h?(i=(o=new h).port2,o.port1.onmessage=w,r=c(i.postMessage,i,1)):a.addEventListener&&"function"==typeof postMessage&&!a.importScripts?(r=function(e){a.postMessage(e+"","*")},a.addEventListener("message",w,!1)):r="onreadystatechange"in l("script")?function(e){u.appendChild(l("script")).onreadystatechange=function(){u.removeChild(this),m.call(e)}}:function(e){setTimeout(c(m,e,1),0)}),e.exports={set:f,clear:p}},function(e,t,n){var r=n(0).document;e.exports=r&&r.documentElement},function(e,t,n){var r=n(0).navigator;e.exports=r&&r.userAgent||""},function(e,t,n){"use strict";var r=n(26),o=function(e){var t,n;this.promise=new e(function(e,r){if(void 0!==t||void 0!==n)throw TypeError("Bad Promise constructor");t=e,n=r}),this.resolve=r(t),this.reject=r(n)};e.exports.f=function(e){return new o(e)}},function(e,t,n){var r=n(14);e.exports=function(e,t,n){for(var o in t)r(e,o,t[o],n);return e}},function(e,t,n){e.exports=n(0)},function(e,t,n){var r=n(2),o=n(60),i=n(37),a=n(54),s=n(33),c=n(35)("IE_PROTO"),u=function(){},l=function(){var e,t=s("iframe"),n=i.length;for(t.style.display="none",a.appendChild(t),t.src=String("javascript:"),(e=t.contentWindow.document).open(),e.write("