diff --git a/docs-android/app/app.iml b/docs-android/app/app.iml index 0df93fa8..22f4bad8 100644 --- a/docs-android/app/app.iml +++ b/docs-android/app/app.iml @@ -89,11 +89,11 @@ - + @@ -108,18 +108,16 @@ - + - - - + - + \ No newline at end of file diff --git a/docs-android/app/build.gradle b/docs-android/app/build.gradle index 3c6ad05c..ce706bde 100644 --- a/docs-android/app/build.gradle +++ b/docs-android/app/build.gradle @@ -3,7 +3,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.0.0-alpha7' + classpath 'com.android.tools.build:gradle:2.0.0-beta3' } } apply plugin: 'com.android.application' @@ -52,12 +52,11 @@ dependencies { compile fileTree(dir: 'libs', include: '*.jar') compile 'com.android.support:appcompat-v7:23.1.1' compile 'com.android.support:recyclerview-v7:23.1.1' - compile 'com.loopj.android:android-async-http:1.4.9' compile 'it.sephiroth.android.library.imagezoom:imagezoom:1.0.5' - compile 'de.greenrobot:eventbus:2.4.1' + compile 'org.greenrobot:eventbus:3.0.0' compile 'com.shamanland:fab:0.0.6' compile 'com.squareup.picasso:picasso:2.5.2' - compile 'com.squareup.okhttp3:okhttp:3.0.1' - compile "com.squareup.okhttp3:okhttp-urlconnection:3.0.1" + compile 'com.squareup.okhttp3:okhttp:3.1.1' + compile "com.squareup.okhttp3:okhttp-urlconnection:3.1.1" compile 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.0.2' } diff --git a/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentEditActivity.java b/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentEditActivity.java index 6214b2fe..c15d04fc 100644 --- a/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentEditActivity.java +++ b/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentEditActivity.java @@ -1,7 +1,6 @@ package com.sismics.docs.activity; import android.app.ProgressDialog; -import android.content.DialogInterface; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; @@ -25,6 +24,7 @@ import com.sismics.docs.ui.view.DatePickerView; import com.sismics.docs.ui.view.TagsCompleteTextView; import com.sismics.docs.util.PreferenceUtil; +import org.greenrobot.eventbus.EventBus; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -35,8 +35,6 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import de.greenrobot.event.EventBus; - /** * Document edition activity. * @@ -123,7 +121,7 @@ public class DocumentEditActivity extends AppCompatActivity { } else { setTitle(R.string.edit_document); titleEditText.setText(document.optString("title")); - descriptionEditText.setText(document.optString("description")); + descriptionEditText.setText(document.isNull("description") ? "" : document.optString("description")); datePickerView.setDate(new Date(document.optLong("create_date"))); languageSpinner.setSelection(languageAdapter.getItemPosition(document.optString("language"))); JSONArray documentTags = document.optJSONArray("tags"); @@ -164,13 +162,7 @@ public class DocumentEditActivity extends AppCompatActivity { // Cancellable progress dialog final ProgressDialog progressDialog = ProgressDialog.show(this, getString(R.string.please_wait), - getString(R.string.document_editing_message), true, true, - new DialogInterface.OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) { - DocumentResource.cancel(DocumentEditActivity.this); - } - }); + getString(R.string.document_editing_message), true, true); // Server callback HttpCallback callback = new HttpCallback() { diff --git a/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentViewActivity.java b/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentViewActivity.java index 8c90f2c5..c5e8d12a 100644 --- a/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentViewActivity.java +++ b/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentViewActivity.java @@ -1,16 +1,13 @@ package com.sismics.docs.activity; import android.app.AlertDialog; -import android.app.DownloadManager; import android.app.ProgressDialog; import android.content.ClipData; -import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; import android.os.Build; import android.os.Bundle; -import android.os.Environment; import android.support.v4.app.DialogFragment; import android.support.v4.view.GravityCompat; import android.support.v4.view.ViewPager; @@ -47,15 +44,18 @@ import com.sismics.docs.event.FileDeleteEvent; import com.sismics.docs.fragment.DocExportPdfFragment; import com.sismics.docs.fragment.DocShareFragment; import com.sismics.docs.listener.HttpCallback; -import com.sismics.docs.listener.JsonHttpResponseHandler; import com.sismics.docs.model.application.ApplicationContext; import com.sismics.docs.resource.CommentResource; import com.sismics.docs.resource.DocumentResource; import com.sismics.docs.resource.FileResource; import com.sismics.docs.service.FileUploadService; +import com.sismics.docs.util.NetworkUtil; import com.sismics.docs.util.PreferenceUtil; import com.sismics.docs.util.TagUtil; +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -64,9 +64,6 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; -import cz.msebera.android.httpclient.Header; -import de.greenrobot.event.EventBus; - /** * Document activity. * @@ -183,7 +180,7 @@ public class DocumentViewActivity extends AppCompatActivity { createdDateTextView.setText(date); TextView descriptionTextView = (TextView) findViewById(R.id.descriptionTextView); - if (description == null || description.isEmpty() || description.equals(JSONObject.NULL.toString())) { + if (description.isEmpty() || document.isNull("description")) { descriptionTextView.setVisibility(View.GONE); } else { descriptionTextView.setVisibility(View.VISIBLE); @@ -251,7 +248,8 @@ public class DocumentViewActivity extends AppCompatActivity { button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - DialogFragment dialog = DocExportPdfFragment.newInstance(DocumentViewActivity.this.document.optString("id")); + DialogFragment dialog = DocExportPdfFragment.newInstance( + DocumentViewActivity.this.document.optString("id"), DocumentViewActivity.this.document.optString("title")); dialog.show(getSupportFragmentManager(), "DocExportPdfFragment"); } }); @@ -282,14 +280,14 @@ public class DocumentViewActivity extends AppCompatActivity { CommentResource.add(DocumentViewActivity.this, DocumentViewActivity.this.document.optString("id"), commentEditText.getText().toString(), - new JsonHttpResponseHandler() { - public void onSuccess(int statusCode, Header[] headers, JSONObject response) { + new HttpCallback() { + public void onSuccess(JSONObject response) { EventBus.getDefault().post(new CommentAddEvent(response)); commentEditText.setText(""); } @Override - public void onAllFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) { + public void onFailure(JSONObject json, Exception e) { Toast.makeText(DocumentViewActivity.this, R.string.comment_add_failure, Toast.LENGTH_LONG).show(); } }); @@ -366,11 +364,11 @@ public class DocumentViewActivity extends AppCompatActivity { int position = fileViewPager.getCurrentItem(); if (mimeType == null || !mimeType.contains("/")) return; String ext = mimeType.split("/")[1]; - String fileName = getTitle() + "-" + position + "." + ext; + String fileName = document.optString("title") + "-" + position + "." + ext; // Download the file String fileUrl = PreferenceUtil.getServerUrl(this) + "/api/file/" + file.optString("id") + "/data"; - downloadFile(fileUrl, fileName, getTitle().toString(), getString(R.string.downloading_file, position + 1)); + NetworkUtil.downloadFile(this, fileUrl, fileName, document.optString("title"), getString(R.string.download_file_title)); } private void deleteCurrentFile() { @@ -393,24 +391,18 @@ public class DocumentViewActivity extends AppCompatActivity { // Show a progress dialog while deleting final ProgressDialog progressDialog = ProgressDialog.show(DocumentViewActivity.this, getString(R.string.please_wait), - getString(R.string.file_deleting_message), true, true, - new DialogInterface.OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) { - FileResource.cancel(DocumentViewActivity.this); - } - }); + getString(R.string.file_deleting_message), true, true); // Actual delete server call final String fileId = file.optString("id"); - FileResource.delete(DocumentViewActivity.this, fileId, new JsonHttpResponseHandler() { + FileResource.delete(DocumentViewActivity.this, fileId, new HttpCallback() { @Override - public void onSuccess(int statusCode, Header[] headers, JSONObject response) { + public void onSuccess(JSONObject response) { EventBus.getDefault().post(new FileDeleteEvent(fileId)); } @Override - public void onAllFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) { + public void onFailure(JSONObject json, Exception e) { Toast.makeText(DocumentViewActivity.this, R.string.file_delete_failure, Toast.LENGTH_LONG).show(); } @@ -435,28 +427,8 @@ public class DocumentViewActivity extends AppCompatActivity { private void downloadZip() { if (document == null) return; String url = PreferenceUtil.getServerUrl(this) + "/api/file/zip?id=" + document.optString("id"); - String fileName = getTitle() + ".zip"; - downloadFile(url, fileName, getTitle().toString(), getString(R.string.downloading_document)); - } - - /** - * Download a file using Android download manager. - * - * @param url URL to download - * @param fileName Destination file name - * @param title Notification title - * @param description Notification description - */ - private void downloadFile(String url, String fileName, String title, String description) { - String authToken = PreferenceUtil.getAuthToken(this); - DownloadManager downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); - DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); - request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); - request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName); - request.addRequestHeader("Cookie", "auth_token=" + authToken); - request.setTitle(title); - request.setDescription(description); - downloadManager.enqueue(request); + String fileName = document.optString("title") + ".zip"; + NetworkUtil.downloadFile(this, url, fileName, document.optString("title"), getString(R.string.download_document_title)); } /** @@ -478,13 +450,7 @@ public class DocumentViewActivity extends AppCompatActivity { // Show a progress dialog while deleting final ProgressDialog progressDialog = ProgressDialog.show(DocumentViewActivity.this, getString(R.string.please_wait), - getString(R.string.document_deleting_message), true, true, - new DialogInterface.OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) { - DocumentResource.cancel(DocumentViewActivity.this); - } - }); + getString(R.string.document_deleting_message), true, true); // Actual delete server call final String documentId = document.optString("id"); @@ -520,6 +486,7 @@ public class DocumentViewActivity extends AppCompatActivity { * * @param event Document fullscreen event */ + @Subscribe(threadMode = ThreadMode.MAIN) public void onEventMainThread(DocumentFullscreenEvent event) { findViewById(R.id.detailLayout).setVisibility(event.isFullscreen() ? View.GONE : View.VISIBLE); } @@ -529,6 +496,7 @@ public class DocumentViewActivity extends AppCompatActivity { * * @param event Document edit event */ + @Subscribe(threadMode = ThreadMode.MAIN) public void onEventMainThread(DocumentEditEvent event) { if (document == null) return; if (event.getDocument().optString("id").equals(document.optString("id"))) { @@ -542,6 +510,7 @@ public class DocumentViewActivity extends AppCompatActivity { * * @param event Document delete event */ + @Subscribe(threadMode = ThreadMode.MAIN) public void onEventMainThread(DocumentDeleteEvent event) { if (document == null) return; if (event.getDocumentId().equals(document.optString("id"))) { @@ -555,6 +524,7 @@ public class DocumentViewActivity extends AppCompatActivity { * * @param event File delete event */ + @Subscribe(threadMode = ThreadMode.MAIN) public void onEventMainThread(FileDeleteEvent event) { if (filePagerAdapter == null) return; filePagerAdapter.remove(event.getFileId()); @@ -567,6 +537,7 @@ public class DocumentViewActivity extends AppCompatActivity { * * @param event File add event */ + @Subscribe(threadMode = ThreadMode.MAIN) public void onEventMainThread(FileAddEvent event) { if (document == null) return; if (document.optString("id").equals(event.getDocumentId())) { @@ -579,6 +550,7 @@ public class DocumentViewActivity extends AppCompatActivity { * * @param event Comment add event */ + @Subscribe(threadMode = ThreadMode.MAIN) public void onEventMainThread(CommentAddEvent event) { if (commentListAdapter == null) return; TextView emptyView = (TextView) findViewById(R.id.commentEmptyView); @@ -593,6 +565,7 @@ public class DocumentViewActivity extends AppCompatActivity { * * @param event Comment add event */ + @Subscribe(threadMode = ThreadMode.MAIN) public void onEventMainThread(CommentDeleteEvent event) { if (commentListAdapter == null) return; TextView emptyView = (TextView) findViewById(R.id.commentEmptyView); @@ -696,14 +669,14 @@ public class DocumentViewActivity extends AppCompatActivity { final String commentId = comment.optString("id"); Toast.makeText(DocumentViewActivity.this, R.string.deleting_comment, Toast.LENGTH_LONG).show(); - CommentResource.remove(DocumentViewActivity.this, commentId, new JsonHttpResponseHandler() { + CommentResource.remove(DocumentViewActivity.this, commentId, new HttpCallback() { @Override - public void onSuccess(int statusCode, Header[] headers, JSONObject response) { + public void onSuccess(JSONObject response) { EventBus.getDefault().post(new CommentDeleteEvent(commentId)); } @Override - public void onAllFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) { + public void onFailure(JSONObject json, Exception e) { Toast.makeText(DocumentViewActivity.this, R.string.error_deleting_comment, Toast.LENGTH_LONG).show(); } }); @@ -728,9 +701,9 @@ public class DocumentViewActivity extends AppCompatActivity { listView.setVisibility(View.GONE); registerForContextMenu(listView); - CommentResource.list(this, document.optString("id"), new JsonHttpResponseHandler() { + CommentResource.list(this, document.optString("id"), new HttpCallback() { @Override - public void onSuccess(int statusCode, Header[] headers, JSONObject response) { + public void onSuccess(JSONObject response) { JSONArray comments = response.optJSONArray("comments"); commentListAdapter = new CommentListAdapter(DocumentViewActivity.this, comments); listView.setAdapter(commentListAdapter); @@ -743,7 +716,7 @@ public class DocumentViewActivity extends AppCompatActivity { } @Override - public void onAllFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) { + public void onFailure(JSONObject json, Exception e) { emptyView.setText(R.string.error_loading_comments); progressBar.setVisibility(View.GONE); listView.setVisibility(View.GONE); @@ -766,9 +739,9 @@ public class DocumentViewActivity extends AppCompatActivity { progressBar.setVisibility(View.VISIBLE); filesEmptyView.setVisibility(View.GONE); - FileResource.list(this, document.optString("id"), new JsonHttpResponseHandler() { + FileResource.list(this, document.optString("id"), new HttpCallback() { @Override - public void onSuccess(int statusCode, Header[] headers, JSONObject response) { + public void onSuccess(JSONObject response) { JSONArray files = response.optJSONArray("files"); filePagerAdapter = new FilePagerAdapter(DocumentViewActivity.this, files); fileViewPager.setAdapter(filePagerAdapter); @@ -778,7 +751,7 @@ public class DocumentViewActivity extends AppCompatActivity { } @Override - public void onAllFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) { + public void onFailure(JSONObject json, Exception e) { filesEmptyView.setText(R.string.error_loading_files); progressBar.setVisibility(View.GONE); filesEmptyView.setVisibility(View.VISIBLE); diff --git a/docs-android/app/src/main/java/com/sismics/docs/activity/LoginActivity.java b/docs-android/app/src/main/java/com/sismics/docs/activity/LoginActivity.java index 9495e863..096588bd 100644 --- a/docs-android/app/src/main/java/com/sismics/docs/activity/LoginActivity.java +++ b/docs-android/app/src/main/java/com/sismics/docs/activity/LoginActivity.java @@ -14,7 +14,7 @@ import android.widget.TextView; import com.sismics.docs.R; import com.sismics.docs.listener.CallbackListener; -import com.sismics.docs.listener.JsonHttpResponseHandler; +import com.sismics.docs.listener.HttpCallback; import com.sismics.docs.model.application.ApplicationContext; import com.sismics.docs.resource.UserResource; import com.sismics.docs.ui.form.Validator; @@ -24,8 +24,6 @@ import com.sismics.docs.util.PreferenceUtil; import org.json.JSONObject; -import cz.msebera.android.httpclient.Header; - /** * Login activity. * @@ -90,9 +88,9 @@ public class LoginActivity extends AppCompatActivity { PreferenceUtil.setServerUrl(LoginActivity.this, txtServer.getText().toString()); try { - UserResource.login(getApplicationContext(), txtUsername.getText().toString(), txtPassword.getText().toString(), new JsonHttpResponseHandler() { + UserResource.login(getApplicationContext(), txtUsername.getText().toString(), txtPassword.getText().toString(), new HttpCallback() { @Override - public void onSuccess(int statusCode, Header[] headers, JSONObject json) { + public void onSuccess(JSONObject json) { // Empty previous user caches PreferenceUtil.resetUserCache(getApplicationContext()); @@ -108,11 +106,11 @@ public class LoginActivity extends AppCompatActivity { } @Override - public void onAllFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) { + public void onFailure(JSONObject json, Exception e) { loginForm.setVisibility(View.VISIBLE); progressBar.setVisibility(View.GONE); - if (responseBytes != null && new String(responseBytes).contains("\"ForbiddenError\"")) { + if (json != null && json.optString("type").equals("ForbiddenError")) { DialogUtil.showOkDialog(LoginActivity.this, R.string.login_fail_title, R.string.login_fail); } else { DialogUtil.showOkDialog(LoginActivity.this, R.string.network_error_title, R.string.network_error); @@ -150,9 +148,9 @@ public class LoginActivity extends AppCompatActivity { finish(); } else { // Trying to get user data - UserResource.info(getApplicationContext(), new JsonHttpResponseHandler() { + UserResource.info(getApplicationContext(), new HttpCallback() { @Override - public void onSuccess(int statusCode, Header[] headers, final JSONObject json) { + public void onSuccess(final JSONObject json) { if (json.optBoolean("anonymous", true)) { loginForm.setVisibility(View.VISIBLE); return; @@ -168,7 +166,7 @@ public class LoginActivity extends AppCompatActivity { } @Override - public void onAllFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) { + public void onFailure(JSONObject json, Exception e) { DialogUtil.showOkDialog(LoginActivity.this, R.string.network_error_title, R.string.network_error); loginForm.setVisibility(View.VISIBLE); } diff --git a/docs-android/app/src/main/java/com/sismics/docs/activity/MainActivity.java b/docs-android/app/src/main/java/com/sismics/docs/activity/MainActivity.java index 80748991..6732e7f3 100644 --- a/docs-android/app/src/main/java/com/sismics/docs/activity/MainActivity.java +++ b/docs-android/app/src/main/java/com/sismics/docs/activity/MainActivity.java @@ -23,18 +23,18 @@ import com.sismics.docs.adapter.TagListAdapter; import com.sismics.docs.event.AdvancedSearchEvent; import com.sismics.docs.event.SearchEvent; import com.sismics.docs.fragment.SearchFragment; -import com.sismics.docs.listener.JsonHttpResponseHandler; +import com.sismics.docs.listener.HttpCallback; import com.sismics.docs.model.application.ApplicationContext; import com.sismics.docs.provider.RecentSuggestionsProvider; import com.sismics.docs.resource.TagResource; import com.sismics.docs.resource.UserResource; import com.sismics.docs.util.PreferenceUtil; +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; import org.json.JSONObject; -import cz.msebera.android.httpclient.Header; -import de.greenrobot.event.EventBus; - /** * Main activity. * @@ -90,9 +90,9 @@ public class MainActivity extends AppCompatActivity { if (cacheTags != null) { tagListView.setAdapter(new TagListAdapter(cacheTags.optJSONArray("stats"))); } - TagResource.stats(this, new JsonHttpResponseHandler() { + TagResource.stats(this, new HttpCallback() { @Override - public void onSuccess(int statusCode, Header[] headers, JSONObject response) { + public void onSuccess(JSONObject response) { PreferenceUtil.setCachedJson(MainActivity.this, PreferenceUtil.PREF_CACHED_TAGS_JSON, response); tagListView.setAdapter(new TagListAdapter(response.optJSONArray("stats"))); tagProgressView.setVisibility(View.GONE); @@ -100,7 +100,7 @@ public class MainActivity extends AppCompatActivity { } @Override - public void onAllFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) { + public void onFailure(JSONObject json, Exception e) { tagEmptyView.setText(R.string.error_loading_tags); tagProgressView.setVisibility(View.GONE); tagListView.setEmptyView(tagEmptyView); @@ -146,7 +146,7 @@ public class MainActivity extends AppCompatActivity { public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.logout: - UserResource.logout(getApplicationContext(), new JsonHttpResponseHandler() { + UserResource.logout(getApplicationContext(), new HttpCallback() { @Override public void onFinish() { // Force logout in all cases, so the user is not stuck in case of network error @@ -266,6 +266,7 @@ public class MainActivity extends AppCompatActivity { * * @param event Advanced search event */ + @Subscribe(threadMode = ThreadMode.MAIN) public void onEventMainThread(AdvancedSearchEvent event) { searchQuery(event.getQuery()); } diff --git a/docs-android/app/src/main/java/com/sismics/docs/adapter/FilePagerAdapter.java b/docs-android/app/src/main/java/com/sismics/docs/adapter/FilePagerAdapter.java index 8b04cede..c2926652 100644 --- a/docs-android/app/src/main/java/com/sismics/docs/adapter/FilePagerAdapter.java +++ b/docs-android/app/src/main/java/com/sismics/docs/adapter/FilePagerAdapter.java @@ -36,11 +36,6 @@ public class FilePagerAdapter extends PagerAdapter { */ private Context context; - /** - * Auth token used to download files. - */ - private String authToken; - /** * File pager adapter. * @@ -53,7 +48,6 @@ public class FilePagerAdapter extends PagerAdapter { files.add(filesArray.optJSONObject(i)); } this.context = context; - this.authToken = PreferenceUtil.getAuthToken(context); } @Override diff --git a/docs-android/app/src/main/java/com/sismics/docs/adapter/ShareListAdapter.java b/docs-android/app/src/main/java/com/sismics/docs/adapter/ShareListAdapter.java index 6469866f..e92a8862 100644 --- a/docs-android/app/src/main/java/com/sismics/docs/adapter/ShareListAdapter.java +++ b/docs-android/app/src/main/java/com/sismics/docs/adapter/ShareListAdapter.java @@ -12,14 +12,13 @@ import com.sismics.docs.R; import com.sismics.docs.event.ShareDeleteEvent; import com.sismics.docs.event.ShareSendEvent; +import org.greenrobot.eventbus.EventBus; import org.json.JSONArray; import org.json.JSONObject; import java.util.ArrayList; import java.util.List; -import de.greenrobot.event.EventBus; - /** * Share list adapter. * diff --git a/docs-android/app/src/main/java/com/sismics/docs/adapter/TagListAdapter.java b/docs-android/app/src/main/java/com/sismics/docs/adapter/TagListAdapter.java index b10be67e..f921a804 100644 --- a/docs-android/app/src/main/java/com/sismics/docs/adapter/TagListAdapter.java +++ b/docs-android/app/src/main/java/com/sismics/docs/adapter/TagListAdapter.java @@ -20,6 +20,7 @@ import org.json.JSONObject; import java.util.ArrayList; import java.util.List; +import java.util.Locale; /** * Tag list adapter. @@ -99,7 +100,7 @@ public class TagListAdapter extends BaseAdapter { TextView tagTextView = (TextView) view.findViewById(R.id.tagTextView); tagTextView.setText(tagItem.name); TextView tagCountTextView = (TextView) view.findViewById(R.id.tagCountTextView); - tagCountTextView.setText(String.format("%d", tagItem.count)); + tagCountTextView.setText(String.format(Locale.ENGLISH, "%d", tagItem.count)); // Label color filtering ImageView labelImageView = (ImageView) view.findViewById(R.id.labelImageView); diff --git a/docs-android/app/src/main/java/com/sismics/docs/fragment/DocExportPdfFragment.java b/docs-android/app/src/main/java/com/sismics/docs/fragment/DocExportPdfFragment.java index 0aab910e..3af5480c 100644 --- a/docs-android/app/src/main/java/com/sismics/docs/fragment/DocExportPdfFragment.java +++ b/docs-android/app/src/main/java/com/sismics/docs/fragment/DocExportPdfFragment.java @@ -8,8 +8,15 @@ import android.support.annotation.NonNull; import android.support.v4.app.DialogFragment; import android.view.LayoutInflater; import android.view.View; +import android.widget.CheckBox; +import android.widget.SeekBar; +import android.widget.TextView; import com.sismics.docs.R; +import com.sismics.docs.util.NetworkUtil; +import com.sismics.docs.util.PreferenceUtil; + +import java.util.Locale; /** * Export PDF dialog fragment. @@ -21,11 +28,13 @@ public class DocExportPdfFragment extends DialogFragment { * Export PDF dialog fragment. * * @param id Document ID + * @param title Document title */ - public static DocExportPdfFragment newInstance(String id) { + public static DocExportPdfFragment newInstance(String id, String title) { DocExportPdfFragment fragment = new DocExportPdfFragment(); Bundle args = new Bundle(); args.putString("id", id); + args.putString("title", title); fragment.setArguments(args); return fragment; } @@ -38,11 +47,41 @@ public class DocExportPdfFragment extends DialogFragment { // Setup the view LayoutInflater inflater = getActivity().getLayoutInflater(); View view = inflater.inflate(R.layout.document_export_pdf_dialog, null); + final SeekBar marginSeekBar = (SeekBar) view.findViewById(R.id.marginSeekBar); + final CheckBox exportMetadataCheckbox = (CheckBox) view.findViewById(R.id.exportMetadataCheckbox); + final CheckBox exportCommentsCheckbox = (CheckBox) view.findViewById(R.id.exportCommentsCheckbox); + final CheckBox fitToPageCheckbox = (CheckBox) view.findViewById(R.id.fitToPageCheckbox); + final TextView marginValueText = (TextView) view.findViewById(R.id.marginValueText); + + // Margin label follow seekbar value + marginSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + marginValueText.setText(String.format(Locale.ENGLISH, "%d", progress)); + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + + } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + + } + }); // Build the dialog builder.setView(view) .setPositiveButton(R.string.download, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { + // Download the PDF + String pdfUrl = PreferenceUtil.getServerUrl(getActivity()) + "/api/document/" + getArguments().getString("id") + "/pdf?" + + "metadata=" + exportMetadataCheckbox.isChecked() + "&comments=" + exportCommentsCheckbox.isChecked() + "&fitimagetopage=" + fitToPageCheckbox.isChecked() + + "&margin=" + marginSeekBar.getProgress(); + String title = getArguments().getString("title"); + NetworkUtil.downloadFile(getActivity(), pdfUrl, title + ".pdf", title, getString(R.string.download_pdf_title)); + getDialog().cancel(); } }) diff --git a/docs-android/app/src/main/java/com/sismics/docs/fragment/DocListFragment.java b/docs-android/app/src/main/java/com/sismics/docs/fragment/DocListFragment.java index db810b88..dad50038 100644 --- a/docs-android/app/src/main/java/com/sismics/docs/fragment/DocListFragment.java +++ b/docs-android/app/src/main/java/com/sismics/docs/fragment/DocListFragment.java @@ -27,10 +27,11 @@ import com.sismics.docs.resource.DocumentResource; import com.sismics.docs.ui.view.DividerItemDecoration; import com.sismics.docs.ui.view.EmptyRecyclerView; +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; import org.json.JSONObject; -import de.greenrobot.event.EventBus; - /** * @author bgamard. */ @@ -99,7 +100,7 @@ public class DocListFragment extends Fragment { })); // Infinite scrolling - recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() { + recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); @@ -149,6 +150,7 @@ public class DocListFragment extends Fragment { * * @param event Search event */ + @Subscribe(threadMode = ThreadMode.MAIN) public void onEventMainThread(SearchEvent event) { query = event.getQuery(); loadDocuments(getView(), true); @@ -159,6 +161,7 @@ public class DocListFragment extends Fragment { * * @param event Document edit event */ + @Subscribe(threadMode = ThreadMode.MAIN) public void onEventMainThread(DocumentEditEvent event) { adapter.updateDocument(event.getDocument()); } @@ -168,6 +171,7 @@ public class DocListFragment extends Fragment { * * @param event Document delete event */ + @Subscribe(threadMode = ThreadMode.MAIN) public void onEventMainThread(DocumentDeleteEvent event) { adapter.deleteDocument(event.getDocumentId()); } @@ -177,6 +181,7 @@ public class DocListFragment extends Fragment { * * @param event Document add event */ + @Subscribe(threadMode = ThreadMode.MAIN) public void onEventMainThread(DocumentAddEvent event) { // Refresh the list, maybe the new document fit in it loadDocuments(getView(), true); diff --git a/docs-android/app/src/main/java/com/sismics/docs/fragment/DocShareFragment.java b/docs-android/app/src/main/java/com/sismics/docs/fragment/DocShareFragment.java index aa85a063..a97f6a67 100644 --- a/docs-android/app/src/main/java/com/sismics/docs/fragment/DocShareFragment.java +++ b/docs-android/app/src/main/java/com/sismics/docs/fragment/DocShareFragment.java @@ -22,17 +22,16 @@ import com.sismics.docs.adapter.ShareListAdapter; import com.sismics.docs.event.ShareDeleteEvent; import com.sismics.docs.event.ShareSendEvent; import com.sismics.docs.listener.HttpCallback; -import com.sismics.docs.listener.JsonHttpResponseHandler; import com.sismics.docs.resource.DocumentResource; import com.sismics.docs.resource.ShareResource; import com.sismics.docs.util.PreferenceUtil; +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; import org.json.JSONArray; import org.json.JSONObject; -import cz.msebera.android.httpclient.Header; -import de.greenrobot.event.EventBus; - /** * Document sharing dialog fragment. * @@ -76,15 +75,15 @@ public class DocShareFragment extends DialogFragment { shareAddButton.setEnabled(false); ShareResource.add(getActivity(), getArguments().getString("id"), shareNameEditText.getText().toString(), - new JsonHttpResponseHandler() { + new HttpCallback() { @Override - public void onSuccess(int statusCode, Header[] headers, JSONObject response) { + public void onSuccess(JSONObject response) { shareNameEditText.setText(""); loadShares(getDialog().getWindow().getDecorView()); } @Override - public void onAllFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) { + public void onFailure(JSONObject json, Exception e) { Toast.makeText(getActivity(), R.string.error_adding_share, Toast.LENGTH_SHORT).show(); } @@ -141,20 +140,32 @@ public class DocShareFragment extends DialogFragment { }); } + /** + * A share delete event has been fired. + * + * @param event Share delete event + */ + @Subscribe(threadMode = ThreadMode.MAIN) public void onEventMainThread(ShareDeleteEvent event) { - ShareResource.delete(getActivity(), event.getId(), new JsonHttpResponseHandler() { + ShareResource.delete(getActivity(), event.getId(), new HttpCallback() { @Override - public void onSuccess(int statusCode, Header[] headers, JSONObject response) { + public void onSuccess(JSONObject response) { loadShares(getDialog().getWindow().getDecorView()); } @Override - public void onAllFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) { + public void onFailure(JSONObject json, Exception e) { Toast.makeText(getActivity(), R.string.error_deleting_share, Toast.LENGTH_SHORT).show(); } }); } + /** + * A share send event has been fired. + * + * @param event Share send event + */ + @Subscribe(threadMode = ThreadMode.MAIN) public void onEventMainThread(ShareSendEvent event) { if (document == null) return; diff --git a/docs-android/app/src/main/java/com/sismics/docs/fragment/SearchFragment.java b/docs-android/app/src/main/java/com/sismics/docs/fragment/SearchFragment.java index 93ead327..d5eeedc5 100644 --- a/docs-android/app/src/main/java/com/sismics/docs/fragment/SearchFragment.java +++ b/docs-android/app/src/main/java/com/sismics/docs/fragment/SearchFragment.java @@ -22,14 +22,13 @@ import com.sismics.docs.ui.view.TagsCompleteTextView; import com.sismics.docs.util.PreferenceUtil; import com.sismics.docs.util.SearchQueryBuilder; +import org.greenrobot.eventbus.EventBus; import org.json.JSONArray; import org.json.JSONObject; import java.util.ArrayList; import java.util.List; -import de.greenrobot.event.EventBus; - /** * Advanced search fragment. * diff --git a/docs-android/app/src/main/java/com/sismics/docs/listener/JsonHttpResponseHandler.java b/docs-android/app/src/main/java/com/sismics/docs/listener/JsonHttpResponseHandler.java deleted file mode 100644 index ee9bb33c..00000000 --- a/docs-android/app/src/main/java/com/sismics/docs/listener/JsonHttpResponseHandler.java +++ /dev/null @@ -1,242 +0,0 @@ -/* - Android Asynchronous Http Client - Copyright (c) 2011 James Smith - http://loopj.com - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package com.sismics.docs.listener; - -import android.util.Log; - -import com.loopj.android.http.TextHttpResponseHandler; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.json.JSONTokener; - -import cz.msebera.android.httpclient.Header; -import cz.msebera.android.httpclient.HttpStatus; - -/** - * Used to intercept and handle the responses from requests made using {@link com.loopj.android.http.AsyncHttpClient}, with - * automatic parsing into a {@link JSONObject} or {@link JSONArray}.

 

This class is - * designed to be passed to get, post, put and delete requests with the {@link #onSuccess(int, - * cz.msebera.android.httpclient.Header[], org.json.JSONArray)} or {@link #onSuccess(int, - * cz.msebera.android.httpclient.Header[], org.json.JSONObject)} methods anonymously overridden.

 

- * Additionally, you can override the other event methods from the parent class. - */ -public class JsonHttpResponseHandler extends TextHttpResponseHandler { - - private static final String LOG_TAG = "JsonHttpResponseHandler"; - - /** - * Creates new JsonHttpResponseHandler, with JSON String encoding UTF-8 - */ - public JsonHttpResponseHandler() { - super(DEFAULT_CHARSET); - } - - /** - * Creates new JsonHttpRespnseHandler with given JSON String encoding - * - * @param encoding String encoding to be used when parsing JSON - */ - public JsonHttpResponseHandler(String encoding) { - super(encoding); - } - - /** - * Returns when request succeeds - * - * @param statusCode http response status line - * @param headers response headers if any - * @param response parsed response if any - */ - public void onSuccess(int statusCode, Header[] headers, JSONObject response) { - Log.w(LOG_TAG, "onSuccess(int, Header[], JSONObject) was not overriden, but callback was received"); - } - - /** - * Returns when request succeeds - * - * @param statusCode http response status line - * @param headers response headers if any - * @param response parsed response if any - */ - public void onSuccess(int statusCode, Header[] headers, JSONArray response) { - Log.w(LOG_TAG, "onSuccess(int, Header[], JSONArray) was not overriden, but callback was received"); - } - - /** - * Returns when request failed - * - * @param statusCode http response status line - * @param headers response headers if any - * @param throwable throwable describing the way request failed - * @param errorResponse parsed response if any - */ - public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONObject errorResponse) { - Log.w(LOG_TAG, "onFailure(int, Header[], Throwable, JSONObject) was not overriden, but callback was received", throwable); - } - - /** - * Returns when request failed - * - * @param statusCode http response status line - * @param headers response headers if any - * @param throwable throwable describing the way request failed - * @param errorResponse parsed response if any - */ - public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONArray errorResponse) { - Log.w(LOG_TAG, "onFailure(int, Header[], Throwable, JSONArray) was not overriden, but callback was received", throwable); - } - - @Override - public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) { - Log.w(LOG_TAG, "onFailure(int, Header[], String, Throwable) was not overriden, but callback was received", throwable); - } - - @Override - public void onSuccess(int statusCode, Header[] headers, String responseString) { - Log.w(LOG_TAG, "onSuccess(int, Header[], String) was not overriden, but callback was received"); - } - - @Override - public final void onSuccess(final int statusCode, final Header[] headers, final byte[] responseBytes) { - if (statusCode != HttpStatus.SC_NO_CONTENT) { - Runnable parser = new Runnable() { - @Override - public void run() { - try { - final Object jsonResponse = parseResponse(responseBytes); - postRunnable(new Runnable() { - @Override - public void run() { - if (jsonResponse instanceof JSONObject) { - onSuccess(statusCode, headers, (JSONObject) jsonResponse); - } else if (jsonResponse instanceof JSONArray) { - onSuccess(statusCode, headers, (JSONArray) jsonResponse); - } else if (jsonResponse instanceof String) { - onFailure(statusCode, headers, (String) jsonResponse, new JSONException("Response cannot be parsed as JSON data")); - } else { - onFailure(statusCode, headers, new JSONException("Unexpected response type " + jsonResponse.getClass().getName()), (JSONObject) null); - } - - } - }); - } catch (final JSONException ex) { - postRunnable(new Runnable() { - @Override - public void run() { - onFailure(statusCode, headers, ex, (JSONObject) null); - } - }); - } - } - }; - if (!getUseSynchronousMode()) { - new Thread(parser).start(); - } else { - // In synchronous mode everything should be run on one thread - parser.run(); - } - } else { - onSuccess(statusCode, headers, new JSONObject()); - } - } - - @Override - public final void onFailure(final int statusCode, final Header[] headers, final byte[] responseBytes, final Throwable throwable) { - if (responseBytes != null) { - Runnable parser = new Runnable() { - @Override - public void run() { - try { - final Object jsonResponse = parseResponse(responseBytes); - postRunnable(new Runnable() { - @Override - public void run() { - if (jsonResponse instanceof JSONObject) { - onFailure(statusCode, headers, throwable, (JSONObject) jsonResponse); - } else if (jsonResponse instanceof JSONArray) { - onFailure(statusCode, headers, throwable, (JSONArray) jsonResponse); - } else if (jsonResponse instanceof String) { - onFailure(statusCode, headers, (String) jsonResponse, throwable); - } else { - onFailure(statusCode, headers, new JSONException("Unexpected response type " + jsonResponse.getClass().getName()), (JSONObject) null); - } - } - }); - - } catch (final JSONException ex) { - postRunnable(new Runnable() { - @Override - public void run() { - onFailure(statusCode, headers, ex, (JSONObject) null); - } - }); - - } - } - }; - if (!getUseSynchronousMode()) { - new Thread(parser).start(); - } else { - // In synchronous mode everything should be run on one thread - parser.run(); - } - } else { - Log.v(LOG_TAG, "response body is null, calling onFailure(Throwable, JSONObject)"); - onFailure(statusCode, headers, throwable, (JSONObject) null); - } - - // In all cases, call the default failure listener - onAllFailure(statusCode, headers, responseBytes, throwable); - } - - public void onAllFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) { - // All failures go there - } - - /** - * Returns Object of type {@link JSONObject}, {@link JSONArray}, String, Boolean, Integer, Long, - * Double or {@link JSONObject#NULL}, see {@link org.json.JSONTokener#nextValue()} - * - * @param responseBody response bytes to be assembled in String and parsed as JSON - * @return Object parsedResponse - * @throws org.json.JSONException exception if thrown while parsing JSON - */ - protected Object parseResponse(byte[] responseBody) throws JSONException { - if (null == responseBody) - return null; - Object result = null; - //trim the string to prevent start with blank, and test if the string is valid JSON, because the parser don't do this :(. If JSON is not valid this will return null - String jsonString = getResponseString(responseBody, getCharset()); - if (jsonString != null) { - jsonString = jsonString.trim(); - if (jsonString.startsWith(UTF8_BOM)) { - jsonString = jsonString.substring(1); - } - if (jsonString.startsWith("{") || jsonString.startsWith("[")) { - result = new JSONTokener(jsonString).nextValue(); - } - } - if (result == null) { - result = jsonString; - } - return result; - } -} diff --git a/docs-android/app/src/main/java/com/sismics/docs/listener/RecyclerItemClickListener.java b/docs-android/app/src/main/java/com/sismics/docs/listener/RecyclerItemClickListener.java index 4287396b..92a7c80e 100644 --- a/docs-android/app/src/main/java/com/sismics/docs/listener/RecyclerItemClickListener.java +++ b/docs-android/app/src/main/java/com/sismics/docs/listener/RecyclerItemClickListener.java @@ -29,7 +29,7 @@ public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListen public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) { View childView = view.findChildViewUnder(e.getX(), e.getY()); if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) { - mListener.onItemClick(childView, view.getChildPosition(childView)); + mListener.onItemClick(childView, view.getChildAdapterPosition(childView)); } return false; } diff --git a/docs-android/app/src/main/java/com/sismics/docs/model/application/ApplicationContext.java b/docs-android/app/src/main/java/com/sismics/docs/model/application/ApplicationContext.java index 3fe032a8..b911ddc3 100644 --- a/docs-android/app/src/main/java/com/sismics/docs/model/application/ApplicationContext.java +++ b/docs-android/app/src/main/java/com/sismics/docs/model/application/ApplicationContext.java @@ -4,14 +4,12 @@ import android.app.Activity; import android.content.Context; import com.sismics.docs.listener.CallbackListener; -import com.sismics.docs.listener.JsonHttpResponseHandler; +import com.sismics.docs.listener.HttpCallback; import com.sismics.docs.resource.UserResource; import com.sismics.docs.util.PreferenceUtil; import org.json.JSONObject; -import cz.msebera.android.httpclient.Header; - /** * Global context of the application. * @@ -81,9 +79,9 @@ public class ApplicationContext { * @param callbackListener CallbackListener */ public void fetchUserInfo(final Activity activity, final CallbackListener callbackListener) { - UserResource.info(activity.getApplicationContext(), new JsonHttpResponseHandler() { + UserResource.info(activity.getApplicationContext(), new HttpCallback() { @Override - public void onSuccess(int statusCode, Header[] headers, final JSONObject json) { + public void onSuccess(JSONObject json) { // Save data in application context if (!json.optBoolean("anonymous", true)) { setUserInfo(activity.getApplicationContext(), json); diff --git a/docs-android/app/src/main/java/com/sismics/docs/resource/BaseResource.java b/docs-android/app/src/main/java/com/sismics/docs/resource/BaseResource.java index c0f421cb..e78bd2a2 100644 --- a/docs-android/app/src/main/java/com/sismics/docs/resource/BaseResource.java +++ b/docs-android/app/src/main/java/com/sismics/docs/resource/BaseResource.java @@ -1,124 +1,15 @@ package com.sismics.docs.resource; import android.content.Context; -import android.os.Build; -import com.loopj.android.http.AsyncHttpClient; -import com.loopj.android.http.PersistentCookieStore; -import com.sismics.docs.util.ApplicationUtil; import com.sismics.docs.util.PreferenceUtil; -import java.io.IOException; -import java.net.Socket; -import java.security.KeyManagementException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.UnrecoverableKeyException; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.util.Locale; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; - -import cz.msebera.android.httpclient.conn.ssl.SSLSocketFactory; - /** * Base class for API access. * * @author bgamard */ public class BaseResource { - /** - * User-Agent to use. - */ - protected static String USER_AGENT = null; - - /** - * Accept-Language header. - */ - protected static String ACCEPT_LANGUAGE = null; - - /** - * Async HTTP client. - */ - protected static AsyncHttpClient client = new AsyncHttpClient(); - - static { - // 20sec default timeout - client.setTimeout(60000); - try { - KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); - trustStore.load(null, null); - - // Async HTTP Client uses another HTTP libary - MySSLSocketFactory sf = new MySSLSocketFactory(trustStore); - sf.setHostnameVerifier(MySSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); - client.setSSLSocketFactory(sf); - } catch (Exception e) { - // NOP - } - } - - /** - * Resource initialization. - * - * @param context Context - */ - protected static void init(Context context) { - client.setCookieStore(new PersistentCookieStore(context)); - - if (USER_AGENT == null) { - USER_AGENT = "Sismics Docs Android " + ApplicationUtil.getVersionName(context) + "/Android " + Build.VERSION.RELEASE + "/" + Build.MODEL; - client.setUserAgent(USER_AGENT); - } - - if (ACCEPT_LANGUAGE == null) { - Locale locale = Locale.getDefault(); - ACCEPT_LANGUAGE = locale.getLanguage() + "_" + locale.getCountry(); - client.addHeader("Accept-Language", ACCEPT_LANGUAGE); - } - } - - /** - * Socket factory to allow self-signed certificates for Async HTTP Client. - * - * @author bgamard - */ - public static class MySSLSocketFactory extends cz.msebera.android.httpclient.conn.ssl.SSLSocketFactory { - SSLContext sslContext = SSLContext.getInstance(SSLSocketFactory.TLS); - - public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { - super(truststore); - - TrustManager tm = new X509TrustManager() { - public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { - } - - public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { - } - - public X509Certificate[] getAcceptedIssuers() { - return null; - } - }; - - sslContext.init(null, new TrustManager[]{tm}, null); - } - - @Override - public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException { - return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose); - } - - @Override - public Socket createSocket() throws IOException { - return sslContext.getSocketFactory().createSocket(); - } - } - /** * Returns cleaned API URL. * diff --git a/docs-android/app/src/main/java/com/sismics/docs/resource/CommentResource.java b/docs-android/app/src/main/java/com/sismics/docs/resource/CommentResource.java index 6e545956..d93ee657 100644 --- a/docs-android/app/src/main/java/com/sismics/docs/resource/CommentResource.java +++ b/docs-android/app/src/main/java/com/sismics/docs/resource/CommentResource.java @@ -2,8 +2,12 @@ package com.sismics.docs.resource; import android.content.Context; -import com.loopj.android.http.RequestParams; -import com.sismics.docs.listener.JsonHttpResponseHandler; +import com.sismics.docs.listener.HttpCallback; +import com.sismics.docs.util.OkHttpUtil; + +import okhttp3.FormBody; +import okhttp3.HttpUrl; +import okhttp3.Request; /** @@ -17,12 +21,16 @@ public class CommentResource extends BaseResource { * * @param context Context * @param documentId Document ID - * @param responseHandler Callback + * @param callback Callback */ - public static void list(Context context, String documentId, JsonHttpResponseHandler responseHandler) { - init(context); - - client.get(getApiUrl(context) + "/comment/" + documentId, responseHandler); + public static void list(Context context, String documentId, HttpCallback callback) { + Request request = new Request.Builder() + .url(HttpUrl.parse(getApiUrl(context) + "/comment/" + documentId)) + .get() + .build(); + OkHttpUtil.buildClient(context) + .newCall(request) + .enqueue(HttpCallback.buildOkHttpCallback(callback)); } /** @@ -31,15 +39,19 @@ public class CommentResource extends BaseResource { * @param context Context * @param documentId Document ID * @param content Comment content - * @param responseHandler Callback + * @param callback Callback */ - public static void add(Context context, String documentId, String content, JsonHttpResponseHandler responseHandler) { - init(context); - - RequestParams params = new RequestParams(); - params.put("id", documentId); - params.put("content", content); - client.put(getApiUrl(context) + "/comment", params, responseHandler); + public static void add(Context context, String documentId, String content, HttpCallback callback) { + Request request = new Request.Builder() + .url(HttpUrl.parse(getApiUrl(context) + "/comment")) + .put(new FormBody.Builder() + .add("id", documentId) + .add("content", content) + .build()) + .build(); + OkHttpUtil.buildClient(context) + .newCall(request) + .enqueue(HttpCallback.buildOkHttpCallback(callback)); } /** @@ -47,20 +59,15 @@ public class CommentResource extends BaseResource { * * @param context Context * @param commentId Comment ID - * @param responseHandler Callback + * @param callback Callback */ - public static void remove(Context context, String commentId, JsonHttpResponseHandler responseHandler) { - init(context); - - client.delete(getApiUrl(context) + "/comment/" + commentId, responseHandler); - } - - /** - * Cancel pending requests. - * - * @param context Context - */ - public static void cancel(Context context) { - client.cancelRequests(context, true); + public static void remove(Context context, String commentId, HttpCallback callback) { + Request request = new Request.Builder() + .url(HttpUrl.parse(getApiUrl(context) + "/comment/" + commentId)) + .delete() + .build(); + OkHttpUtil.buildClient(context) + .newCall(request) + .enqueue(HttpCallback.buildOkHttpCallback(callback)); } } diff --git a/docs-android/app/src/main/java/com/sismics/docs/resource/DocumentResource.java b/docs-android/app/src/main/java/com/sismics/docs/resource/DocumentResource.java index 474590bf..b3bc5a71 100644 --- a/docs-android/app/src/main/java/com/sismics/docs/resource/DocumentResource.java +++ b/docs-android/app/src/main/java/com/sismics/docs/resource/DocumentResource.java @@ -94,9 +94,8 @@ public class DocumentResource extends BaseResource { .add("description", description) .add("language", language) .add("create_date", Long.toString(createDate)); - String[] tagIdArray = tagIdList.toArray(new String[tagIdList.size()]); - for (int i = 0; i < tagIdArray.length; i++) { - formBuilder.add("tags", tagIdArray[i]); + for( String tagId : tagIdList) { + formBuilder.add("tags", tagId); } Request request = new Request.Builder() @@ -127,9 +126,8 @@ public class DocumentResource extends BaseResource { .add("description", description) .add("language", language) .add("create_date", Long.toString(createDate)); - String[] tagIdArray = tagIdList.toArray(new String[tagIdList.size()]); - for (int i = 0; i < tagIdArray.length; i++) { - formBuilder.add("tags", tagIdArray[i]); + for( String tagId : tagIdList) { + formBuilder.add("tags", tagId); } Request request = new Request.Builder() @@ -140,13 +138,4 @@ public class DocumentResource extends BaseResource { .newCall(request) .enqueue(HttpCallback.buildOkHttpCallback(callback)); } - - /** - * Cancel pending requests. - * - * @param context Context - */ - public static void cancel(Context context) { - client.cancelRequests(context, true); - } } diff --git a/docs-android/app/src/main/java/com/sismics/docs/resource/FileResource.java b/docs-android/app/src/main/java/com/sismics/docs/resource/FileResource.java index 2e594817..87922f8d 100644 --- a/docs-android/app/src/main/java/com/sismics/docs/resource/FileResource.java +++ b/docs-android/app/src/main/java/com/sismics/docs/resource/FileResource.java @@ -2,13 +2,24 @@ package com.sismics.docs.resource; import android.content.Context; -import com.loopj.android.http.PersistentCookieStore; -import com.loopj.android.http.RequestParams; -import com.loopj.android.http.SyncHttpClient; -import com.sismics.docs.listener.JsonHttpResponseHandler; +import com.sismics.docs.listener.HttpCallback; +import com.sismics.docs.util.OkHttpUtil; +import org.json.JSONObject; + +import java.io.IOException; import java.io.InputStream; -import java.security.KeyStore; + +import okhttp3.HttpUrl; +import okhttp3.MediaType; +import okhttp3.MultipartBody; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; +import okhttp3.internal.Util; +import okio.BufferedSink; +import okio.Okio; +import okio.Source; /** @@ -22,12 +33,19 @@ public class FileResource extends BaseResource { * * @param context Context * @param documentId Document ID - * @param responseHandler Callback + * @param callback Callback */ - public static void list(Context context, String documentId, JsonHttpResponseHandler responseHandler) { - init(context); - - client.get(getApiUrl(context) + "/file/list?id=" + documentId, responseHandler); + public static void list(Context context, String documentId, HttpCallback callback) { + Request request = new Request.Builder() + .url(HttpUrl.parse(getApiUrl(context) + "/file/list") + .newBuilder() + .addQueryParameter("id", documentId) + .build()) + .get() + .build(); + OkHttpUtil.buildClient(context) + .newCall(request) + .enqueue(HttpCallback.buildOkHttpCallback(callback)); } /** @@ -35,12 +53,16 @@ public class FileResource extends BaseResource { * * @param context Context * @param id ID - * @param responseHandler Callback + * @param callback Callback */ - public static void delete(Context context, String id, JsonHttpResponseHandler responseHandler) { - init(context); - - client.delete(getApiUrl(context) + "/file/" + id, responseHandler); + public static void delete(Context context, String id, HttpCallback callback) { + Request request = new Request.Builder() + .url(HttpUrl.parse(getApiUrl(context) + "/file/" + id)) + .delete() + .build(); + OkHttpUtil.buildClient(context) + .newCall(request) + .enqueue(HttpCallback.buildOkHttpCallback(callback)); } /** @@ -49,34 +71,53 @@ public class FileResource extends BaseResource { * @param context Context * @param documentId Document ID * @param is Input stream - * @param responseHandler Callback + * @param callback Callback * @throws Exception */ - public static void addSync(Context context, String documentId, InputStream is, JsonHttpResponseHandler responseHandler) throws Exception { - init(context); + public static void addSync(Context context, String documentId, final InputStream is, HttpCallback callback) throws Exception { + Request request = new Request.Builder() + .url(HttpUrl.parse(getApiUrl(context) + "/file")) + .put(new MultipartBody.Builder() + .setType(MultipartBody.FORM) + .addFormDataPart("id", documentId) + .addFormDataPart("file", "file", new RequestBody() { + @Override + public MediaType contentType() { + return MediaType.parse("application/octet-stream"); + } - SyncHttpClient client = new SyncHttpClient(); - KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); - trustStore.load(null, null); - MySSLSocketFactory sf = new MySSLSocketFactory(trustStore); - sf.setHostnameVerifier(MySSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); - client.setSSLSocketFactory(sf); - client.setCookieStore(new PersistentCookieStore(context)); - client.setUserAgent(USER_AGENT); - client.addHeader("Accept-Language", ACCEPT_LANGUAGE); + @Override + public void writeTo(BufferedSink sink) throws IOException { + Source source = Okio.source(is); + try { + sink.writeAll(source); + } finally { + Util.closeQuietly(source); + } + } + }) + .build()) + .build(); + Response response = OkHttpUtil.buildClient(context) + .newCall(request) + .execute(); - RequestParams params = new RequestParams(); - params.put("id", documentId); - params.put("file", is, "file", "application/octet-stream", true); - client.put(getApiUrl(context) + "/file", params, responseHandler); - } + // Call the right callback + final String body = response.body().string(); + if (response.isSuccessful()) { + try { + callback.onSuccess(new JSONObject(body)); + } catch (Exception e) { + callback.onFailure(null, e); + } + } else { + try { + callback.onFailure(new JSONObject(body), null); + } catch (Exception e) { + callback.onFailure(null, e); + } + } - /** - * Cancel pending requests. - * - * @param context Context - */ - public static void cancel(Context context) { - client.cancelRequests(context, true); + callback.onFinish(); } } diff --git a/docs-android/app/src/main/java/com/sismics/docs/resource/ShareResource.java b/docs-android/app/src/main/java/com/sismics/docs/resource/ShareResource.java index 833d993e..fbbfba81 100644 --- a/docs-android/app/src/main/java/com/sismics/docs/resource/ShareResource.java +++ b/docs-android/app/src/main/java/com/sismics/docs/resource/ShareResource.java @@ -2,8 +2,12 @@ package com.sismics.docs.resource; import android.content.Context; -import com.loopj.android.http.RequestParams; -import com.sismics.docs.listener.JsonHttpResponseHandler; +import com.sismics.docs.listener.HttpCallback; +import com.sismics.docs.util.OkHttpUtil; + +import okhttp3.FormBody; +import okhttp3.HttpUrl; +import okhttp3.Request; /** @@ -18,15 +22,19 @@ public class ShareResource extends BaseResource { * @param context Context * @param documentId Document ID * @param name Name - * @param responseHandler Callback + * @param callback Callback */ - public static void add(Context context, String documentId, String name, JsonHttpResponseHandler responseHandler) { - init(context); - - RequestParams params = new RequestParams(); - params.put("id", documentId); - params.put("name", name); - client.put(getApiUrl(context) + "/share", params, responseHandler); + public static void add(Context context, String documentId, String name, HttpCallback callback) { + Request request = new Request.Builder() + .url(HttpUrl.parse(getApiUrl(context) + "/share")) + .put(new FormBody.Builder() + .add("id", documentId) + .add("name", name) + .build()) + .build(); + OkHttpUtil.buildClient(context) + .newCall(request) + .enqueue(HttpCallback.buildOkHttpCallback(callback)); } /** @@ -34,11 +42,15 @@ public class ShareResource extends BaseResource { * * @param context Context * @param id ID - * @param responseHandler Callback + * @param callback Callback */ - public static void delete(Context context, String id, JsonHttpResponseHandler responseHandler) { - init(context); - - client.delete(getApiUrl(context) + "/share/" + id, responseHandler); + public static void delete(Context context, String id, HttpCallback callback) { + Request request = new Request.Builder() + .url(HttpUrl.parse(getApiUrl(context) + "/share/" + id)) + .delete() + .build(); + OkHttpUtil.buildClient(context) + .newCall(request) + .enqueue(HttpCallback.buildOkHttpCallback(callback)); } } diff --git a/docs-android/app/src/main/java/com/sismics/docs/resource/TagResource.java b/docs-android/app/src/main/java/com/sismics/docs/resource/TagResource.java index db03bb16..34539d14 100644 --- a/docs-android/app/src/main/java/com/sismics/docs/resource/TagResource.java +++ b/docs-android/app/src/main/java/com/sismics/docs/resource/TagResource.java @@ -2,7 +2,11 @@ package com.sismics.docs.resource; import android.content.Context; -import com.sismics.docs.listener.JsonHttpResponseHandler; +import com.sismics.docs.listener.HttpCallback; +import com.sismics.docs.util.OkHttpUtil; + +import okhttp3.HttpUrl; +import okhttp3.Request; /** @@ -15,11 +19,15 @@ public class TagResource extends BaseResource { * GET /tag/stats. * * @param context Context - * @param responseHandler Callback + * @param callback Callback */ - public static void stats(Context context, JsonHttpResponseHandler responseHandler) { - init(context); - - client.get(getApiUrl(context) + "/tag/stats", responseHandler); + public static void stats(Context context, HttpCallback callback) { + Request request = new Request.Builder() + .url(HttpUrl.parse(getApiUrl(context) + "/tag/stats")) + .get() + .build(); + OkHttpUtil.buildClient(context) + .newCall(request) + .enqueue(HttpCallback.buildOkHttpCallback(callback)); } } diff --git a/docs-android/app/src/main/java/com/sismics/docs/resource/UserResource.java b/docs-android/app/src/main/java/com/sismics/docs/resource/UserResource.java index 36cb11db..3d35564a 100644 --- a/docs-android/app/src/main/java/com/sismics/docs/resource/UserResource.java +++ b/docs-android/app/src/main/java/com/sismics/docs/resource/UserResource.java @@ -2,8 +2,12 @@ package com.sismics.docs.resource; import android.content.Context; -import com.loopj.android.http.RequestParams; -import com.sismics.docs.listener.JsonHttpResponseHandler; +import com.sismics.docs.listener.HttpCallback; +import com.sismics.docs.util.OkHttpUtil; + +import okhttp3.FormBody; +import okhttp3.HttpUrl; +import okhttp3.Request; /** * Access to /user API. @@ -18,41 +22,51 @@ public class UserResource extends BaseResource { * @param context Context * @param username Username * @param password Password - * @param responseHandler Callback + * @param callback Callback */ - public static void login(Context context, String username, String password, JsonHttpResponseHandler responseHandler) { - init(context); - - RequestParams params = new RequestParams(); - params.put("username", username); - params.put("password", password); - params.put("remember", "true"); - client.post(getApiUrl(context) + "/user/login", params, responseHandler); + public static void login(Context context, String username, String password, HttpCallback callback) { + Request request = new Request.Builder() + .url(HttpUrl.parse(getApiUrl(context) + "/user/login")) + .post(new FormBody.Builder() + .add("username", username) + .add("password", password) + .add("remember", "true") + .build()) + .build(); + OkHttpUtil.buildClient(context) + .newCall(request) + .enqueue(HttpCallback.buildOkHttpCallback(callback)); } /** * GET /user. * * @param context Context - * @param responseHandler Callback + * @param callback Callback */ - public static void info(Context context, JsonHttpResponseHandler responseHandler) { - init(context); - - RequestParams params = new RequestParams(); - client.get(getApiUrl(context) + "/user", params, responseHandler); + public static void info(Context context, HttpCallback callback) { + Request request = new Request.Builder() + .url(HttpUrl.parse(getApiUrl(context) + "/user")) + .get() + .build(); + OkHttpUtil.buildClient(context) + .newCall(request) + .enqueue(HttpCallback.buildOkHttpCallback(callback)); } /** * POST /user/logout. * * @param context Context - * @param responseHandler Callback + * @param callback Callback */ - public static void logout(Context context, JsonHttpResponseHandler responseHandler) { - init(context); - - RequestParams params = new RequestParams(); - client.post(getApiUrl(context) + "/user/logout", params, responseHandler); + public static void logout(Context context, HttpCallback callback) { + Request request = new Request.Builder() + .url(HttpUrl.parse(getApiUrl(context) + "/user/logout")) + .post(new FormBody.Builder().build()) + .build(); + OkHttpUtil.buildClient(context) + .newCall(request) + .enqueue(HttpCallback.buildOkHttpCallback(callback)); } } diff --git a/docs-android/app/src/main/java/com/sismics/docs/service/FileUploadService.java b/docs-android/app/src/main/java/com/sismics/docs/service/FileUploadService.java index 79903b77..07fcb6cd 100644 --- a/docs-android/app/src/main/java/com/sismics/docs/service/FileUploadService.java +++ b/docs-android/app/src/main/java/com/sismics/docs/service/FileUploadService.java @@ -12,16 +12,16 @@ import android.util.Log; import com.sismics.docs.R; import com.sismics.docs.event.FileAddEvent; -import com.sismics.docs.listener.JsonHttpResponseHandler; +import com.sismics.docs.listener.HttpCallback; import com.sismics.docs.resource.FileResource; +import org.greenrobot.eventbus.EventBus; import org.json.JSONObject; import java.io.IOException; import java.io.InputStream; -import cz.msebera.android.httpclient.Header; -import de.greenrobot.event.EventBus; +import okhttp3.internal.Util; /** * Service to upload a file to a document in the background. @@ -81,17 +81,22 @@ public class FileUploadService extends IntentService { */ private void handleFileUpload(final String documentId, final Uri uri) throws Exception { final InputStream is = getContentResolver().openInputStream(uri); - FileResource.addSync(this, documentId, is, new JsonHttpResponseHandler() { + FileResource.addSync(this, documentId, is, new HttpCallback() { @Override - public void onSuccess(int statusCode, Header[] headers, JSONObject response) { + public void onSuccess(JSONObject response) { EventBus.getDefault().post(new FileAddEvent(documentId, response.optString("id"))); FileUploadService.this.onComplete(); } @Override - public void onAllFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) { + public void onFailure(JSONObject json, Exception e) { FileUploadService.this.onError(); } + + @Override + public void onFinish() { + Util.closeQuietly(is); + } }); } diff --git a/docs-android/app/src/main/java/com/sismics/docs/util/ApplicationUtil.java b/docs-android/app/src/main/java/com/sismics/docs/util/ApplicationUtil.java index fba41d56..3c703035 100644 --- a/docs-android/app/src/main/java/com/sismics/docs/util/ApplicationUtil.java +++ b/docs-android/app/src/main/java/com/sismics/docs/util/ApplicationUtil.java @@ -10,7 +10,6 @@ import android.content.pm.PackageManager.NameNotFoundException; * @author bgamard */ public class ApplicationUtil { - /** * Returns version name. * diff --git a/docs-android/app/src/main/java/com/sismics/docs/util/DialogUtil.java b/docs-android/app/src/main/java/com/sismics/docs/util/DialogUtil.java index 271977c6..9967a25b 100644 --- a/docs-android/app/src/main/java/com/sismics/docs/util/DialogUtil.java +++ b/docs-android/app/src/main/java/com/sismics/docs/util/DialogUtil.java @@ -12,7 +12,6 @@ import com.sismics.docs.R; * @author bgamard */ public class DialogUtil { - /** * Create a dialog with an OK button. * diff --git a/docs-android/app/src/main/java/com/sismics/docs/util/NetworkUtil.java b/docs-android/app/src/main/java/com/sismics/docs/util/NetworkUtil.java new file mode 100644 index 00000000..a81b4862 --- /dev/null +++ b/docs-android/app/src/main/java/com/sismics/docs/util/NetworkUtil.java @@ -0,0 +1,33 @@ +package com.sismics.docs.util; + +import android.app.DownloadManager; +import android.content.Context; +import android.net.Uri; +import android.os.Environment; + +/** + * Utility class for network actions. + * + * @author bgamard. + */ +public class NetworkUtil { + /** + * Download a file using Android download manager. + * + * @param url URL to download + * @param fileName Destination file name + * @param title Notification title + * @param description Notification description + */ + public static void downloadFile(Context context, String url, String fileName, String title, String description) { + String authToken = PreferenceUtil.getAuthToken(context); + DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); + DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); + request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); + request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName); + request.addRequestHeader("Cookie", "auth_token=" + authToken); + request.setTitle(title); + request.setDescription(description); + downloadManager.enqueue(request); + } +} diff --git a/docs-android/app/src/main/java/com/sismics/docs/util/OkHttpUtil.java b/docs-android/app/src/main/java/com/sismics/docs/util/OkHttpUtil.java index e6756cdf..8ab91793 100644 --- a/docs-android/app/src/main/java/com/sismics/docs/util/OkHttpUtil.java +++ b/docs-android/app/src/main/java/com/sismics/docs/util/OkHttpUtil.java @@ -11,8 +11,6 @@ import com.squareup.picasso.Picasso; import java.io.IOException; import java.net.CookieManager; import java.net.CookiePolicy; -import java.net.HttpCookie; -import java.net.URI; import java.security.cert.CertificateException; import java.util.Locale; import java.util.concurrent.TimeUnit; @@ -105,10 +103,10 @@ public class OkHttpUtil { @Override public Response intercept(Interceptor.Chain chain) throws IOException { // Override cache configuration final Request original = chain.request(); - final Request.Builder requestBuilder = original.newBuilder() + return chain.proceed(original.newBuilder() .header("Cache-Control", "max-age=" + (3600 * 24 * 365)) - .method(original.method(), original.body()); - return chain.proceed(requestBuilder.build()); + .method(original.method(), original.body()) + .build()); } }) .cache(getCache(context)) @@ -169,8 +167,6 @@ public class OkHttpUtil { // Cookie handling PersistentCookieStore cookieStore = new PersistentCookieStore(context); CookieManager cookieManager = new CookieManager(cookieStore, CookiePolicy.ACCEPT_ALL); - cookieStore.add(URI.create(PreferenceUtil.getServerUrl(context)), - new HttpCookie("auth_token", PreferenceUtil.getAuthToken(context))); // TODO Remove me when async http is ditched // Runtime configuration return okHttpClient.newBuilder() @@ -178,11 +174,11 @@ public class OkHttpUtil { .addNetworkInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { - Request originalRequest = chain.request(); - return chain.proceed(originalRequest.newBuilder() + Request original = chain.request(); + return chain.proceed(original.newBuilder() .header("User-Agent", userAgent) .header("Accept-Language", acceptLanguage) - // TODO necessary?? .method(originalRequest.method(), originalRequest.body()) + .method(original.method(), original.body()) .build()); } }) diff --git a/docs-android/app/src/main/java/com/sismics/docs/util/PreferenceUtil.java b/docs-android/app/src/main/java/com/sismics/docs/util/PreferenceUtil.java index 581bc139..da8537ea 100644 --- a/docs-android/app/src/main/java/com/sismics/docs/util/PreferenceUtil.java +++ b/docs-android/app/src/main/java/com/sismics/docs/util/PreferenceUtil.java @@ -5,14 +5,13 @@ import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.preference.PreferenceManager; -import com.loopj.android.http.PersistentCookieStore; +import com.sismics.docs.resource.cookie.PersistentCookieStore; import org.json.JSONObject; +import java.net.HttpCookie; import java.util.List; -import cz.msebera.android.httpclient.cookie.Cookie; - /** * Utility class on preferences. * @@ -27,6 +26,7 @@ public class PreferenceUtil { /** * Returns a preference of boolean type. + * * @param context Context * @param key Shared preference key * @return Shared preference value @@ -38,6 +38,7 @@ public class PreferenceUtil { /** * Returns a preference of string type. + * * @param context Context * @param key Shared preference key * @return Shared preference value @@ -49,6 +50,7 @@ public class PreferenceUtil { /** * Returns a preference of integer type. + * * @param context Context * @param key Shared preference key * @return Shared preference value @@ -70,6 +72,7 @@ public class PreferenceUtil { /** * Update JSON cache. + * * @param context Context * @param key Shared preference key * @param json JSON data @@ -81,6 +84,7 @@ public class PreferenceUtil { /** * Returns a JSON cache. + * * @param context Context * @param key Shared preference key * @return JSON data @@ -97,6 +101,7 @@ public class PreferenceUtil { /** * Update server URL. + * * @param context Context */ public static void setServerUrl(Context context, String serverUrl) { @@ -106,6 +111,7 @@ public class PreferenceUtil { /** * Empty user caches. + * * @param context Context */ public static void resetUserCache(Context context) { @@ -119,12 +125,13 @@ public class PreferenceUtil { /** * Returns auth token cookie from shared preferences. + * * @return Auth token */ public static String getAuthToken(Context context) { PersistentCookieStore cookieStore = new PersistentCookieStore(context); - List cookieList = cookieStore.getCookies(); - for (Cookie cookie : cookieList) { + List cookieList = cookieStore.getCookies(); + for (HttpCookie cookie : cookieList) { if (cookie.getName().equals("auth_token")) { return cookie.getValue(); } @@ -135,6 +142,7 @@ public class PreferenceUtil { /** * Returns cleaned server URL. + * * @param context Context * @return Server URL */ diff --git a/docs-android/app/src/main/res/layout/document_export_pdf_dialog.xml b/docs-android/app/src/main/res/layout/document_export_pdf_dialog.xml index 2ab84d61..16db3354 100644 --- a/docs-android/app/src/main/res/layout/document_export_pdf_dialog.xml +++ b/docs-android/app/src/main/res/layout/document_export_pdf_dialog.xml @@ -8,23 +8,59 @@ + android:layout_margin="6dp" + android:text="@string/export_metadata" + android:id="@+id/exportMetadataCheckbox" /> + android:layout_margin="6dp" + android:text="@string/export_comments" + android:id="@+id/exportCommentsCheckbox" /> + android:layout_margin="6dp" + android:checked="true" + android:text="@string/fit_image_to_page" + android:id="@+id/fitToPageCheckbox" /> - + android:layout_margin="16dp" + android:orientation="horizontal"> + + + + + + + + + + \ No newline at end of file diff --git a/docs-android/app/src/main/res/values/strings.xml b/docs-android/app/src/main/res/values/strings.xml index a6e76661..c65eeaec 100644 --- a/docs-android/app/src/main/res/values/strings.xml +++ b/docs-android/app/src/main/res/values/strings.xml @@ -28,9 +28,7 @@ A crash occurred, a report has been sent to resolve this problem Created date Download current file - Downloading file number %1s Download - Downloading document Search documents All documents Shared documents @@ -119,6 +117,13 @@ Error deleting comment Export PDF Download - + Margin + Fit image to page + Export comments + Export metadata + mm + Sismics Docs file export + Sismics Docs document export + Sismics Docs PDF export diff --git a/docs-core/pom.xml b/docs-core/pom.xml index d5f915ab..6db59fe5 100644 --- a/docs-core/pom.xml +++ b/docs-core/pom.xml @@ -28,7 +28,7 @@ org.hibernate - hibernate-validator + hibernate-c3p0 diff --git a/docs-core/src/main/java/com/sismics/util/jpa/DbOpenHelper.java b/docs-core/src/main/java/com/sismics/util/jpa/DbOpenHelper.java index 47f687c7..6ac6e64d 100644 --- a/docs-core/src/main/java/com/sismics/util/jpa/DbOpenHelper.java +++ b/docs-core/src/main/java/com/sismics/util/jpa/DbOpenHelper.java @@ -1,21 +1,11 @@ package com.sismics.util.jpa; -import com.google.common.base.Strings; -import com.google.common.io.CharStreams; -import com.sismics.docs.core.util.ConfigUtil; -import com.sismics.util.ResourceUtil; -import org.hibernate.HibernateException; -import org.hibernate.JDBCException; -import org.hibernate.engine.jdbc.internal.FormatStyle; -import org.hibernate.engine.jdbc.internal.Formatter; -import org.hibernate.engine.jdbc.spi.JdbcServices; -import org.hibernate.engine.jdbc.spi.SqlStatementLogger; -import org.hibernate.service.ServiceRegistry; -import org.hibernate.tool.hbm2ddl.ConnectionHelper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.*; +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Writer; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; @@ -26,6 +16,22 @@ import java.util.Collections; import java.util.List; import java.util.ResourceBundle; +import org.hibernate.HibernateException; +import org.hibernate.JDBCException; +import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess; +import org.hibernate.engine.jdbc.internal.FormatStyle; +import org.hibernate.engine.jdbc.internal.Formatter; +import org.hibernate.engine.jdbc.spi.JdbcServices; +import org.hibernate.engine.jdbc.spi.SqlStatementLogger; +import org.hibernate.service.ServiceRegistry; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Strings; +import com.google.common.io.CharStreams; +import com.sismics.docs.core.util.ConfigUtil; +import com.sismics.util.ResourceUtil; + /** * A helper to update the database incrementally. * @@ -37,10 +43,10 @@ public abstract class DbOpenHelper { */ private static final Logger log = LoggerFactory.getLogger(DbOpenHelper.class); - private final ConnectionHelper connectionHelper; - private final SqlStatementLogger sqlStatementLogger; + private final JdbcConnectionAccess jdbcConnectionAccess; + private final List exceptions = new ArrayList(); private Formatter formatter; @@ -51,9 +57,8 @@ public abstract class DbOpenHelper { public DbOpenHelper(ServiceRegistry serviceRegistry) throws HibernateException { final JdbcServices jdbcServices = serviceRegistry.getService(JdbcServices.class); - connectionHelper = new SuppliedConnectionProviderConnectionHelper(jdbcServices.getConnectionProvider()); - sqlStatementLogger = jdbcServices.getSqlStatementLogger(); + jdbcConnectionAccess = jdbcServices.getBootstrapJdbcConnectionAccess(); formatter = (sqlStatementLogger.isFormat() ? FormatStyle.DDL : FormatStyle.NONE).getFormatter(); } @@ -67,8 +72,7 @@ public abstract class DbOpenHelper { try { try { - connectionHelper.prepare(true); - connection = connectionHelper.getConnection(); + connection = jdbcConnectionAccess.obtainConnection(); } catch (SQLException sqle) { exceptions.add(sqle); log.error("Unable to get database metadata", sqle); @@ -120,7 +124,7 @@ public abstract class DbOpenHelper { stmt.close(); stmt = null; } - connectionHelper.release(); + jdbcConnectionAccess.releaseConnection(connection); } catch (Exception e) { exceptions.add(e); log.error("Unable to close connection", e); diff --git a/docs-core/src/main/java/com/sismics/util/jpa/EMF.java b/docs-core/src/main/java/com/sismics/util/jpa/EMF.java index 01287b9e..c0073ce3 100644 --- a/docs-core/src/main/java/com/sismics/util/jpa/EMF.java +++ b/docs-core/src/main/java/com/sismics/util/jpa/EMF.java @@ -11,10 +11,10 @@ import java.util.Properties; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Environment; import org.hibernate.internal.util.config.ConfigurationHelper; import org.hibernate.service.ServiceRegistry; -import org.hibernate.service.ServiceRegistryBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,7 +36,7 @@ public final class EMF { Environment.verifyProperties(properties); ConfigurationHelper.resolvePlaceHolders(properties); - ServiceRegistry reg = new ServiceRegistryBuilder().applySettings(properties).buildServiceRegistry(); + ServiceRegistry reg = new StandardServiceRegistryBuilder().applySettings(properties).build(); DbOpenHelper openHelper = new DbOpenHelper(reg) { @@ -85,12 +85,16 @@ public final class EMF { String dbFile = dbDirectory.resolve("docs").toAbsolutePath().toString(); props.put("hibernate.connection.url", "jdbc:h2:file:" + dbFile + ";CACHE_SIZE=65536"); props.put("hibernate.connection.username", "sa"); - props.put("hibernate.hbm2ddl.auto", "none"); + props.put("hibernate.hbm2ddl.auto", ""); props.put("hibernate.dialect", "org.hibernate.dialect.HSQLDialect"); props.put("hibernate.show_sql", "false"); props.put("hibernate.format_sql", "false"); props.put("hibernate.max_fetch_depth", "5"); props.put("hibernate.cache.use_second_level_cache", "false"); + props.put("hibernate.c3p0.min_size", "1"); + props.put("hibernate.c3p0.max_size", "10"); + props.put("hibernate.c3p0.timeout", "0"); + props.put("hibernate.c3p0.max_statements", "0"); return props; } diff --git a/docs-core/src/main/java/com/sismics/util/jpa/ManagedProvidedConnectionHelper.java b/docs-core/src/main/java/com/sismics/util/jpa/ManagedProvidedConnectionHelper.java deleted file mode 100644 index 452b692e..00000000 --- a/docs-core/src/main/java/com/sismics/util/jpa/ManagedProvidedConnectionHelper.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. - * - * This copyrighted material is made available to anyone wishing to use, modify, - * copy, or redistribute it subject to the terms and conditions of the GNU - * Lesser General Public License, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this distribution; if not, write to: - * Free Software Foundation, Inc. - * 51 Franklin Street, Fifth Floor - * Boston, MA 02110-1301 USA - * - */ - -package com.sismics.util.jpa; - -import org.hibernate.cfg.Environment; -import org.hibernate.engine.jdbc.spi.SqlExceptionHelper; -import org.hibernate.internal.util.config.ConfigurationHelper; -import org.hibernate.service.ServiceRegistryBuilder; -import org.hibernate.service.internal.StandardServiceRegistryImpl; -import org.hibernate.service.jdbc.connections.spi.ConnectionProvider; -import org.hibernate.tool.hbm2ddl.ConnectionHelper; - -import java.sql.Connection; -import java.sql.SQLException; -import java.util.Properties; - -/** - * A {@link ConnectionHelper} implementation based on an internally - * built and managed {@link ConnectionProvider}. - * - * @author Steve Ebersole - */ -class ManagedProviderConnectionHelper implements ConnectionHelper { - private Properties cfgProperties; - private StandardServiceRegistryImpl serviceRegistry; - private Connection connection; - - public ManagedProviderConnectionHelper(Properties cfgProperties) { - this.cfgProperties = cfgProperties; - } - - @Override - public void prepare(boolean needsAutoCommit) throws SQLException { - serviceRegistry = createServiceRegistry(cfgProperties); - connection = serviceRegistry.getService(ConnectionProvider.class).getConnection(); - if (needsAutoCommit && !connection.getAutoCommit()) { - connection.commit(); - connection.setAutoCommit(true); - } - } - - private static StandardServiceRegistryImpl createServiceRegistry(Properties properties) { - Environment.verifyProperties(properties); - ConfigurationHelper.resolvePlaceHolders(properties); - return (StandardServiceRegistryImpl) new ServiceRegistryBuilder().applySettings(properties).buildServiceRegistry(); - } - - @Override - public Connection getConnection() throws SQLException { - return connection; - } - - @Override - public void release() throws SQLException { - try { - releaseConnection(); - } finally { - releaseServiceRegistry(); - } - } - - private void releaseConnection() throws SQLException { - if (connection != null) { - try { - new SqlExceptionHelper().logAndClearWarnings(connection); - } finally { - try { - serviceRegistry.getService(ConnectionProvider.class).closeConnection(connection); - } finally { - connection = null; - } - } - } - } - - private void releaseServiceRegistry() { - if (serviceRegistry != null) { - try { - serviceRegistry.destroy(); - } finally { - serviceRegistry = null; - } - } - } -} diff --git a/docs-core/src/main/java/com/sismics/util/jpa/SessionUtil.java b/docs-core/src/main/java/com/sismics/util/jpa/SessionUtil.java deleted file mode 100644 index 02e54ba7..00000000 --- a/docs-core/src/main/java/com/sismics/util/jpa/SessionUtil.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.sismics.util.jpa; - -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.hibernate.ejb.HibernateEntityManagerFactory; - -/** - * Hibernate session utilities. - * - * @author jtremeaux - */ -public final class SessionUtil { - /** - * Private constructor. - */ - private SessionUtil() { - } - - /** - * Returns an instance of the current session. - * - * @return Instance of the current session - */ - public static Session getCurrentSession() { - SessionFactory sessionFactory = ((HibernateEntityManagerFactory) EMF.get()).getSessionFactory(); - return sessionFactory.getCurrentSession(); - } -} \ No newline at end of file diff --git a/docs-core/src/main/java/com/sismics/util/jpa/SuppliedConnectionProviderConnectionHelper.java b/docs-core/src/main/java/com/sismics/util/jpa/SuppliedConnectionProviderConnectionHelper.java deleted file mode 100644 index 0da68386..00000000 --- a/docs-core/src/main/java/com/sismics/util/jpa/SuppliedConnectionProviderConnectionHelper.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. - * - * This copyrighted material is made available to anyone wishing to use, modify, - * copy, or redistribute it subject to the terms and conditions of the GNU - * Lesser General Public License, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this distribution; if not, write to: - * Free Software Foundation, Inc. - * 51 Franklin Street, Fifth Floor - * Boston, MA 02110-1301 USA - * - */ - -package com.sismics.util.jpa; - -import org.hibernate.engine.jdbc.spi.SqlExceptionHelper; -import org.hibernate.service.jdbc.connections.spi.ConnectionProvider; -import org.hibernate.tool.hbm2ddl.ConnectionHelper; - -import java.sql.Connection; -import java.sql.SQLException; - -/** - * A {@link ConnectionHelper} implementation based on a provided - * {@link ConnectionProvider}. Essentially, ensures that the connection - * gets cleaned up, but that the provider itself remains usable since it - * was externally provided to us. - * - * @author Steve Ebersole - */ -class SuppliedConnectionProviderConnectionHelper implements ConnectionHelper { - private ConnectionProvider provider; - private Connection connection; - private boolean toggleAutoCommit; - - public SuppliedConnectionProviderConnectionHelper(ConnectionProvider provider) { - this.provider = provider; - } - - @Override - public void prepare(boolean needsAutoCommit) throws SQLException { - connection = provider.getConnection(); - toggleAutoCommit = needsAutoCommit && !connection.getAutoCommit(); - if ( toggleAutoCommit ) { - try { - connection.commit(); - } - catch( Throwable ignore ) { - // might happen with a managed connection - } - connection.setAutoCommit( true ); - } - } - - @Override - public Connection getConnection() throws SQLException { - return connection; - } - - @Override - public void release() throws SQLException { - // we only release the connection - if ( connection != null ) { - new SqlExceptionHelper().logAndClearWarnings( connection ); - if ( toggleAutoCommit ) { - connection.setAutoCommit( false ); - } - provider.closeConnection( connection ); - connection = null; - } - } -} diff --git a/docs-core/src/test/java/com/sismics/docs/core/dao/jpa/TestJpa.java b/docs-core/src/test/java/com/sismics/docs/core/dao/jpa/TestJpa.java index 0dc8d675..8abad9c7 100644 --- a/docs-core/src/test/java/com/sismics/docs/core/dao/jpa/TestJpa.java +++ b/docs-core/src/test/java/com/sismics/docs/core/dao/jpa/TestJpa.java @@ -3,7 +3,7 @@ package com.sismics.docs.core.dao.jpa; import com.sismics.docs.BaseTransactionalTest; import com.sismics.docs.core.model.jpa.User; import com.sismics.docs.core.util.TransactionUtil; -import junit.framework.Assert; +import org.junit.Assert; import org.junit.Test; /** diff --git a/docs-core/src/test/java/com/sismics/docs/core/util/TestEncryptUtil.java b/docs-core/src/test/java/com/sismics/docs/core/util/TestEncryptUtil.java index 39477e5f..68dbbe8b 100644 --- a/docs-core/src/test/java/com/sismics/docs/core/util/TestEncryptUtil.java +++ b/docs-core/src/test/java/com/sismics/docs/core/util/TestEncryptUtil.java @@ -5,8 +5,7 @@ import java.io.InputStream; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; -import junit.framework.Assert; - +import org.junit.Assert; import org.junit.Test; import com.google.common.base.Strings; diff --git a/docs-core/src/test/java/com/sismics/docs/core/util/TestFileUtil.java b/docs-core/src/test/java/com/sismics/docs/core/util/TestFileUtil.java index 7ec18c99..7e04aaf2 100644 --- a/docs-core/src/test/java/com/sismics/docs/core/util/TestFileUtil.java +++ b/docs-core/src/test/java/com/sismics/docs/core/util/TestFileUtil.java @@ -11,7 +11,7 @@ import com.google.common.io.Resources; import com.sismics.docs.core.model.jpa.File; import com.sismics.util.mime.MimeType; -import junit.framework.Assert; +import org.junit.Assert; /** * Test of the file entity utilities. diff --git a/docs-core/src/test/java/com/sismics/util/TestDateUtil.java b/docs-core/src/test/java/com/sismics/util/TestDateUtil.java index 797904b6..4c587881 100644 --- a/docs-core/src/test/java/com/sismics/util/TestDateUtil.java +++ b/docs-core/src/test/java/com/sismics/util/TestDateUtil.java @@ -1,6 +1,6 @@ package com.sismics.util; -import junit.framework.Assert; +import org.junit.Assert; import org.junit.Test; /** diff --git a/docs-core/src/test/java/com/sismics/util/TestImageUtil.java b/docs-core/src/test/java/com/sismics/util/TestImageUtil.java index d6c62703..6d980aaa 100644 --- a/docs-core/src/test/java/com/sismics/util/TestImageUtil.java +++ b/docs-core/src/test/java/com/sismics/util/TestImageUtil.java @@ -1,6 +1,6 @@ package com.sismics.util; -import junit.framework.Assert; +import org.junit.Assert; import org.junit.Test; /** diff --git a/docs-core/src/test/java/com/sismics/util/TestResourceUtil.java b/docs-core/src/test/java/com/sismics/util/TestResourceUtil.java index c780dcf6..10518fc4 100644 --- a/docs-core/src/test/java/com/sismics/util/TestResourceUtil.java +++ b/docs-core/src/test/java/com/sismics/util/TestResourceUtil.java @@ -1,6 +1,6 @@ package com.sismics.util; -import junit.framework.Assert; +import org.junit.Assert; import org.junit.Test; import java.util.List; diff --git a/docs-core/src/test/resources/hibernate.properties b/docs-core/src/test/resources/hibernate.properties index edd32f92..2c068af9 100644 --- a/docs-core/src/test/resources/hibernate.properties +++ b/docs-core/src/test/resources/hibernate.properties @@ -2,9 +2,13 @@ hibernate.connection.driver_class=org.h2.Driver hibernate.connection.url=jdbc:h2:mem:docs hibernate.connection.username=sa hibernate.connection.password= -hibernate.hbm2ddl.auto=none +hibernate.hbm2ddl.auto= hibernate.dialect=org.hibernate.dialect.HSQLDialect hibernate.show_sql=true hibernate.format_sql=false hibernate.max_fetch_depth=5 hibernate.cache.use_second_level_cache=false +hibernate.c3p0.min_size=1 +hibernate.c3p0.max_size=10 +hibernate.c3p0.timeout=0 +hibernate.c3p0.max_statements=0 \ No newline at end of file diff --git a/docs-parent/pom.xml b/docs-parent/pom.xml index 7dbec5a4..30badbc7 100644 --- a/docs-parent/pom.xml +++ b/docs-parent/pom.xml @@ -20,20 +20,20 @@ 2.6 2.4 1.4 - 18.0 + 19.0 1.2.16 1.6.4 1.6.6 - 4.7 - 1.4.190 + 4.12 + 1.4.191 2.22.1 0.3m 4.2.0 4.2 - 2.0.0-RC2 - 1.53 + 2.0.0-RC3 + 1.54 2.9.1 - 4.1.0.Final + 5.0.7.Final 3.1.0 1.0.5 4.2.1 @@ -48,11 +48,10 @@ 1.8 2.10 - 2.4 - 2.5.2 + 2.6 2.7 2.6 - 2.18.1 + 2.19.1 9.2.13.v20150730 @@ -306,7 +305,7 @@ org.hibernate - hibernate-validator + hibernate-c3p0 ${org.hibernate.hibernate.version} diff --git a/docs-stress/src/main/java/com/sismics/docs/stress/Main.java b/docs-stress/src/main/java/com/sismics/docs/stress/Main.java index 788af740..6ee460ef 100644 --- a/docs-stress/src/main/java/com/sismics/docs/stress/Main.java +++ b/docs-stress/src/main/java/com/sismics/docs/stress/Main.java @@ -17,7 +17,7 @@ import javax.ws.rs.core.Form; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response.Status; -import junit.framework.Assert; +import org.junit.Assert; import org.glassfish.jersey.client.ClientResponse; import org.glassfish.jersey.media.multipart.FormDataMultiPart; diff --git a/docs-web-common/src/test/java/com/sismics/docs/rest/util/TestValidationUtil.java b/docs-web-common/src/test/java/com/sismics/docs/rest/util/TestValidationUtil.java index 4d5a289a..d9eb4cc5 100644 --- a/docs-web-common/src/test/java/com/sismics/docs/rest/util/TestValidationUtil.java +++ b/docs-web-common/src/test/java/com/sismics/docs/rest/util/TestValidationUtil.java @@ -2,7 +2,7 @@ package com.sismics.docs.rest.util; import com.sismics.rest.exception.ClientException; import com.sismics.rest.util.ValidationUtil; -import junit.framework.Assert; +import org.junit.Assert; import org.junit.Test; /** diff --git a/docs-web/pom.xml b/docs-web/pom.xml index 744c698e..048cc060 100644 --- a/docs-web/pom.xml +++ b/docs-web/pom.xml @@ -88,7 +88,7 @@ com.twelvemonkeys.servlet servlet - + com.sismics.docs diff --git a/docs-web/src/dev/resources/hibernate.properties b/docs-web/src/dev/resources/hibernate.properties index 0f7dfbdd..7e4efc32 100644 --- a/docs-web/src/dev/resources/hibernate.properties +++ b/docs-web/src/dev/resources/hibernate.properties @@ -2,9 +2,13 @@ hibernate.connection.driver_class=org.h2.Driver hibernate.connection.url=jdbc:h2:mem:docs hibernate.connection.username=sa hibernate.connection.password= -hibernate.hbm2ddl.auto=none +hibernate.hbm2ddl.auto= hibernate.dialect=org.hibernate.dialect.HSQLDialect hibernate.show_sql=false hibernate.format_sql=false hibernate.max_fetch_depth=5 hibernate.cache.use_second_level_cache=false +hibernate.c3p0.min_size=1 +hibernate.c3p0.max_size=10 +hibernate.c3p0.timeout=0 +hibernate.c3p0.max_statements=0 \ No newline at end of file diff --git a/docs-web/src/main/webapp/src/style/bootstrap.css b/docs-web/src/main/webapp/src/style/bootstrap.css index 6d772357..3d6b3daa 100644 --- a/docs-web/src/main/webapp/src/style/bootstrap.css +++ b/docs-web/src/main/webapp/src/style/bootstrap.css @@ -1,13 +1,3 @@ -/*! - * Bootstrap v3.3.5 (http://getbootstrap.com) - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */ - -/*! - * Generated using the Bootstrap Customizer (http://getbootstrap.com/customize/?id=cd406b52370309d5bcbd) - * Config saved to config.json and https://gist.github.com/cd406b52370309d5bcbd - */ /*! * Bootstrap v3.3.6 (http://getbootstrap.com) * Copyright 2011-2015 Twitter, Inc. @@ -16,8 +6,8 @@ /*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ html { font-family: sans-serif; - -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; } body { margin: 0; @@ -70,28 +60,28 @@ dfn { font-style: italic; } h1 { + margin: .67em 0; font-size: 2em; - margin: 0.67em 0; } mark { - background: #ff0; color: #000; + background: #ff0; } small { font-size: 80%; } sub, sup { + position: relative; font-size: 75%; line-height: 0; - position: relative; vertical-align: baseline; } sup { - top: -0.5em; + top: -.5em; } sub { - bottom: -0.25em; + bottom: -.25em; } img { border: 0; @@ -103,10 +93,10 @@ figure { margin: 1em 40px; } hr { + height: 0; -webkit-box-sizing: content-box; -moz-box-sizing: content-box; box-sizing: content-box; - height: 0; } pre { overflow: auto; @@ -123,9 +113,9 @@ input, optgroup, select, textarea { - color: inherit; - font: inherit; margin: 0; + font: inherit; + color: inherit; } button { overflow: visible; @@ -147,8 +137,8 @@ html input[disabled] { } button::-moz-focus-inner, input::-moz-focus-inner { - border: 0; padding: 0; + border: 0; } input { line-height: normal; @@ -165,23 +155,23 @@ input[type="number"]::-webkit-outer-spin-button { height: auto; } input[type="search"] { - -webkit-appearance: textfield; -webkit-box-sizing: content-box; -moz-box-sizing: content-box; box-sizing: content-box; + -webkit-appearance: textfield; } input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; } fieldset { - border: 1px solid #c0c0c0; + padding: .35em .625em .75em; margin: 0 2px; - padding: 0.35em 0.625em 0.75em; + border: 1px solid #c0c0c0; } legend { - border: 0; padding: 0; + border: 0; } textarea { overflow: auto; @@ -190,8 +180,8 @@ optgroup { font-weight: bold; } table { - border-collapse: collapse; border-spacing: 0; + border-collapse: collapse; } td, th { @@ -202,11 +192,11 @@ th { *, *:before, *:after { - background: transparent !important; color: #000 !important; + text-shadow: none !important; + background: transparent !important; -webkit-box-shadow: none !important; box-shadow: none !important; - text-shadow: none !important; } a, a:visited { @@ -225,6 +215,7 @@ th { pre, blockquote { border: 1px solid #999; + page-break-inside: avoid; } thead { @@ -271,6 +262,7 @@ th { } @font-face { font-family: 'Glyphicons Halflings'; + src: url('../fonts/glyphicons-halflings-regular.eot'); src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg'); } @@ -282,6 +274,7 @@ th { font-style: normal; font-weight: normal; line-height: 1; + -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } @@ -1074,25 +1067,26 @@ th { } * { -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; } *:before, *:after { -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; } html { font-size: 10px; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } body { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; line-height: 1.42857143; - color: #333333; - background-color: #ffffff; + color: #333; + background-color: #fff; } input, button, @@ -1135,17 +1129,17 @@ img { border-radius: 6px; } .img-thumbnail { - padding: 4px; - line-height: 1.42857143; - background-color: #ffffff; - border: 1px solid #dddddd; - border-radius: 4px; - -webkit-transition: all 0.2s ease-in-out; - -o-transition: all 0.2s ease-in-out; - transition: all 0.2s ease-in-out; display: inline-block; max-width: 100%; height: auto; + padding: 4px; + line-height: 1.42857143; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 4px; + -webkit-transition: all .2s ease-in-out; + -o-transition: all .2s ease-in-out; + transition: all .2s ease-in-out; } .img-circle { border-radius: 50%; @@ -1154,14 +1148,14 @@ hr { margin-top: 20px; margin-bottom: 20px; border: 0; - border-top: 1px solid #eeeeee; + border-top: 1px solid #eee; } .sr-only { position: absolute; width: 1px; height: 1px; - margin: -1px; padding: 0; + margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); border: 0; @@ -1221,7 +1215,7 @@ h6 .small, .h6 .small { font-weight: normal; line-height: 1; - color: #777777; + color: #777; } h1, .h1, @@ -1313,8 +1307,8 @@ small, } mark, .mark { - background-color: #fcf8e3; padding: .2em; + background-color: #fcf8e3; } .text-left { text-align: left; @@ -1341,7 +1335,7 @@ mark, text-transform: capitalize; } .text-muted { - color: #777777; + color: #777; } .text-primary { color: #337ab7; @@ -1417,7 +1411,7 @@ a.bg-danger:focus { .page-header { padding-bottom: 9px; margin: 40px 0 20px; - border-bottom: 1px solid #eeeeee; + border-bottom: 1px solid #eee; } ul, ol { @@ -1436,13 +1430,13 @@ ol ol { } .list-inline { padding-left: 0; - list-style: none; margin-left: -5px; + list-style: none; } .list-inline > li { display: inline-block; - padding-left: 5px; padding-right: 5px; + padding-left: 5px; } dl { margin-top: 0; @@ -1462,9 +1456,9 @@ dd { .dl-horizontal dt { float: left; width: 160px; + overflow: hidden; clear: left; text-align: right; - overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } @@ -1475,7 +1469,7 @@ dd { abbr[title], abbr[data-original-title] { cursor: help; - border-bottom: 1px dotted #777777; + border-bottom: 1px dotted #777; } .initialism { font-size: 90%; @@ -1485,7 +1479,7 @@ blockquote { padding: 10px 20px; margin: 0 0 20px; font-size: 17.5px; - border-left: 5px solid #eeeeee; + border-left: 5px solid #eee; } blockquote p:last-child, blockquote ul:last-child, @@ -1498,7 +1492,7 @@ blockquote .small { display: block; font-size: 80%; line-height: 1.42857143; - color: #777777; + color: #777; } blockquote footer:before, blockquote small:before, @@ -1509,9 +1503,9 @@ blockquote .small:before { blockquote.pull-right { padding-right: 15px; padding-left: 0; - border-right: 5px solid #eeeeee; - border-left: 0; text-align: right; + border-right: 5px solid #eee; + border-left: 0; } .blockquote-reverse footer:before, blockquote.pull-right footer:before, @@ -1550,11 +1544,11 @@ code { kbd { padding: 2px 4px; font-size: 90%; - color: #ffffff; - background-color: #333333; + color: #fff; + background-color: #333; border-radius: 3px; - -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25); - box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25); + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25); } kbd kbd { padding: 0; @@ -1569,11 +1563,11 @@ pre { margin: 0 0 10px; font-size: 13px; line-height: 1.42857143; + color: #333; word-break: break-all; word-wrap: break-word; - color: #333333; background-color: #f5f5f5; - border: 1px solid #cccccc; + border: 1px solid #ccc; border-radius: 4px; } pre code { @@ -1589,10 +1583,10 @@ pre code { overflow-y: scroll; } .container { + padding-right: 15px; + padding-left: 15px; margin-right: auto; margin-left: auto; - padding-left: 15px; - padding-right: 15px; } @media (min-width: 768px) { .container { @@ -1610,20 +1604,20 @@ pre code { } } .container-fluid { + padding-right: 15px; + padding-left: 15px; margin-right: auto; margin-left: auto; - padding-left: 15px; - padding-right: 15px; } .row { - margin-left: -15px; margin-right: -15px; + margin-left: -15px; } .col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { position: relative; min-height: 1px; - padding-left: 15px; padding-right: 15px; + padding-left: 15px; } .col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { float: left; @@ -1779,7 +1773,7 @@ pre code { margin-left: 8.33333333%; } .col-xs-offset-0 { - margin-left: 0%; + margin-left: 0; } @media (min-width: 768px) { .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { @@ -1936,7 +1930,7 @@ pre code { margin-left: 8.33333333%; } .col-sm-offset-0 { - margin-left: 0%; + margin-left: 0; } } @media (min-width: 992px) { @@ -2094,7 +2088,7 @@ pre code { margin-left: 8.33333333%; } .col-md-offset-0 { - margin-left: 0%; + margin-left: 0; } } @media (min-width: 1200px) { @@ -2252,7 +2246,7 @@ pre code { margin-left: 8.33333333%; } .col-lg-offset-0 { - margin-left: 0%; + margin-left: 0; } } table { @@ -2261,7 +2255,7 @@ table { caption { padding-top: 8px; padding-bottom: 8px; - color: #777777; + color: #777; text-align: left; } th { @@ -2281,11 +2275,11 @@ th { padding: 8px; line-height: 1.42857143; vertical-align: top; - border-top: 1px solid #dddddd; + border-top: 1px solid #ddd; } .table > thead > tr > th { vertical-align: bottom; - border-bottom: 2px solid #dddddd; + border-bottom: 2px solid #ddd; } .table > caption + thead > tr:first-child > th, .table > colgroup + thead > tr:first-child > th, @@ -2296,10 +2290,10 @@ th { border-top: 0; } .table > tbody + tbody { - border-top: 2px solid #dddddd; + border-top: 2px solid #ddd; } .table .table { - background-color: #ffffff; + background-color: #fff; } .table-condensed > thead > tr > th, .table-condensed > tbody > tr > th, @@ -2310,7 +2304,7 @@ th { padding: 5px; } .table-bordered { - border: 1px solid #dddddd; + border: 1px solid #ddd; } .table-bordered > thead > tr > th, .table-bordered > tbody > tr > th, @@ -2318,7 +2312,7 @@ th { .table-bordered > thead > tr > td, .table-bordered > tbody > tr > td, .table-bordered > tfoot > tr > td { - border: 1px solid #dddddd; + border: 1px solid #ddd; } .table-bordered > thead > tr > th, .table-bordered > thead > tr > td { @@ -2332,14 +2326,14 @@ th { } table col[class*="col-"] { position: static; - float: none; display: table-column; + float: none; } table td[class*="col-"], table th[class*="col-"] { position: static; - float: none; display: table-cell; + float: none; } .table > thead > tr > td.active, .table > tbody > tr > td.active, @@ -2447,8 +2441,8 @@ table th[class*="col-"] { background-color: #ebcccc; } .table-responsive { + min-height: .01%; overflow-x: auto; - min-height: 0.01%; } @media screen and (max-width: 767px) { .table-responsive { @@ -2456,7 +2450,7 @@ table th[class*="col-"] { margin-bottom: 15px; overflow-y: hidden; -ms-overflow-style: -ms-autohiding-scrollbar; - border: 1px solid #dddddd; + border: 1px solid #ddd; } .table-responsive > .table { margin-bottom: 0; @@ -2496,10 +2490,10 @@ table th[class*="col-"] { } } fieldset { + min-width: 0; padding: 0; margin: 0; border: 0; - min-width: 0; } legend { display: block; @@ -2508,7 +2502,7 @@ legend { margin-bottom: 20px; font-size: 21px; line-height: inherit; - color: #333333; + color: #333; border: 0; border-bottom: 1px solid #e5e5e5; } @@ -2520,8 +2514,8 @@ label { } input[type="search"] { -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; } input[type="radio"], input[type="checkbox"] { @@ -2552,7 +2546,7 @@ output { padding-top: 7px; font-size: 14px; line-height: 1.42857143; - color: #555555; + color: #555; } .form-control { display: block; @@ -2561,41 +2555,41 @@ output { padding: 6px 12px; font-size: 14px; line-height: 1.42857143; - color: #555555; - background-color: #ffffff; + color: #555; + background-color: #fff; background-image: none; - border: 1px solid #cccccc; + border: 1px solid #ccc; border-radius: 4px; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s; - -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; - transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; } .form-control:focus { border-color: #66afe9; outline: 0; - -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); - box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6); } .form-control::-moz-placeholder { - color: #999999; + color: #999; opacity: 1; } .form-control:-ms-input-placeholder { - color: #999999; + color: #999; } .form-control::-webkit-input-placeholder { - color: #999999; + color: #999; } .form-control::-ms-expand { - border: 0; background-color: transparent; + border: 0; } .form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control { - background-color: #eeeeee; + background-color: #eee; opacity: 1; } .form-control[disabled], @@ -2659,8 +2653,8 @@ input[type="search"] { .checkbox input[type="checkbox"], .checkbox-inline input[type="checkbox"] { position: absolute; - margin-left: -20px; margin-top: 4px \9; + margin-left: -20px; } .radio + .radio, .checkbox + .checkbox { @@ -2672,8 +2666,8 @@ input[type="search"] { display: inline-block; padding-left: 20px; margin-bottom: 0; - vertical-align: middle; font-weight: normal; + vertical-align: middle; cursor: pointer; } .radio-inline + .radio-inline, @@ -2702,15 +2696,15 @@ fieldset[disabled] .checkbox label { cursor: not-allowed; } .form-control-static { + min-height: 34px; padding-top: 7px; padding-bottom: 7px; margin-bottom: 0; - min-height: 34px; } .form-control-static.input-lg, .form-control-static.input-sm { - padding-left: 0; padding-right: 0; + padding-left: 0; } .input-sm { height: 30px; @@ -2832,18 +2826,18 @@ select[multiple].input-lg { } .has-success .form-control { border-color: #3c763d; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); } .has-success .form-control:focus { border-color: #2b542c; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168; } .has-success .input-group-addon { color: #3c763d; - border-color: #3c763d; background-color: #dff0d8; + border-color: #3c763d; } .has-success .form-control-feedback { color: #3c763d; @@ -2862,18 +2856,18 @@ select[multiple].input-lg { } .has-warning .form-control { border-color: #8a6d3b; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); } .has-warning .form-control:focus { border-color: #66512c; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b; } .has-warning .input-group-addon { color: #8a6d3b; - border-color: #8a6d3b; background-color: #fcf8e3; + border-color: #8a6d3b; } .has-warning .form-control-feedback { color: #8a6d3b; @@ -2892,18 +2886,18 @@ select[multiple].input-lg { } .has-error .form-control { border-color: #a94442; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); } .has-error .form-control:focus { border-color: #843534; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483; } .has-error .input-group-addon { color: #a94442; - border-color: #a94442; background-color: #f2dede; + border-color: #a94442; } .has-error .form-control-feedback { color: #a94442; @@ -2974,23 +2968,23 @@ select[multiple].input-lg { .form-horizontal .checkbox, .form-horizontal .radio-inline, .form-horizontal .checkbox-inline { + padding-top: 7px; margin-top: 0; margin-bottom: 0; - padding-top: 7px; } .form-horizontal .radio, .form-horizontal .checkbox { min-height: 27px; } .form-horizontal .form-group { - margin-left: -15px; margin-right: -15px; + margin-left: -15px; } @media (min-width: 768px) { .form-horizontal .control-label { - text-align: right; - margin-bottom: 0; padding-top: 7px; + margin-bottom: 0; + text-align: right; } } .form-horizontal .has-feedback .form-control-feedback { @@ -3010,24 +3004,24 @@ select[multiple].input-lg { } .btn { display: inline-block; + padding: 6px 12px; margin-bottom: 0; + font-size: 14px; font-weight: normal; + line-height: 1.42857143; text-align: center; + white-space: nowrap; vertical-align: middle; -ms-touch-action: manipulation; touch-action: manipulation; cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; background-image: none; border: 1px solid transparent; - white-space: nowrap; - padding: 6px 12px; - font-size: 14px; - line-height: 1.42857143; border-radius: 4px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; } .btn:focus, .btn:active:focus, @@ -3042,49 +3036,49 @@ select[multiple].input-lg { .btn:hover, .btn:focus, .btn.focus { - color: #333333; + color: #333; text-decoration: none; } .btn:active, .btn.active { - outline: 0; background-image: none; - -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + outline: 0; + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); } .btn.disabled, .btn[disabled], fieldset[disabled] .btn { cursor: not-allowed; - opacity: 0.65; filter: alpha(opacity=65); -webkit-box-shadow: none; - box-shadow: none; + box-shadow: none; + opacity: .65; } a.btn.disabled, fieldset[disabled] a.btn { pointer-events: none; } .btn-default { - color: #333333; - background-color: #ffffff; - border-color: #cccccc; + color: #333; + background-color: #fff; + border-color: #ccc; } .btn-default:focus, .btn-default.focus { - color: #333333; + color: #333; background-color: #e6e6e6; border-color: #8c8c8c; } .btn-default:hover { - color: #333333; + color: #333; background-color: #e6e6e6; border-color: #adadad; } .btn-default:active, .btn-default.active, .open > .dropdown-toggle.btn-default { - color: #333333; + color: #333; background-color: #e6e6e6; border-color: #adadad; } @@ -3097,7 +3091,7 @@ fieldset[disabled] a.btn { .btn-default:active.focus, .btn-default.active.focus, .open > .dropdown-toggle.btn-default.focus { - color: #333333; + color: #333; background-color: #d4d4d4; border-color: #8c8c8c; } @@ -3115,33 +3109,33 @@ fieldset[disabled] .btn-default:focus, .btn-default.disabled.focus, .btn-default[disabled].focus, fieldset[disabled] .btn-default.focus { - background-color: #ffffff; - border-color: #cccccc; + background-color: #fff; + border-color: #ccc; } .btn-default .badge { - color: #ffffff; - background-color: #333333; + color: #fff; + background-color: #333; } .btn-primary { - color: #ffffff; + color: #fff; background-color: #337ab7; border-color: #2e6da4; } .btn-primary:focus, .btn-primary.focus { - color: #ffffff; + color: #fff; background-color: #286090; border-color: #122b40; } .btn-primary:hover { - color: #ffffff; + color: #fff; background-color: #286090; border-color: #204d74; } .btn-primary:active, .btn-primary.active, .open > .dropdown-toggle.btn-primary { - color: #ffffff; + color: #fff; background-color: #286090; border-color: #204d74; } @@ -3154,7 +3148,7 @@ fieldset[disabled] .btn-default.focus { .btn-primary:active.focus, .btn-primary.active.focus, .open > .dropdown-toggle.btn-primary.focus { - color: #ffffff; + color: #fff; background-color: #204d74; border-color: #122b40; } @@ -3177,28 +3171,28 @@ fieldset[disabled] .btn-primary.focus { } .btn-primary .badge { color: #337ab7; - background-color: #ffffff; + background-color: #fff; } .btn-success { - color: #ffffff; + color: #fff; background-color: #5cb85c; border-color: #4cae4c; } .btn-success:focus, .btn-success.focus { - color: #ffffff; + color: #fff; background-color: #449d44; border-color: #255625; } .btn-success:hover { - color: #ffffff; + color: #fff; background-color: #449d44; border-color: #398439; } .btn-success:active, .btn-success.active, .open > .dropdown-toggle.btn-success { - color: #ffffff; + color: #fff; background-color: #449d44; border-color: #398439; } @@ -3211,7 +3205,7 @@ fieldset[disabled] .btn-primary.focus { .btn-success:active.focus, .btn-success.active.focus, .open > .dropdown-toggle.btn-success.focus { - color: #ffffff; + color: #fff; background-color: #398439; border-color: #255625; } @@ -3234,28 +3228,28 @@ fieldset[disabled] .btn-success.focus { } .btn-success .badge { color: #5cb85c; - background-color: #ffffff; + background-color: #fff; } .btn-info { - color: #ffffff; + color: #fff; background-color: #5bc0de; border-color: #46b8da; } .btn-info:focus, .btn-info.focus { - color: #ffffff; + color: #fff; background-color: #31b0d5; border-color: #1b6d85; } .btn-info:hover { - color: #ffffff; + color: #fff; background-color: #31b0d5; border-color: #269abc; } .btn-info:active, .btn-info.active, .open > .dropdown-toggle.btn-info { - color: #ffffff; + color: #fff; background-color: #31b0d5; border-color: #269abc; } @@ -3268,7 +3262,7 @@ fieldset[disabled] .btn-success.focus { .btn-info:active.focus, .btn-info.active.focus, .open > .dropdown-toggle.btn-info.focus { - color: #ffffff; + color: #fff; background-color: #269abc; border-color: #1b6d85; } @@ -3291,28 +3285,28 @@ fieldset[disabled] .btn-info.focus { } .btn-info .badge { color: #5bc0de; - background-color: #ffffff; + background-color: #fff; } .btn-warning { - color: #ffffff; + color: #fff; background-color: #f0ad4e; border-color: #eea236; } .btn-warning:focus, .btn-warning.focus { - color: #ffffff; + color: #fff; background-color: #ec971f; border-color: #985f0d; } .btn-warning:hover { - color: #ffffff; + color: #fff; background-color: #ec971f; border-color: #d58512; } .btn-warning:active, .btn-warning.active, .open > .dropdown-toggle.btn-warning { - color: #ffffff; + color: #fff; background-color: #ec971f; border-color: #d58512; } @@ -3325,7 +3319,7 @@ fieldset[disabled] .btn-info.focus { .btn-warning:active.focus, .btn-warning.active.focus, .open > .dropdown-toggle.btn-warning.focus { - color: #ffffff; + color: #fff; background-color: #d58512; border-color: #985f0d; } @@ -3348,28 +3342,28 @@ fieldset[disabled] .btn-warning.focus { } .btn-warning .badge { color: #f0ad4e; - background-color: #ffffff; + background-color: #fff; } .btn-danger { - color: #ffffff; + color: #fff; background-color: #d9534f; border-color: #d43f3a; } .btn-danger:focus, .btn-danger.focus { - color: #ffffff; + color: #fff; background-color: #c9302c; border-color: #761c19; } .btn-danger:hover { - color: #ffffff; + color: #fff; background-color: #c9302c; border-color: #ac2925; } .btn-danger:active, .btn-danger.active, .open > .dropdown-toggle.btn-danger { - color: #ffffff; + color: #fff; background-color: #c9302c; border-color: #ac2925; } @@ -3382,7 +3376,7 @@ fieldset[disabled] .btn-warning.focus { .btn-danger:active.focus, .btn-danger.active.focus, .open > .dropdown-toggle.btn-danger.focus { - color: #ffffff; + color: #fff; background-color: #ac2925; border-color: #761c19; } @@ -3405,11 +3399,11 @@ fieldset[disabled] .btn-danger.focus { } .btn-danger .badge { color: #d9534f; - background-color: #ffffff; + background-color: #fff; } .btn-link { - color: #337ab7; font-weight: normal; + color: #337ab7; border-radius: 0; } .btn-link, @@ -3419,7 +3413,7 @@ fieldset[disabled] .btn-danger.focus { fieldset[disabled] .btn-link { background-color: transparent; -webkit-box-shadow: none; - box-shadow: none; + box-shadow: none; } .btn-link, .btn-link:hover, @@ -3437,7 +3431,7 @@ fieldset[disabled] .btn-link { fieldset[disabled] .btn-link:hover, .btn-link[disabled]:focus, fieldset[disabled] .btn-link:focus { - color: #777777; + color: #777; text-decoration: none; } .btn-lg, @@ -3475,9 +3469,9 @@ input[type="button"].btn-block { } .fade { opacity: 0; - -webkit-transition: opacity 0.15s linear; - -o-transition: opacity 0.15s linear; - transition: opacity 0.15s linear; + -webkit-transition: opacity .15s linear; + -o-transition: opacity .15s linear; + transition: opacity .15s linear; } .fade.in { opacity: 1; @@ -3498,15 +3492,15 @@ tbody.collapse.in { position: relative; height: 0; overflow: hidden; - -webkit-transition-property: height, visibility; - -o-transition-property: height, visibility; - transition-property: height, visibility; - -webkit-transition-duration: 0.35s; - -o-transition-duration: 0.35s; - transition-duration: 0.35s; -webkit-transition-timing-function: ease; - -o-transition-timing-function: ease; - transition-timing-function: ease; + -o-transition-timing-function: ease; + transition-timing-function: ease; + -webkit-transition-duration: .35s; + -o-transition-duration: .35s; + transition-duration: .35s; + -webkit-transition-property: height, visibility; + -o-transition-property: height, visibility; + transition-property: height, visibility; } .caret { display: inline-block; @@ -3536,17 +3530,17 @@ tbody.collapse.in { min-width: 160px; padding: 5px 0; margin: 2px 0 0; - list-style: none; font-size: 14px; text-align: left; - background-color: #ffffff; - border: 1px solid #cccccc; - border: 1px solid rgba(0, 0, 0, 0.15); - border-radius: 4px; - -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); - box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + list-style: none; + background-color: #fff; -webkit-background-clip: padding-box; background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, .15); + border-radius: 4px; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175); + box-shadow: 0 6px 12px rgba(0, 0, 0, .175); } .dropdown-menu.pull-right { right: 0; @@ -3564,35 +3558,35 @@ tbody.collapse.in { clear: both; font-weight: normal; line-height: 1.42857143; - color: #333333; + color: #333; white-space: nowrap; } .dropdown-menu > li > a:hover, .dropdown-menu > li > a:focus { - text-decoration: none; color: #262626; + text-decoration: none; background-color: #f5f5f5; } .dropdown-menu > .active > a, .dropdown-menu > .active > a:hover, .dropdown-menu > .active > a:focus { - color: #ffffff; + color: #fff; text-decoration: none; - outline: 0; background-color: #337ab7; + outline: 0; } .dropdown-menu > .disabled > a, .dropdown-menu > .disabled > a:hover, .dropdown-menu > .disabled > a:focus { - color: #777777; + color: #777; } .dropdown-menu > .disabled > a:hover, .dropdown-menu > .disabled > a:focus { text-decoration: none; + cursor: not-allowed; background-color: transparent; background-image: none; filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - cursor: not-allowed; } .open > .dropdown-menu { display: block; @@ -3601,27 +3595,27 @@ tbody.collapse.in { outline: 0; } .dropdown-menu-right { - left: auto; right: 0; + left: auto; } .dropdown-menu-left { - left: 0; right: auto; + left: 0; } .dropdown-header { display: block; padding: 3px 20px; font-size: 12px; line-height: 1.42857143; - color: #777777; + color: #777; white-space: nowrap; } .dropdown-backdrop { position: fixed; - left: 0; + top: 0; right: 0; bottom: 0; - top: 0; + left: 0; z-index: 990; } .pull-right > .dropdown-menu { @@ -3630,10 +3624,10 @@ tbody.collapse.in { } .dropup .caret, .navbar-fixed-bottom .dropdown .caret { + content: ""; border-top: 0; border-bottom: 4px dashed; border-bottom: 4px solid \9; - content: ""; } .dropup .dropdown-menu, .navbar-fixed-bottom .dropdown .dropdown-menu { @@ -3643,12 +3637,12 @@ tbody.collapse.in { } @media (min-width: 768px) { .navbar-right .dropdown-menu { - left: auto; right: 0; + left: auto; } .navbar-right .dropdown-menu-left { - left: 0; right: auto; + left: 0; } } .btn-group, @@ -3698,13 +3692,13 @@ tbody.collapse.in { margin-left: 0; } .btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { - border-bottom-right-radius: 0; border-top-right-radius: 0; + border-bottom-right-radius: 0; } .btn-group > .btn:last-child:not(:first-child), .btn-group > .dropdown-toggle:not(:first-child) { - border-bottom-left-radius: 0; border-top-left-radius: 0; + border-bottom-left-radius: 0; } .btn-group > .btn-group { float: left; @@ -3714,32 +3708,32 @@ tbody.collapse.in { } .btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child, .btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle { - border-bottom-right-radius: 0; border-top-right-radius: 0; + border-bottom-right-radius: 0; } .btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { - border-bottom-left-radius: 0; border-top-left-radius: 0; + border-bottom-left-radius: 0; } .btn-group .dropdown-toggle:active, .btn-group.open .dropdown-toggle { outline: 0; } .btn-group > .btn + .dropdown-toggle { - padding-left: 8px; padding-right: 8px; + padding-left: 8px; } .btn-group > .btn-lg + .dropdown-toggle { - padding-left: 12px; padding-right: 12px; + padding-left: 12px; } .btn-group.open .dropdown-toggle { - -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); } .btn-group.open .dropdown-toggle.btn-link { -webkit-box-shadow: none; - box-shadow: none; + box-shadow: none; } .btn .caret { margin-left: 0; @@ -3773,14 +3767,14 @@ tbody.collapse.in { border-radius: 0; } .btn-group-vertical > .btn:first-child:not(:last-child) { - border-top-right-radius: 4px; border-top-left-radius: 4px; + border-top-right-radius: 4px; border-bottom-right-radius: 0; border-bottom-left-radius: 0; } .btn-group-vertical > .btn:last-child:not(:first-child) { - border-top-right-radius: 0; border-top-left-radius: 0; + border-top-right-radius: 0; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; } @@ -3793,8 +3787,8 @@ tbody.collapse.in { border-bottom-left-radius: 0; } .btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { - border-top-right-radius: 0; border-top-left-radius: 0; + border-top-right-radius: 0; } .btn-group-justified { display: table; @@ -3804,8 +3798,8 @@ tbody.collapse.in { } .btn-group-justified > .btn, .btn-group-justified > .btn-group { - float: none; display: table-cell; + float: none; width: 1%; } .btn-group-justified > .btn-group .btn { @@ -3829,8 +3823,8 @@ tbody.collapse.in { } .input-group[class*="col-"] { float: none; - padding-left: 0; padding-right: 0; + padding-left: 0; } .input-group .form-control { position: relative; @@ -3909,10 +3903,10 @@ select[multiple].input-group-sm > .input-group-btn > .btn { font-size: 14px; font-weight: normal; line-height: 1; - color: #555555; + color: #555; text-align: center; - background-color: #eeeeee; - border: 1px solid #cccccc; + background-color: #eee; + border: 1px solid #ccc; border-radius: 4px; } .input-group-addon.input-sm { @@ -3936,8 +3930,8 @@ select[multiple].input-group-sm > .input-group-btn > .btn { .input-group-btn:first-child > .dropdown-toggle, .input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle), .input-group-btn:last-child > .btn-group:not(:last-child) > .btn { - border-bottom-right-radius: 0; border-top-right-radius: 0; + border-bottom-right-radius: 0; } .input-group-addon:first-child { border-right: 0; @@ -3949,8 +3943,8 @@ select[multiple].input-group-sm > .input-group-btn > .btn { .input-group-btn:last-child > .dropdown-toggle, .input-group-btn:first-child > .btn:not(:first-child), .input-group-btn:first-child > .btn-group:not(:first-child) > .btn { - border-bottom-left-radius: 0; border-top-left-radius: 0; + border-bottom-left-radius: 0; } .input-group-addon:last-child { border-left: 0; @@ -3981,8 +3975,8 @@ select[multiple].input-group-sm > .input-group-btn > .btn { margin-left: -1px; } .nav { - margin-bottom: 0; padding-left: 0; + margin-bottom: 0; list-style: none; } .nav > li { @@ -3997,22 +3991,22 @@ select[multiple].input-group-sm > .input-group-btn > .btn { .nav > li > a:hover, .nav > li > a:focus { text-decoration: none; - background-color: #eeeeee; + background-color: #eee; } .nav > li.disabled > a { - color: #777777; + color: #777; } .nav > li.disabled > a:hover, .nav > li.disabled > a:focus { - color: #777777; + color: #777; text-decoration: none; - background-color: transparent; cursor: not-allowed; + background-color: transparent; } .nav .open > a, .nav .open > a:hover, .nav .open > a:focus { - background-color: #eeeeee; + background-color: #eee; border-color: #337ab7; } .nav .nav-divider { @@ -4025,7 +4019,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn { max-width: none; } .nav-tabs { - border-bottom: 1px solid #dddddd; + border-bottom: 1px solid #ddd; } .nav-tabs > li { float: left; @@ -4038,16 +4032,16 @@ select[multiple].input-group-sm > .input-group-btn > .btn { border-radius: 4px 4px 0 0; } .nav-tabs > li > a:hover { - border-color: #eeeeee #eeeeee #dddddd; + border-color: #eee #eee #ddd; } .nav-tabs > li.active > a, .nav-tabs > li.active > a:hover, .nav-tabs > li.active > a:focus { - color: #555555; - background-color: #ffffff; - border: 1px solid #dddddd; - border-bottom-color: transparent; + color: #555; cursor: default; + background-color: #fff; + border: 1px solid #ddd; + border-bottom-color: transparent; } .nav-tabs.nav-justified { width: 100%; @@ -4057,8 +4051,8 @@ select[multiple].input-group-sm > .input-group-btn > .btn { float: none; } .nav-tabs.nav-justified > li > a { - text-align: center; margin-bottom: 5px; + text-align: center; } .nav-tabs.nav-justified > .dropdown .dropdown-menu { top: auto; @@ -4080,17 +4074,17 @@ select[multiple].input-group-sm > .input-group-btn > .btn { .nav-tabs.nav-justified > .active > a, .nav-tabs.nav-justified > .active > a:hover, .nav-tabs.nav-justified > .active > a:focus { - border: 1px solid #dddddd; + border: 1px solid #ddd; } @media (min-width: 768px) { .nav-tabs.nav-justified > li > a { - border-bottom: 1px solid #dddddd; + border-bottom: 1px solid #ddd; border-radius: 4px 4px 0 0; } .nav-tabs.nav-justified > .active > a, .nav-tabs.nav-justified > .active > a:hover, .nav-tabs.nav-justified > .active > a:focus { - border-bottom-color: #ffffff; + border-bottom-color: #fff; } } .nav-pills > li { @@ -4105,7 +4099,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn { .nav-pills > li.active > a, .nav-pills > li.active > a:hover, .nav-pills > li.active > a:focus { - color: #ffffff; + color: #fff; background-color: #337ab7; } .nav-stacked > li { @@ -4122,8 +4116,8 @@ select[multiple].input-group-sm > .input-group-btn > .btn { float: none; } .nav-justified > li > a { - text-align: center; margin-bottom: 5px; + text-align: center; } .nav-justified > .dropdown .dropdown-menu { top: auto; @@ -4148,17 +4142,17 @@ select[multiple].input-group-sm > .input-group-btn > .btn { .nav-tabs-justified > .active > a, .nav-tabs-justified > .active > a:hover, .nav-tabs-justified > .active > a:focus { - border: 1px solid #dddddd; + border: 1px solid #ddd; } @media (min-width: 768px) { .nav-tabs-justified > li > a { - border-bottom: 1px solid #dddddd; + border-bottom: 1px solid #ddd; border-radius: 4px 4px 0 0; } .nav-tabs-justified > .active > a, .nav-tabs-justified > .active > a:hover, .nav-tabs-justified > .active > a:focus { - border-bottom-color: #ffffff; + border-bottom-color: #fff; } } .tab-content > .tab-pane { @@ -4169,8 +4163,8 @@ select[multiple].input-group-sm > .input-group-btn > .btn { } .nav-tabs .dropdown-menu { margin-top: -1px; - border-top-right-radius: 0; border-top-left-radius: 0; + border-top-right-radius: 0; } .navbar { position: relative; @@ -4189,13 +4183,13 @@ select[multiple].input-group-sm > .input-group-btn > .btn { } } .navbar-collapse { - overflow-x: visible; padding-right: 15px; padding-left: 15px; - border-top: 1px solid transparent; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); + overflow-x: visible; -webkit-overflow-scrolling: touch; + border-top: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); } .navbar-collapse.in { overflow-y: auto; @@ -4219,8 +4213,8 @@ select[multiple].input-group-sm > .input-group-btn > .btn { .navbar-fixed-top .navbar-collapse, .navbar-static-top .navbar-collapse, .navbar-fixed-bottom .navbar-collapse { - padding-left: 0; padding-right: 0; + padding-left: 0; } } .navbar-fixed-top .navbar-collapse, @@ -4282,10 +4276,10 @@ select[multiple].input-group-sm > .input-group-btn > .btn { } .navbar-brand { float: left; + height: 50px; padding: 15px 15px; font-size: 18px; line-height: 20px; - height: 50px; } .navbar-brand:hover, .navbar-brand:focus { @@ -4303,9 +4297,9 @@ select[multiple].input-group-sm > .input-group-btn > .btn { .navbar-toggle { position: relative; float: right; - margin-right: 15px; padding: 9px 10px; margin-top: 8px; + margin-right: 15px; margin-bottom: 8px; background-color: transparent; background-image: none; @@ -4374,15 +4368,15 @@ select[multiple].input-group-sm > .input-group-btn > .btn { } } .navbar-form { - margin-left: -15px; - margin-right: -15px; padding: 10px 15px; + margin-top: 8px; + margin-right: -15px; + margin-bottom: 8px; + margin-left: -15px; border-top: 1px solid transparent; border-bottom: 1px solid transparent; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); - margin-top: 8px; - margin-bottom: 8px; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); } @media (min-width: 768px) { .navbar-form .form-group { @@ -4445,24 +4439,24 @@ select[multiple].input-group-sm > .input-group-btn > .btn { @media (min-width: 768px) { .navbar-form { width: auto; - border: 0; - margin-left: 0; - margin-right: 0; padding-top: 0; padding-bottom: 0; + margin-right: 0; + margin-left: 0; + border: 0; -webkit-box-shadow: none; - box-shadow: none; + box-shadow: none; } } .navbar-nav > li > .dropdown-menu { margin-top: 0; - border-top-right-radius: 0; border-top-left-radius: 0; + border-top-right-radius: 0; } .navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { margin-bottom: 0; - border-top-right-radius: 4px; border-top-left-radius: 4px; + border-top-right-radius: 4px; border-bottom-right-radius: 0; border-bottom-left-radius: 0; } @@ -4485,8 +4479,8 @@ select[multiple].input-group-sm > .input-group-btn > .btn { @media (min-width: 768px) { .navbar-text { float: left; - margin-left: 15px; margin-right: 15px; + margin-left: 15px; } } @media (min-width: 768px) { @@ -4506,7 +4500,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn { border-color: #e7e7e7; } .navbar-default .navbar-brand { - color: #777777; + color: #777; } .navbar-default .navbar-brand:hover, .navbar-default .navbar-brand:focus { @@ -4514,37 +4508,37 @@ select[multiple].input-group-sm > .input-group-btn > .btn { background-color: transparent; } .navbar-default .navbar-text { - color: #777777; + color: #777; } .navbar-default .navbar-nav > li > a { - color: #777777; + color: #777; } .navbar-default .navbar-nav > li > a:hover, .navbar-default .navbar-nav > li > a:focus { - color: #333333; + color: #333; background-color: transparent; } .navbar-default .navbar-nav > .active > a, .navbar-default .navbar-nav > .active > a:hover, .navbar-default .navbar-nav > .active > a:focus { - color: #555555; + color: #555; background-color: #e7e7e7; } .navbar-default .navbar-nav > .disabled > a, .navbar-default .navbar-nav > .disabled > a:hover, .navbar-default .navbar-nav > .disabled > a:focus { - color: #cccccc; + color: #ccc; background-color: transparent; } .navbar-default .navbar-toggle { - border-color: #dddddd; + border-color: #ddd; } .navbar-default .navbar-toggle:hover, .navbar-default .navbar-toggle:focus { - background-color: #dddddd; + background-color: #ddd; } .navbar-default .navbar-toggle .icon-bar { - background-color: #888888; + background-color: #888; } .navbar-default .navbar-collapse, .navbar-default .navbar-form { @@ -4553,52 +4547,52 @@ select[multiple].input-group-sm > .input-group-btn > .btn { .navbar-default .navbar-nav > .open > a, .navbar-default .navbar-nav > .open > a:hover, .navbar-default .navbar-nav > .open > a:focus { + color: #555; background-color: #e7e7e7; - color: #555555; } @media (max-width: 767px) { .navbar-default .navbar-nav .open .dropdown-menu > li > a { - color: #777777; + color: #777; } .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { - color: #333333; + color: #333; background-color: transparent; } .navbar-default .navbar-nav .open .dropdown-menu > .active > a, .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { - color: #555555; + color: #555; background-color: #e7e7e7; } .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { - color: #cccccc; + color: #ccc; background-color: transparent; } } .navbar-default .navbar-link { - color: #777777; + color: #777; } .navbar-default .navbar-link:hover { - color: #333333; + color: #333; } .navbar-default .btn-link { - color: #777777; + color: #777; } .navbar-default .btn-link:hover, .navbar-default .btn-link:focus { - color: #333333; + color: #333; } .navbar-default .btn-link[disabled]:hover, fieldset[disabled] .navbar-default .btn-link:hover, .navbar-default .btn-link[disabled]:focus, fieldset[disabled] .navbar-default .btn-link:focus { - color: #cccccc; + color: #ccc; } .navbar-inverse { - background-color: #222222; + background-color: #222; border-color: #080808; } .navbar-inverse .navbar-brand { @@ -4606,7 +4600,7 @@ fieldset[disabled] .navbar-default .btn-link:focus { } .navbar-inverse .navbar-brand:hover, .navbar-inverse .navbar-brand:focus { - color: #ffffff; + color: #fff; background-color: transparent; } .navbar-inverse .navbar-text { @@ -4617,30 +4611,30 @@ fieldset[disabled] .navbar-default .btn-link:focus { } .navbar-inverse .navbar-nav > li > a:hover, .navbar-inverse .navbar-nav > li > a:focus { - color: #ffffff; + color: #fff; background-color: transparent; } .navbar-inverse .navbar-nav > .active > a, .navbar-inverse .navbar-nav > .active > a:hover, .navbar-inverse .navbar-nav > .active > a:focus { - color: #ffffff; + color: #fff; background-color: #080808; } .navbar-inverse .navbar-nav > .disabled > a, .navbar-inverse .navbar-nav > .disabled > a:hover, .navbar-inverse .navbar-nav > .disabled > a:focus { - color: #444444; + color: #444; background-color: transparent; } .navbar-inverse .navbar-toggle { - border-color: #333333; + border-color: #333; } .navbar-inverse .navbar-toggle:hover, .navbar-inverse .navbar-toggle:focus { - background-color: #333333; + background-color: #333; } .navbar-inverse .navbar-toggle .icon-bar { - background-color: #ffffff; + background-color: #fff; } .navbar-inverse .navbar-collapse, .navbar-inverse .navbar-form { @@ -4649,8 +4643,8 @@ fieldset[disabled] .navbar-default .btn-link:focus { .navbar-inverse .navbar-nav > .open > a, .navbar-inverse .navbar-nav > .open > a:hover, .navbar-inverse .navbar-nav > .open > a:focus { + color: #fff; background-color: #080808; - color: #ffffff; } @media (max-width: 767px) { .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { @@ -4664,19 +4658,19 @@ fieldset[disabled] .navbar-default .btn-link:focus { } .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { - color: #ffffff; + color: #fff; background-color: transparent; } .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { - color: #ffffff; + color: #fff; background-color: #080808; } .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { - color: #444444; + color: #444; background-color: transparent; } } @@ -4684,20 +4678,20 @@ fieldset[disabled] .navbar-default .btn-link:focus { color: #9d9d9d; } .navbar-inverse .navbar-link:hover { - color: #ffffff; + color: #fff; } .navbar-inverse .btn-link { color: #9d9d9d; } .navbar-inverse .btn-link:hover, .navbar-inverse .btn-link:focus { - color: #ffffff; + color: #fff; } .navbar-inverse .btn-link[disabled]:hover, fieldset[disabled] .navbar-inverse .btn-link:hover, .navbar-inverse .btn-link[disabled]:focus, fieldset[disabled] .navbar-inverse .btn-link:focus { - color: #444444; + color: #444; } .breadcrumb { padding: 8px 15px; @@ -4710,12 +4704,12 @@ fieldset[disabled] .navbar-inverse .btn-link:focus { display: inline-block; } .breadcrumb > li + li:before { - content: "/\00a0"; padding: 0 5px; - color: #cccccc; + color: #ccc; + content: "/\00a0"; } .breadcrumb > .active { - color: #777777; + color: #777; } .pagination { display: inline-block; @@ -4731,23 +4725,23 @@ fieldset[disabled] .navbar-inverse .btn-link:focus { position: relative; float: left; padding: 6px 12px; - line-height: 1.42857143; - text-decoration: none; - color: #337ab7; - background-color: #ffffff; - border: 1px solid #dddddd; margin-left: -1px; + line-height: 1.42857143; + color: #337ab7; + text-decoration: none; + background-color: #fff; + border: 1px solid #ddd; } .pagination > li:first-child > a, .pagination > li:first-child > span { margin-left: 0; - border-bottom-left-radius: 4px; border-top-left-radius: 4px; + border-bottom-left-radius: 4px; } .pagination > li:last-child > a, .pagination > li:last-child > span { - border-bottom-right-radius: 4px; border-top-right-radius: 4px; + border-bottom-right-radius: 4px; } .pagination > li > a:hover, .pagination > li > span:hover, @@ -4755,8 +4749,8 @@ fieldset[disabled] .navbar-inverse .btn-link:focus { .pagination > li > span:focus { z-index: 2; color: #23527c; - background-color: #eeeeee; - border-color: #dddddd; + background-color: #eee; + border-color: #ddd; } .pagination > .active > a, .pagination > .active > span, @@ -4765,10 +4759,10 @@ fieldset[disabled] .navbar-inverse .btn-link:focus { .pagination > .active > a:focus, .pagination > .active > span:focus { z-index: 3; - color: #ffffff; + color: #fff; + cursor: default; background-color: #337ab7; border-color: #337ab7; - cursor: default; } .pagination > .disabled > span, .pagination > .disabled > span:hover, @@ -4776,10 +4770,10 @@ fieldset[disabled] .navbar-inverse .btn-link:focus { .pagination > .disabled > a, .pagination > .disabled > a:hover, .pagination > .disabled > a:focus { - color: #777777; - background-color: #ffffff; - border-color: #dddddd; + color: #777; cursor: not-allowed; + background-color: #fff; + border-color: #ddd; } .pagination-lg > li > a, .pagination-lg > li > span { @@ -4789,13 +4783,13 @@ fieldset[disabled] .navbar-inverse .btn-link:focus { } .pagination-lg > li:first-child > a, .pagination-lg > li:first-child > span { - border-bottom-left-radius: 6px; border-top-left-radius: 6px; + border-bottom-left-radius: 6px; } .pagination-lg > li:last-child > a, .pagination-lg > li:last-child > span { - border-bottom-right-radius: 6px; border-top-right-radius: 6px; + border-bottom-right-radius: 6px; } .pagination-sm > li > a, .pagination-sm > li > span { @@ -4805,19 +4799,19 @@ fieldset[disabled] .navbar-inverse .btn-link:focus { } .pagination-sm > li:first-child > a, .pagination-sm > li:first-child > span { - border-bottom-left-radius: 3px; border-top-left-radius: 3px; + border-bottom-left-radius: 3px; } .pagination-sm > li:last-child > a, .pagination-sm > li:last-child > span { - border-bottom-right-radius: 3px; border-top-right-radius: 3px; + border-bottom-right-radius: 3px; } .pager { padding-left: 0; margin: 20px 0; - list-style: none; text-align: center; + list-style: none; } .pager li { display: inline; @@ -4826,14 +4820,14 @@ fieldset[disabled] .navbar-inverse .btn-link:focus { .pager li > span { display: inline-block; padding: 5px 14px; - background-color: #ffffff; - border: 1px solid #dddddd; + background-color: #fff; + border: 1px solid #ddd; border-radius: 15px; } .pager li > a:hover, .pager li > a:focus { text-decoration: none; - background-color: #eeeeee; + background-color: #eee; } .pager .next > a, .pager .next > span { @@ -4847,9 +4841,9 @@ fieldset[disabled] .navbar-inverse .btn-link:focus { .pager .disabled > a:hover, .pager .disabled > a:focus, .pager .disabled > span { - color: #777777; - background-color: #ffffff; + color: #777; cursor: not-allowed; + background-color: #fff; } .label { display: inline; @@ -4857,7 +4851,7 @@ fieldset[disabled] .navbar-inverse .btn-link:focus { font-size: 75%; font-weight: bold; line-height: 1; - color: #ffffff; + color: #fff; text-align: center; white-space: nowrap; vertical-align: baseline; @@ -4865,7 +4859,7 @@ fieldset[disabled] .navbar-inverse .btn-link:focus { } a.label:hover, a.label:focus { - color: #ffffff; + color: #fff; text-decoration: none; cursor: pointer; } @@ -4877,7 +4871,7 @@ a.label:focus { top: -1px; } .label-default { - background-color: #777777; + background-color: #777; } .label-default[href]:hover, .label-default[href]:focus { @@ -4924,12 +4918,12 @@ a.label:focus { padding: 3px 7px; font-size: 12px; font-weight: bold; - color: #ffffff; line-height: 1; - vertical-align: middle; - white-space: nowrap; + color: #fff; text-align: center; - background-color: #777777; + white-space: nowrap; + vertical-align: middle; + background-color: #777; border-radius: 10px; } .badge:empty { @@ -4946,14 +4940,14 @@ a.label:focus { } a.badge:hover, a.badge:focus { - color: #ffffff; + color: #fff; text-decoration: none; cursor: pointer; } .list-group-item.active > .badge, .nav-pills > .active > a > .badge { color: #337ab7; - background-color: #ffffff; + background-color: #fff; } .list-group-item > .badge { float: right; @@ -4969,7 +4963,7 @@ a.badge:focus { padding-bottom: 30px; margin-bottom: 30px; color: inherit; - background-color: #eeeeee; + background-color: #eee; } .jumbotron h1, .jumbotron .h1 { @@ -4985,9 +4979,9 @@ a.badge:focus { } .container .jumbotron, .container-fluid .jumbotron { - border-radius: 6px; - padding-left: 15px; padding-right: 15px; + padding-left: 15px; + border-radius: 6px; } .jumbotron .container { max-width: 100%; @@ -4999,8 +4993,8 @@ a.badge:focus { } .container .jumbotron, .container-fluid .jumbotron { - padding-left: 60px; padding-right: 60px; + padding-left: 60px; } .jumbotron h1, .jumbotron .h1 { @@ -5012,17 +5006,17 @@ a.badge:focus { padding: 4px; margin-bottom: 20px; line-height: 1.42857143; - background-color: #ffffff; - border: 1px solid #dddddd; + background-color: #fff; + border: 1px solid #ddd; border-radius: 4px; - -webkit-transition: border 0.2s ease-in-out; - -o-transition: border 0.2s ease-in-out; - transition: border 0.2s ease-in-out; + -webkit-transition: border .2s ease-in-out; + -o-transition: border .2s ease-in-out; + transition: border .2s ease-in-out; } .thumbnail > img, .thumbnail a > img { - margin-left: auto; margin-right: auto; + margin-left: auto; } a.thumbnail:hover, a.thumbnail:focus, @@ -5031,7 +5025,7 @@ a.thumbnail.active { } .thumbnail .caption { padding: 9px; - color: #333333; + color: #333; } .alert { padding: 15px; @@ -5065,9 +5059,9 @@ a.thumbnail.active { color: inherit; } .alert-success { + color: #3c763d; background-color: #dff0d8; border-color: #d6e9c6; - color: #3c763d; } .alert-success hr { border-top-color: #c9e2b3; @@ -5076,9 +5070,9 @@ a.thumbnail.active { color: #2b542c; } .alert-info { + color: #31708f; background-color: #d9edf7; border-color: #bce8f1; - color: #31708f; } .alert-info hr { border-top-color: #a6e1ec; @@ -5087,9 +5081,9 @@ a.thumbnail.active { color: #245269; } .alert-warning { + color: #8a6d3b; background-color: #fcf8e3; border-color: #faebcc; - color: #8a6d3b; } .alert-warning hr { border-top-color: #f7e1b5; @@ -5098,9 +5092,9 @@ a.thumbnail.active { color: #66512c; } .alert-danger { + color: #a94442; background-color: #f2dede; border-color: #ebccd1; - color: #a94442; } .alert-danger hr { border-top-color: #e4b9c0; @@ -5133,74 +5127,74 @@ a.thumbnail.active { } } .progress { - overflow: hidden; height: 20px; margin-bottom: 20px; + overflow: hidden; background-color: #f5f5f5; border-radius: 4px; - -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); } .progress-bar { float: left; - width: 0%; + width: 0; height: 100%; font-size: 12px; line-height: 20px; - color: #ffffff; + color: #fff; text-align: center; background-color: #337ab7; - -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); - box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); - -webkit-transition: width 0.6s ease; - -o-transition: width 0.6s ease; - transition: width 0.6s ease; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); + -webkit-transition: width .6s ease; + -o-transition: width .6s ease; + transition: width .6s ease; } .progress-striped .progress-bar, .progress-bar-striped { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); -webkit-background-size: 40px 40px; background-size: 40px 40px; } .progress.active .progress-bar, .progress-bar.active { -webkit-animation: progress-bar-stripes 2s linear infinite; - -o-animation: progress-bar-stripes 2s linear infinite; - animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; } .progress-bar-success { background-color: #5cb85c; } .progress-striped .progress-bar-success { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); } .progress-bar-info { background-color: #5bc0de; } .progress-striped .progress-bar-info { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); } .progress-bar-warning { background-color: #f0ad4e; } .progress-striped .progress-bar-warning { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); } .progress-bar-danger { background-color: #d9534f; } .progress-striped .progress-bar-danger { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); } .media { margin-top: 15px; @@ -5210,8 +5204,8 @@ a.thumbnail.active { } .media, .media-body { - zoom: 1; overflow: hidden; + zoom: 1; } .media-body { width: 10000px; @@ -5251,20 +5245,20 @@ a.thumbnail.active { list-style: none; } .list-group { - margin-bottom: 20px; padding-left: 0; + margin-bottom: 20px; } .list-group-item { position: relative; display: block; padding: 10px 15px; margin-bottom: -1px; - background-color: #ffffff; - border: 1px solid #dddddd; + background-color: #fff; + border: 1px solid #ddd; } .list-group-item:first-child { - border-top-right-radius: 4px; border-top-left-radius: 4px; + border-top-right-radius: 4px; } .list-group-item:last-child { margin-bottom: 0; @@ -5273,18 +5267,18 @@ a.thumbnail.active { } a.list-group-item, button.list-group-item { - color: #555555; + color: #555; } a.list-group-item .list-group-item-heading, button.list-group-item .list-group-item-heading { - color: #333333; + color: #333; } a.list-group-item:hover, button.list-group-item:hover, a.list-group-item:focus, button.list-group-item:focus { + color: #555; text-decoration: none; - color: #555555; background-color: #f5f5f5; } button.list-group-item { @@ -5294,9 +5288,9 @@ button.list-group-item { .list-group-item.disabled, .list-group-item.disabled:hover, .list-group-item.disabled:focus { - background-color: #eeeeee; - color: #777777; + color: #777; cursor: not-allowed; + background-color: #eee; } .list-group-item.disabled .list-group-item-heading, .list-group-item.disabled:hover .list-group-item-heading, @@ -5306,13 +5300,13 @@ button.list-group-item { .list-group-item.disabled .list-group-item-text, .list-group-item.disabled:hover .list-group-item-text, .list-group-item.disabled:focus .list-group-item-text { - color: #777777; + color: #777; } .list-group-item.active, .list-group-item.active:hover, .list-group-item.active:focus { z-index: 2; - color: #ffffff; + color: #fff; background-color: #337ab7; border-color: #337ab7; } @@ -5458,11 +5452,11 @@ button.list-group-item-danger.active:focus { } .panel { margin-bottom: 20px; - background-color: #ffffff; + background-color: #fff; border: 1px solid transparent; border-radius: 4px; - -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05); + box-shadow: 0 1px 1px rgba(0, 0, 0, .05); } .panel-body { padding: 15px; @@ -5470,8 +5464,8 @@ button.list-group-item-danger.active:focus { .panel-heading { padding: 10px 15px; border-bottom: 1px solid transparent; - border-top-right-radius: 3px; border-top-left-radius: 3px; + border-top-right-radius: 3px; } .panel-heading > .dropdown .dropdown-toggle { color: inherit; @@ -5492,7 +5486,7 @@ button.list-group-item-danger.active:focus { .panel-footer { padding: 10px 15px; background-color: #f5f5f5; - border-top: 1px solid #dddddd; + border-top: 1px solid #ddd; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; } @@ -5508,8 +5502,8 @@ button.list-group-item-danger.active:focus { .panel > .list-group:first-child .list-group-item:first-child, .panel > .panel-collapse > .list-group:first-child .list-group-item:first-child { border-top: 0; - border-top-right-radius: 3px; border-top-left-radius: 3px; + border-top-right-radius: 3px; } .panel > .list-group:last-child .list-group-item:last-child, .panel > .panel-collapse > .list-group:last-child .list-group-item:last-child { @@ -5518,8 +5512,8 @@ button.list-group-item-danger.active:focus { border-bottom-left-radius: 3px; } .panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child { - border-top-right-radius: 0; border-top-left-radius: 0; + border-top-right-radius: 0; } .panel-heading + .list-group .list-group-item:first-child { border-top-width: 0; @@ -5535,13 +5529,13 @@ button.list-group-item-danger.active:focus { .panel > .table caption, .panel > .table-responsive > .table caption, .panel > .panel-collapse > .table caption { - padding-left: 15px; padding-right: 15px; + padding-left: 15px; } .panel > .table:first-child, .panel > .table-responsive:first-child > .table:first-child { - border-top-right-radius: 3px; border-top-left-radius: 3px; + border-top-right-radius: 3px; } .panel > .table:first-child > thead:first-child > tr:first-child, .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child, @@ -5579,8 +5573,8 @@ button.list-group-item-danger.active:focus { .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child, .panel > .table:last-child > tfoot:last-child > tr:last-child, .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child { - border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; } .panel > .table:last-child > tbody:last-child > tr:last-child td:first-child, .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child, @@ -5606,7 +5600,7 @@ button.list-group-item-danger.active:focus { .panel > .panel-body + .table-responsive, .panel > .table + .panel-body, .panel > .table-responsive + .panel-body { - border-top: 1px solid #dddddd; + border-top: 1px solid #ddd; } .panel > .table > tbody:first-child > tr:first-child th, .panel > .table > tbody:first-child > tr:first-child td { @@ -5665,8 +5659,8 @@ button.list-group-item-danger.active:focus { border-bottom: 0; } .panel > .table-responsive { - border: 0; margin-bottom: 0; + border: 0; } .panel-group { margin-bottom: 20px; @@ -5683,37 +5677,37 @@ button.list-group-item-danger.active:focus { } .panel-group .panel-heading + .panel-collapse > .panel-body, .panel-group .panel-heading + .panel-collapse > .list-group { - border-top: 1px solid #dddddd; + border-top: 1px solid #ddd; } .panel-group .panel-footer { border-top: 0; } .panel-group .panel-footer + .panel-collapse .panel-body { - border-bottom: 1px solid #dddddd; + border-bottom: 1px solid #ddd; } .panel-default { - border-color: #dddddd; + border-color: #ddd; } .panel-default > .panel-heading { - color: #333333; + color: #333; background-color: #f5f5f5; - border-color: #dddddd; + border-color: #ddd; } .panel-default > .panel-heading + .panel-collapse > .panel-body { - border-top-color: #dddddd; + border-top-color: #ddd; } .panel-default > .panel-heading .badge { color: #f5f5f5; - background-color: #333333; + background-color: #333; } .panel-default > .panel-footer + .panel-collapse > .panel-body { - border-bottom-color: #dddddd; + border-bottom-color: #ddd; } .panel-primary { border-color: #337ab7; } .panel-primary > .panel-heading { - color: #ffffff; + color: #fff; background-color: #337ab7; border-color: #337ab7; } @@ -5722,7 +5716,7 @@ button.list-group-item-danger.active:focus { } .panel-primary > .panel-heading .badge { color: #337ab7; - background-color: #ffffff; + background-color: #fff; } .panel-primary > .panel-footer + .panel-collapse > .panel-body { border-bottom-color: #337ab7; @@ -5813,10 +5807,10 @@ button.list-group-item-danger.active:focus { .embed-responsive video { position: absolute; top: 0; - left: 0; bottom: 0; - height: 100%; + left: 0; width: 100%; + height: 100%; border: 0; } .embed-responsive-16by9 { @@ -5832,12 +5826,12 @@ button.list-group-item-danger.active:focus { background-color: #f5f5f5; border: 1px solid #e3e3e3; border-radius: 4px; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05); } .well blockquote { border-color: #ddd; - border-color: rgba(0, 0, 0, 0.15); + border-color: rgba(0, 0, 0, .15); } .well-lg { padding: 24px; @@ -5852,55 +5846,55 @@ button.list-group-item-danger.active:focus { font-size: 21px; font-weight: bold; line-height: 1; - color: #000000; - text-shadow: 0 1px 0 #ffffff; - opacity: 0.2; + color: #000; + text-shadow: 0 1px 0 #fff; filter: alpha(opacity=20); + opacity: .2; } .close:hover, .close:focus { - color: #000000; + color: #000; text-decoration: none; cursor: pointer; - opacity: 0.5; filter: alpha(opacity=50); + opacity: .5; } button.close { + -webkit-appearance: none; padding: 0; cursor: pointer; background: transparent; border: 0; - -webkit-appearance: none; } .modal-open { overflow: hidden; } .modal { - display: none; - overflow: hidden; position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 1050; + display: none; + overflow: hidden; -webkit-overflow-scrolling: touch; outline: 0; } .modal.fade .modal-dialog { + -webkit-transition: -webkit-transform .3s ease-out; + -o-transition: -o-transform .3s ease-out; + transition: transform .3s ease-out; -webkit-transform: translate(0, -25%); - -ms-transform: translate(0, -25%); - -o-transform: translate(0, -25%); - transform: translate(0, -25%); - -webkit-transition: -webkit-transform 0.3s ease-out; - -o-transition: -o-transform 0.3s ease-out; - transition: transform 0.3s ease-out; + -ms-transform: translate(0, -25%); + -o-transform: translate(0, -25%); + transform: translate(0, -25%); } .modal.in .modal-dialog { -webkit-transform: translate(0, 0); - -ms-transform: translate(0, 0); - -o-transform: translate(0, 0); - transform: translate(0, 0); + -ms-transform: translate(0, 0); + -o-transform: translate(0, 0); + transform: translate(0, 0); } .modal-open .modal { overflow-x: hidden; @@ -5913,15 +5907,15 @@ button.close { } .modal-content { position: relative; - background-color: #ffffff; - border: 1px solid #999999; - border: 1px solid rgba(0, 0, 0, 0.2); - border-radius: 6px; - -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); - box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); + background-color: #fff; -webkit-background-clip: padding-box; background-clip: padding-box; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, .2); + border-radius: 6px; outline: 0; + -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5); + box-shadow: 0 3px 9px rgba(0, 0, 0, .5); } .modal-backdrop { position: fixed; @@ -5930,15 +5924,15 @@ button.close { bottom: 0; left: 0; z-index: 1040; - background-color: #000000; + background-color: #000; } .modal-backdrop.fade { - opacity: 0; filter: alpha(opacity=0); + opacity: 0; } .modal-backdrop.in { - opacity: 0.5; filter: alpha(opacity=50); + opacity: .5; } .modal-header { padding: 15px; @@ -5961,8 +5955,8 @@ button.close { border-top: 1px solid #e5e5e5; } .modal-footer .btn + .btn { - margin-left: 5px; margin-bottom: 0; + margin-left: 5px; } .modal-footer .btn-group .btn + .btn { margin-left: -1px; @@ -5983,8 +5977,8 @@ button.close { margin: 30px auto; } .modal-content { - -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); - box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); + -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5); + box-shadow: 0 5px 15px rgba(0, 0, 0, .5); } .modal-sm { width: 300px; @@ -6000,50 +5994,51 @@ button.close { z-index: 1070; display: block; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 12px; font-style: normal; font-weight: normal; - letter-spacing: normal; - line-break: auto; line-height: 1.42857143; text-align: left; text-align: start; text-decoration: none; text-shadow: none; text-transform: none; - white-space: normal; + letter-spacing: normal; word-break: normal; word-spacing: normal; word-wrap: normal; - font-size: 12px; - opacity: 0; + white-space: normal; filter: alpha(opacity=0); + opacity: 0; + + line-break: auto; } .tooltip.in { - opacity: 0.9; filter: alpha(opacity=90); + opacity: .9; } .tooltip.top { - margin-top: -3px; padding: 5px 0; + margin-top: -3px; } .tooltip.right { - margin-left: 3px; padding: 0 5px; + margin-left: 3px; } .tooltip.bottom { - margin-top: 3px; padding: 5px 0; + margin-top: 3px; } .tooltip.left { - margin-left: -3px; padding: 0 5px; + margin-left: -3px; } .tooltip-inner { max-width: 200px; padding: 3px 8px; - color: #ffffff; + color: #fff; text-align: center; - background-color: #000000; + background-color: #000; border-radius: 4px; } .tooltip-arrow { @@ -6058,56 +6053,56 @@ button.close { left: 50%; margin-left: -5px; border-width: 5px 5px 0; - border-top-color: #000000; + border-top-color: #000; } .tooltip.top-left .tooltip-arrow { - bottom: 0; right: 5px; + bottom: 0; margin-bottom: -5px; border-width: 5px 5px 0; - border-top-color: #000000; + border-top-color: #000; } .tooltip.top-right .tooltip-arrow { bottom: 0; left: 5px; margin-bottom: -5px; border-width: 5px 5px 0; - border-top-color: #000000; + border-top-color: #000; } .tooltip.right .tooltip-arrow { top: 50%; left: 0; margin-top: -5px; border-width: 5px 5px 5px 0; - border-right-color: #000000; + border-right-color: #000; } .tooltip.left .tooltip-arrow { top: 50%; right: 0; margin-top: -5px; border-width: 5px 0 5px 5px; - border-left-color: #000000; + border-left-color: #000; } .tooltip.bottom .tooltip-arrow { top: 0; left: 50%; margin-left: -5px; border-width: 0 5px 5px; - border-bottom-color: #000000; + border-bottom-color: #000; } .tooltip.bottom-left .tooltip-arrow { top: 0; right: 5px; margin-top: -5px; border-width: 0 5px 5px; - border-bottom-color: #000000; + border-bottom-color: #000; } .tooltip.bottom-right .tooltip-arrow { top: 0; left: 5px; margin-top: -5px; border-width: 0 5px 5px; - border-bottom-color: #000000; + border-bottom-color: #000; } .popover { position: absolute; @@ -6118,29 +6113,30 @@ button.close { max-width: 276px; padding: 1px; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; font-style: normal; font-weight: normal; - letter-spacing: normal; - line-break: auto; line-height: 1.42857143; text-align: left; text-align: start; text-decoration: none; text-shadow: none; text-transform: none; - white-space: normal; + letter-spacing: normal; word-break: normal; word-spacing: normal; word-wrap: normal; - font-size: 14px; - background-color: #ffffff; + white-space: normal; + background-color: #fff; -webkit-background-clip: padding-box; background-clip: padding-box; - border: 1px solid #cccccc; - border: 1px solid rgba(0, 0, 0, 0.2); + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, .2); border-radius: 6px; - -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2); + box-shadow: 0 5px 10px rgba(0, 0, 0, .2); + + line-break: auto; } .popover.top { margin-top: -10px; @@ -6155,8 +6151,8 @@ button.close { margin-left: -10px; } .popover-title { - margin: 0; padding: 8px 14px; + margin: 0; font-size: 14px; background-color: #f7f7f7; border-bottom: 1px solid #ebebeb; @@ -6178,83 +6174,83 @@ button.close { border-width: 11px; } .popover > .arrow:after { - border-width: 10px; content: ""; + border-width: 10px; } .popover.top > .arrow { + bottom: -11px; left: 50%; margin-left: -11px; + border-top-color: #999; + border-top-color: rgba(0, 0, 0, .25); border-bottom-width: 0; - border-top-color: #999999; - border-top-color: rgba(0, 0, 0, 0.25); - bottom: -11px; } .popover.top > .arrow:after { - content: " "; bottom: 1px; margin-left: -10px; + content: " "; + border-top-color: #fff; border-bottom-width: 0; - border-top-color: #ffffff; } .popover.right > .arrow { top: 50%; left: -11px; margin-top: -11px; + border-right-color: #999; + border-right-color: rgba(0, 0, 0, .25); border-left-width: 0; - border-right-color: #999999; - border-right-color: rgba(0, 0, 0, 0.25); } .popover.right > .arrow:after { - content: " "; - left: 1px; bottom: -10px; + left: 1px; + content: " "; + border-right-color: #fff; border-left-width: 0; - border-right-color: #ffffff; } .popover.bottom > .arrow { + top: -11px; left: 50%; margin-left: -11px; border-top-width: 0; - border-bottom-color: #999999; - border-bottom-color: rgba(0, 0, 0, 0.25); - top: -11px; + border-bottom-color: #999; + border-bottom-color: rgba(0, 0, 0, .25); } .popover.bottom > .arrow:after { - content: " "; top: 1px; margin-left: -10px; + content: " "; border-top-width: 0; - border-bottom-color: #ffffff; + border-bottom-color: #fff; } .popover.left > .arrow { top: 50%; right: -11px; margin-top: -11px; border-right-width: 0; - border-left-color: #999999; - border-left-color: rgba(0, 0, 0, 0.25); + border-left-color: #999; + border-left-color: rgba(0, 0, 0, .25); } .popover.left > .arrow:after { - content: " "; right: 1px; - border-right-width: 0; - border-left-color: #ffffff; bottom: -10px; + content: " "; + border-right-width: 0; + border-left-color: #fff; } .carousel { position: relative; } .carousel-inner { position: relative; - overflow: hidden; width: 100%; + overflow: hidden; } .carousel-inner > .item { - display: none; position: relative; - -webkit-transition: 0.6s ease-in-out left; - -o-transition: 0.6s ease-in-out left; - transition: 0.6s ease-in-out left; + display: none; + -webkit-transition: .6s ease-in-out left; + -o-transition: .6s ease-in-out left; + transition: .6s ease-in-out left; } .carousel-inner > .item > img, .carousel-inner > .item > a > img { @@ -6262,32 +6258,33 @@ button.close { } @media all and (transform-3d), (-webkit-transform-3d) { .carousel-inner > .item { - -webkit-transition: -webkit-transform 0.6s ease-in-out; - -o-transition: -o-transform 0.6s ease-in-out; - transition: transform 0.6s ease-in-out; + -webkit-transition: -webkit-transform .6s ease-in-out; + -o-transition: -o-transform .6s ease-in-out; + transition: transform .6s ease-in-out; + -webkit-backface-visibility: hidden; - backface-visibility: hidden; + backface-visibility: hidden; -webkit-perspective: 1000px; - perspective: 1000px; + perspective: 1000px; } .carousel-inner > .item.next, .carousel-inner > .item.active.right { - -webkit-transform: translate3d(100%, 0, 0); - transform: translate3d(100%, 0, 0); left: 0; + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); } .carousel-inner > .item.prev, .carousel-inner > .item.active.left { - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); left: 0; + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); } .carousel-inner > .item.next.left, .carousel-inner > .item.prev.right, .carousel-inner > .item.active { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); left: 0; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); } } .carousel-inner > .active, @@ -6323,42 +6320,42 @@ button.close { .carousel-control { position: absolute; top: 0; - left: 0; bottom: 0; + left: 0; width: 15%; - opacity: 0.5; - filter: alpha(opacity=50); font-size: 20px; - color: #ffffff; + color: #fff; text-align: center; - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); + text-shadow: 0 1px 2px rgba(0, 0, 0, .6); background-color: rgba(0, 0, 0, 0); + filter: alpha(opacity=50); + opacity: .5; } .carousel-control.left { - background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); - background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); - background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0.0001))); - background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); - background-repeat: repeat-x; + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001))); + background-image: linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); + background-repeat: repeat-x; } .carousel-control.right { - left: auto; right: 0; - background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); - background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); - background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, 0.0001)), to(rgba(0, 0, 0, 0.5))); - background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); - background-repeat: repeat-x; + left: auto; + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5))); + background-image: linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); + background-repeat: repeat-x; } .carousel-control:hover, .carousel-control:focus { - outline: 0; - color: #ffffff; + color: #fff; text-decoration: none; - opacity: 0.9; filter: alpha(opacity=90); + outline: 0; + opacity: .9; } .carousel-control .icon-prev, .carousel-control .icon-next, @@ -6366,9 +6363,9 @@ button.close { .carousel-control .glyphicon-chevron-right { position: absolute; top: 50%; - margin-top: -10px; z-index: 5; display: inline-block; + margin-top: -10px; } .carousel-control .icon-prev, .carousel-control .glyphicon-chevron-left { @@ -6384,8 +6381,8 @@ button.close { .carousel-control .icon-next { width: 20px; height: 20px; - line-height: 1; font-family: serif; + line-height: 1; } .carousel-control .icon-prev:before { content: '\2039'; @@ -6399,10 +6396,10 @@ button.close { left: 50%; z-index: 15; width: 60%; - margin-left: -30%; padding-left: 0; - list-style: none; + margin-left: -30%; text-align: center; + list-style: none; } .carousel-indicators li { display: inline-block; @@ -6410,29 +6407,29 @@ button.close { height: 10px; margin: 1px; text-indent: -999px; - border: 1px solid #ffffff; - border-radius: 10px; cursor: pointer; background-color: #000 \9; background-color: rgba(0, 0, 0, 0); + border: 1px solid #fff; + border-radius: 10px; } .carousel-indicators .active { - margin: 0; width: 12px; height: 12px; - background-color: #ffffff; + margin: 0; + background-color: #fff; } .carousel-caption { position: absolute; - left: 15%; right: 15%; bottom: 20px; + left: 15%; z-index: 10; padding-top: 20px; padding-bottom: 20px; - color: #ffffff; + color: #fff; text-align: center; - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); + text-shadow: 0 1px 2px rgba(0, 0, 0, .6); } .carousel-caption .btn { text-shadow: none; @@ -6456,8 +6453,8 @@ button.close { margin-right: -10px; } .carousel-caption { - left: 20%; right: 20%; + left: 20%; padding-bottom: 30px; } .carousel-indicators { @@ -6496,8 +6493,8 @@ button.close { .modal-header:after, .modal-footer:before, .modal-footer:after { - content: " "; display: table; + content: " "; } .clearfix:after, .dl-horizontal dd:after, @@ -6519,8 +6516,8 @@ button.close { } .center-block { display: block; - margin-left: auto; margin-right: auto; + margin-left: auto; } .pull-right { float: right !important; diff --git a/docs-web/src/test/java/com/sismics/docs/rest/TestSecurity.java b/docs-web/src/test/java/com/sismics/docs/rest/TestSecurity.java index c9a8005e..a05571fd 100644 --- a/docs-web/src/test/java/com/sismics/docs/rest/TestSecurity.java +++ b/docs-web/src/test/java/com/sismics/docs/rest/TestSecurity.java @@ -6,7 +6,7 @@ import javax.ws.rs.core.Form; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; -import junit.framework.Assert; +import org.junit.Assert; import org.apache.commons.lang.StringUtils; import org.junit.Test; diff --git a/docs-web/src/test/resources/hibernate.properties b/docs-web/src/test/resources/hibernate.properties index edd32f92..2c068af9 100644 --- a/docs-web/src/test/resources/hibernate.properties +++ b/docs-web/src/test/resources/hibernate.properties @@ -2,9 +2,13 @@ hibernate.connection.driver_class=org.h2.Driver hibernate.connection.url=jdbc:h2:mem:docs hibernate.connection.username=sa hibernate.connection.password= -hibernate.hbm2ddl.auto=none +hibernate.hbm2ddl.auto= hibernate.dialect=org.hibernate.dialect.HSQLDialect hibernate.show_sql=true hibernate.format_sql=false hibernate.max_fetch_depth=5 hibernate.cache.use_second_level_cache=false +hibernate.c3p0.min_size=1 +hibernate.c3p0.max_size=10 +hibernate.c3p0.timeout=0 +hibernate.c3p0.max_statements=0 \ No newline at end of file