From 36faf2d87fa57ac9f3aa4af5161885cefbfd57f6 Mon Sep 17 00:00:00 2001 From: Christophe Bliard Date: Wed, 24 Apr 2024 12:06:51 +0200 Subject: [PATCH 001/176] refactor: Make update ancestors spec more maintainable - Use correct progress terminology in test description. - Merge tests changing work and remaining work: the tests setup and expectations where the same. Only the action differed: one was calling the service with `estimated_hours` being modified, the other with `remaining_hours` being modified. - Make tests faster (from 13 secs to 5 secs) - Introduce `shared_let_work_packages` to create work packages with table helpers in a `shared_let` fashion. - Introduce `for_each_context` which runs the same set of tests with different RSpec shared contexts. --- .../update_ancestors_service_spec.rb | 958 ++++++------------ spec/support/for_each_context.rb | 73 ++ spec/support/table_helpers/example_methods.rb | 5 +- .../table_helpers/let_work_packages.rb | 45 +- 4 files changed, 418 insertions(+), 663 deletions(-) create mode 100644 spec/support/for_each_context.rb diff --git a/spec/services/work_packages/update_ancestors_service_spec.rb b/spec/services/work_packages/update_ancestors_service_spec.rb index b549fca80e5b..1361de2f830b 100644 --- a/spec/services/work_packages/update_ancestors_service_spec.rb +++ b/spec/services/work_packages/update_ancestors_service_spec.rb @@ -36,14 +36,8 @@ shared_let(:closed_status) { create(:closed_status, name: "Closed", default_done_ratio: 100) } shared_let(:user) { create(:user) } - let(:estimated_hours) { [nil, nil, nil] } - let(:done_ratios) { [0, 0, 0] } - let(:statuses) { %i(open open open) } - let(:aggregate_done_ratio) { 0.0 } - let(:ignore_non_working_days) { [false, false, false] } - # In order to have dependent values computed, this leverages - # the SetAttributesService to mimick how attributes are set + # the SetAttributesService to mimic how attributes are set # on work packages prior to the UpdateAncestorsService being # executed. def set_attributes_on(work_package, attributes) @@ -54,82 +48,67 @@ def set_attributes_on(work_package, attributes) .call(attributes) end - describe "done_ratio/estimated_hours/remaining_hours propagation" do - context "when setting the status of a work package" do - context 'when using the "status-based" % complete mode', - with_settings: { work_package_done_ratio: "status" } do - def call_update_ancestors_service(work_package) - changed_attributes = work_package.changes.keys.map(&:to_sym) - described_class.new(user:, work_package:) - .call(changed_attributes) - end + def call_update_ancestors_service(work_package) + changed_attributes = work_package.changes.keys.map(&:to_sym) + described_class.new(user:, work_package:) + .call(changed_attributes) + end - context "with both parent and children having estimated hours set" do - shared_let(:parent) do - create(:work_package, - subject: "parent", - estimated_hours: 10.0, - remaining_hours: 10.0, - derived_estimated_hours: 15.0, - derived_remaining_hours: 15.0, - status: open_status) - end - shared_let(:child) do - create(:work_package, - subject: "child", - parent:, - estimated_hours: 5.0, - remaining_hours: 5.0, - status: open_status) - end + describe "work, remaining work, and % complete propagation" do + context 'when using the "status-based" progress calculation mode', + with_settings: { work_package_done_ratio: "status" } do + context "with both parent and children having work set" do + shared_let_work_packages(<<~TABLE) + hierarchy | status | work | ∑ work | remaining work | ∑ remaining work | % complete | ∑ % complete + parent | Open | 10h | 15h | 10h | 15h | 0% | 0% + child | Open | 5h | | 5h | | 0% | + TABLE - context "when changing child status to a status with a default done ratio" do - %i[status status_id].each do |field| - context "with the #{field} field" do - it "recomputes child remaining work and updates ancestors total % complete accordingly" do - value = - case field - when :status then closed_status - when :status_id then closed_status.id - end - set_attributes_on(child, field => value) - call_update_ancestors_service(child) - - expect_work_packages([parent, child], <<~TABLE) - | subject | work | total work | remaining work | total remaining work | % complete | total % complete | - | parent | 10h | 15h | 10h | 10h | 0% | 33% | - | child | 5h | | 0h | | 100% | | - TABLE - end + context "when changing child status to a status with a default % complete ratio" do + %i[status status_id].each do |field| + context "with the #{field} field" do + it "recomputes child remaining work and updates ancestors total % complete accordingly" do + value = + case field + when :status then closed_status + when :status_id then closed_status.id + end + set_attributes_on(child, field => value) + call_update_ancestors_service(child) + + expect_work_packages([parent, child], <<~TABLE) + | subject | status | work | ∑ work | remaining work | ∑ remaining work | % complete | ∑ % complete | + | parent | Open | 10h | 15h | 10h | 10h | 0% | 33% | + | child | Closed | 5h | | 0h | | 100% | | + TABLE end end end end + end - context "with parent having nothing set, and 2 children having values set (bug #54179)" do - let_work_packages(<<~TABLE) - hierarchy | status | work | ∑ work | remaining work | ∑ remaining work | % complete | ∑ % complete - parent | Open | | 15h | | 10h | 0% | 33% - child1 | Open | 10h | | 10h | | 0% | - child2 | Closed | 5h | | 0h | | 100% | - TABLE + context "with parent having nothing set, and 2 children having values set (bug #54179)" do + shared_let_work_packages(<<~TABLE) + hierarchy | status | work | ∑ work | remaining work | ∑ remaining work | % complete | ∑ % complete + parent | Open | | 15h | | 10h | 0% | 33% + child1 | Open | 10h | | 10h | | 0% | + child2 | Closed | 5h | | 0h | | 100% | + TABLE - context "when changing children to all have 100% complete" do - before do - set_attributes_on(child1, status: closed_status) - call_update_ancestors_service(child1) - end + context "when changing children to all have 100% complete" do + before do + set_attributes_on(child1, status: closed_status) + call_update_ancestors_service(child1) + end - it "sets parent total % complete to 100% and its total remaining work to 0h, " \ - "and computes totals for the updated children too" do - table_work_packages.map(&:reload) - expect_work_packages(table_work_packages, <<~TABLE) - hierarchy | status | work | ∑ work | remaining work | ∑ remaining work | % complete | ∑ % complete - parent | Open | | 15h | | 0h | 0% | 100% - child1 | Closed | 10h | | 0h | | 100% | - child2 | Closed | 5h | | 0h | | 100% | - TABLE - end + it "sets parent total % complete to 100% and its total remaining work to 0h" do + table_work_packages.map(&:reload) + expect_work_packages(table_work_packages, <<~TABLE) + hierarchy | status | work | ∑ work | remaining work | ∑ remaining work | % complete | ∑ % complete + parent | Open | | 15h | | 0h | 0% | 100% + child1 | Closed | 10h | | 0h | | 100% | + child2 | Closed | 5h | | 0h | | 100% | + TABLE end end end @@ -137,459 +116,228 @@ def call_update_ancestors_service(work_package) context "for the new ancestor chain" do shared_examples "attributes of parent having children" do - before do - children - end - it "is a success" do expect(subject) .to be_success end - it "updated one work package - the parent" do + it "updates one work package - the parent" do expect(subject.dependent_results.map(&:result)) .to contain_exactly(parent) end - it "has the expected derived done ratio" do + it "has the expected total % complete" do expect(subject.dependent_results.first.result.derived_done_ratio) - .to eq aggregate_done_ratio + .to eq expected_total_p_complete end - it "has the expected derived estimated_hours" do + it "has the expected total work" do expect(subject.dependent_results.first.result.derived_estimated_hours) - .to eq aggregate_estimated_hours + .to eq expected_total_work end - it "has the expected derived remaining_hours" do + it "has the expected total remaining work" do expect(subject.dependent_results.first.result.derived_remaining_hours) - .to eq aggregate_remaining_hours + .to eq expected_total_remaining_work end end - context "when on field-based mode for % complete" do - let(:children) do - (statuses.size - 1).downto(0).map do |i| - create(:work_package, - parent:, - subject: "child #{i}", - estimated_hours: estimated_hours[i], - remaining_hours: remaining_hours[i], - ignore_non_working_days:) - end + shared_context "when work is changed" do + subject do + # On work-based mode, changing estimated_hours + # entails done_ratio also changing when going + # through the SetAttributesService + described_class + .new(user:, + work_package: child1) + .call(%i(estimated_hours done_ratio)) end + end - shared_let(:parent) { create(:work_package, subject: "parent", status: open_status) } - - context "when estimated_hours is changed" do - subject do - # On field-based mode, changing estimated_hours - # entails done_ratio also changing when going - # through the SetAttributesService - described_class - .new(user:, - work_package: children.first) - .call(%i(estimated_hours done_ratio)) - end - - context "with no estimated hours and no progress" do - let(:estimated_hours) { [nil, nil, nil] } - let(:remaining_hours) { [nil, nil, nil] } - - it "is a success" do - expect(subject) - .to be_success - end - - it "does not update the parent" do - expect(subject.dependent_results) - .to be_empty - end - end + shared_context "when remaining work is changed" do + subject do + # On work-based mode, changing remaining work + # entails % complete also changing when going + # through the SetAttributesService + described_class + .new(user:, + work_package: child1) + .call(%i(remaining_hours done_ratio)) + end + end - context "with all tasks having estimated hours and some having progress done already" do - it_behaves_like "attributes of parent having children" do - let(:estimated_hours) do - [10.0, 10.0, 10.0] - end - let(:remaining_hours) do - [0.0, 0.0, 10.0] - end + context "without any work or % complete being set" do + shared_let_work_packages(<<~TABLE) + hierarchy | work | remaining work | % complete + parent | | | + child1 | | | + child2 | | | + child3 | | | + TABLE - let(:aggregate_estimated_hours) do - 30.0 - end - let(:aggregate_remaining_hours) do - 10.0 - end - let(:aggregate_done_ratio) do - 67 - end - end + for_each_context "when work is changed", + "when remaining work is changed" do + it "is a success" do + expect(subject) + .to be_success end - context "with all tasks having estimated hours and all having progress done already" do - it_behaves_like "attributes of parent having children" do - let(:estimated_hours) do - [10.0, 10.0, 10.0] - end - let(:remaining_hours) do - [2.5, 2.5, 10.0] - end - - let(:aggregate_estimated_hours) do - 30.0 - end - let(:aggregate_remaining_hours) do - 15.0 - end - let(:aggregate_done_ratio) do - 50 - end - end + it "does not update the parent" do + expect(subject.dependent_results) + .to be_empty end + end + end - context "with all tasks having estimated hours and no tasks having any remaining hours" do - it_behaves_like "attributes of parent having children" do - let(:estimated_hours) do - [10.0, 2.0, 3.0] - end - let(:remaining_hours) do - [0.0, 0.0, 0.0] - end + context "with all children tasks having work and remaining work set" do + shared_let_work_packages(<<~TABLE) + hierarchy | work | remaining work | % complete + parent | | | + child1 | 10h | 0h | 100% + child2 | 10h | 0h | 100% + child3 | 10h | 10h | 0% + TABLE - let(:aggregate_estimated_hours) do - 15.0 - end - let(:aggregate_remaining_hours) do - 0.0 - end - let(:aggregate_done_ratio) do - 100 - end + for_each_context "when work is changed", + "when remaining work is changed" do + it_behaves_like "attributes of parent having children" do + let(:expected_total_work) do + 30.0 end - end - - context "with all tasks having estimated hours and no tasks having progress set" do - it_behaves_like "attributes of parent having children" do - let(:estimated_hours) do - [10.0, 2.0, 3.0] - end - let(:remaining_hours) do - [nil, nil, nil] - end - - let(:aggregate_estimated_hours) do - 15.0 - end - let(:aggregate_remaining_hours) do - nil - end - let(:aggregate_done_ratio) do - nil - end + let(:expected_total_remaining_work) do + 10.0 end - end - - context "with some tasks having estimated hours and none having progress set" do - it_behaves_like "attributes of parent having children" do - let(:estimated_hours) do - [10.0, nil, nil] - end - let(:remaining_hours) do - [nil, nil, nil] - end - - let(:aggregate_estimated_hours) do - 10.0 - end - let(:aggregate_remaining_hours) do - nil - end - let(:aggregate_done_ratio) do - nil - end + let(:expected_total_p_complete) do + 67 end end + end + end - context "with some tasks having estimated hours and those that do also having progress done" do - it_behaves_like "attributes of parent having children" do - let(:estimated_hours) do - [10.0, nil, nil] - end - let(:remaining_hours) do - [2.5, nil, nil] - end - - let(:aggregate_estimated_hours) do - 10.0 - end - let(:aggregate_remaining_hours) do - 2.5 - end - let(:aggregate_done_ratio) do - 75 - end - end - end + context "with all children tasks having work and remaining work set (second example)" do + shared_let_work_packages(<<~TABLE) + hierarchy | work | remaining work | % complete + parent | | | + child1 | 10h | 2.5h | 75% + child2 | 10h | 2.5h | 75% + child3 | 10h | 10h | 0% + TABLE - context "with the parent having estimated hours and progress" do - shared_let(:parent) do - create(:work_package, - subject: "parent", - estimated_hours: 10.0, - remaining_hours: 5.0) + for_each_context "when work is changed", + "when remaining work is changed" do + it_behaves_like "attributes of parent having children" do + let(:expected_total_work) do + 30.0 end - - context "and some tasks having estimated hours and some progress" do - it_behaves_like "attributes of parent having children" do - let(:estimated_hours) do - [10.0, nil, nil] - end - let(:remaining_hours) do - [2.5, nil, nil] - end - - # Parent's estimated and remaining hours are taken into account - let(:aggregate_estimated_hours) do - 20.0 - end - let(:aggregate_remaining_hours) do - 7.5 - end - let(:aggregate_done_ratio) do - 63 - end - end + let(:expected_total_remaining_work) do + 15.0 end - - context "and no tasks having estimated hours or progress" do - it_behaves_like "attributes of parent having children" do - let(:estimated_hours) do - [nil, nil, nil] - end - let(:remaining_hours) do - [nil, nil, nil] - end - - # Parent's estimated hours and remaining hours become the aggregated values - let(:aggregate_estimated_hours) do - 10.0 - end - let(:aggregate_remaining_hours) do - 5.0 - end - let(:aggregate_done_ratio) do - 50 - end - end + let(:expected_total_p_complete) do + 50 end end end + end - context "when remaining_hours is changed" do - subject do - # On field-based mode, changing remaining_hours - # entails done_ratio also changing when going - # through the SetAttributesService - described_class - .new(user:, - work_package: children.first) - .call(%i(remaining_hours done_ratio)) - end - - context "with no estimated hours and no progress" do - let(:estimated_hours) { [nil, nil, nil] } - let(:remaining_hours) { [nil, nil, nil] } - # let(:statuses) { %i(open open open) } + context "with all children tasks having work set to positive value, and having remaining work set to 0h" do + shared_let_work_packages(<<~TABLE) + hierarchy | work | remaining work | % complete + parent | | | + child1 | 10h | 0h | 100% + child2 | 2h | 0h | 100% + child3 | 3h | 0h | 100% + TABLE - it "is a success" do - expect(subject) - .to be_success + for_each_context "when work is changed", + "when remaining work is changed" do + it_behaves_like "attributes of parent having children" do + let(:expected_total_work) do + 15.0 end - - it "does not update the parent" do - expect(subject.dependent_results) - .to be_empty + let(:expected_total_remaining_work) do + 0.0 end - end - - context "with all tasks having estimated hours and some having progress done already" do - it_behaves_like "attributes of parent having children" do - let(:estimated_hours) do - [10.0, 10.0, 10.0] - end - let(:remaining_hours) do - [0.0, 0.0, 10.0] - end - - let(:aggregate_estimated_hours) do - 30.0 - end - let(:aggregate_remaining_hours) do - 10.0 - end - let(:aggregate_done_ratio) do - 67 - end + let(:expected_total_p_complete) do + 100 end end + end + end - context "with all tasks having estimated hours and all having progress done already" do - it_behaves_like "attributes of parent having children" do - let(:estimated_hours) do - [10.0, 10.0, 10.0] - end - let(:remaining_hours) do - [2.5, 2.5, 10.0] - end + context "with some children tasks having work and remaining work set" do + shared_let_work_packages(<<~TABLE) + hierarchy | work | remaining work | % complete + parent | | | + child1 | 10h | 2.5h | 75% + child2 | | | + child3 | | | + TABLE - let(:aggregate_estimated_hours) do - 30.0 - end - let(:aggregate_remaining_hours) do - 15.0 - end - let(:aggregate_done_ratio) do - 50 - end + for_each_context "when work is changed", + "when remaining work is changed" do + it_behaves_like "attributes of parent having children" do + let(:expected_total_work) do + 10.0 end - end - - context "with all tasks having estimated hours and no tasks having remaining hours" do - it_behaves_like "attributes of parent having children" do - let(:estimated_hours) do - [10.0, 2.0, 3.0] - end - let(:remaining_hours) do - [0.0, 0.0, 0.0] - end - - let(:aggregate_estimated_hours) do - 15.0 - end - let(:aggregate_remaining_hours) do - 0.0 - end - let(:aggregate_done_ratio) do - 100 - end + let(:expected_total_remaining_work) do + 2.5 end - end - - context "with all tasks having estimated hours and no tasks having progress set" do - it_behaves_like "attributes of parent having children" do - let(:estimated_hours) do - [10.0, 2.0, 3.0] - end - let(:remaining_hours) do - [nil, nil, nil] - end - - let(:aggregate_estimated_hours) do - 15.0 - end - let(:aggregate_remaining_hours) do - nil - end - let(:aggregate_done_ratio) do - nil - end + let(:expected_total_p_complete) do + 75 end end + end + end - context "with some tasks having estimated hours and none having progress set" do - it_behaves_like "attributes of parent having children" do - let(:estimated_hours) do - [10.0, nil, nil] - end - let(:remaining_hours) do - [nil, nil, nil] - end + context "with the parent having work and % complete set " \ + "and some children tasks having work and % complete set" do + shared_let_work_packages(<<~TABLE) + hierarchy | work | remaining work | % complete + parent | 10h | 5h | 50% + child1 | 10h | 2.5h | 75% + child2 | | | + child3 | | | + TABLE - let(:aggregate_estimated_hours) do - 10.0 - end - let(:aggregate_remaining_hours) do - nil - end - let(:aggregate_done_ratio) do - nil - end + for_each_context "when work is changed", + "when remaining work is changed" do + it_behaves_like "attributes of parent having children" do + # Parent's work and remaining work are taken into account + let(:expected_total_work) do + 20.0 end - end - - context "with some tasks having estimated hours and those that do also having progress done" do - it_behaves_like "attributes of parent having children" do - let(:estimated_hours) do - [10.0, nil, nil] - end - let(:remaining_hours) do - [2.5, nil, nil] - end - - let(:aggregate_estimated_hours) do - 10.0 - end - let(:aggregate_remaining_hours) do - 2.5 - end - let(:aggregate_done_ratio) do - 75 - end + let(:expected_total_remaining_work) do + 7.5 + end + let(:expected_total_p_complete) do + 63 end end + end + end - context "with the parent having estimated hours and progress" do - shared_let(:parent) do - create(:work_package, - subject: "parent", - estimated_hours: 10.0, - remaining_hours: 5.0) - end + context "with the parent having work and % complete set " \ + "and no children tasks having work or % complete set" do + shared_let_work_packages(<<~TABLE) + hierarchy | work | remaining work | % complete + parent | 10h | 5h | 50% + child1 | | | + child2 | | | + child3 | | | + TABLE - context "and some tasks having estimated hours and some progress" do - it_behaves_like "attributes of parent having children" do - let(:estimated_hours) do - [10.0, nil, nil] - end - let(:remaining_hours) do - [2.5, nil, nil] - end - - # Parent's estimated and remaining hours are taken into account - let(:aggregate_estimated_hours) do - 20.0 - end - let(:aggregate_remaining_hours) do - 7.5 - end - let(:aggregate_done_ratio) do - 63 - end - end + for_each_context "when work is changed", + "when remaining work is changed" do + it_behaves_like "attributes of parent having children" do + # Parent's work and remaining work become the total values + let(:expected_total_work) do + 10.0 end - - context "and no tasks having estimated hours or progress" do - it_behaves_like "attributes of parent having children" do - let(:estimated_hours) do - [nil, nil, nil] - end - let(:remaining_hours) do - [nil, nil, nil] - end - - # Parent's estimated hours and remaining hours become the aggregated values - let(:aggregate_estimated_hours) do - 10.0 - end - let(:aggregate_remaining_hours) do - 5.0 - end - let(:aggregate_done_ratio) do - 50 - end - end + let(:expected_total_remaining_work) do + 5.0 + end + let(:expected_total_p_complete) do + 50 end end end @@ -597,37 +345,13 @@ def call_update_ancestors_service(work_package) end context "for the previous ancestors" do - shared_let(:sibling_estimated_hours) { 7.0 } - shared_let(:sibling_remaining_hours) { 3.5 } - shared_let(:parent_estimated_hours) { 3.0 } - shared_let(:grandparent_estimated_hours) { 3.0 } - shared_let(:grandparent_remaining_hours) { 1.5 } - - shared_let(:grandparent) do - create(:work_package, - subject: "grandparent", - estimated_hours: grandparent_estimated_hours, - remaining_hours: grandparent_remaining_hours) - end - shared_let(:parent) do - create(:work_package, - subject: "parent", - estimated_hours: parent_estimated_hours, - parent: grandparent) - end - shared_let(:sibling) do - create(:work_package, - subject: "sibling", - parent:, - estimated_hours: sibling_estimated_hours, - remaining_hours: sibling_remaining_hours) - end - - shared_let(:work_package) do - create(:work_package, - subject: "subject - loses its parent", - parent:) - end + shared_let_work_packages(<<~TABLE) + hierarchy | work | remaining work | % complete + grandparent | 3h | 1.5h | 50% + parent | 3h | 0h | 100% + work package | | | + sibling | 7h | 3.5h | 50% + TABLE subject do work_package.parent = nil @@ -644,93 +368,25 @@ def call_update_ancestors_service(work_package) .to be_success end + it "updates the totals of the ancestors" do + subject + expect_work_packages([grandparent, parent, sibling, work_package], <<~TABLE) + hierarchy | work | remaining work | % complete | ∑ work | ∑ remaining work | ∑ % complete + grandparent | 3h | 1.5h | 50% | 13h | 5h | 62% + parent | 3h | 0h | 100% | 10h | 3.5h | 65% + sibling | 7h | 3.5h | 50% | | | + work package | | | | | | + TABLE + end + it "returns the former ancestors in the dependent results" do expect(subject.dependent_results.map(&:result)) .to contain_exactly(parent, grandparent) end - - it "updates the derived_done_ratio, derived_estimated_hours, and derived_remaining_hours of the former parent" do - expect do - subject - parent.reload - end - .to change(parent, :derived_done_ratio).to(65) # 6.5h derived_work_done / 10.0h derived_estimated_hours - .and change(parent, :derived_estimated_hours).to(parent_estimated_hours + sibling_estimated_hours) - .and change(parent, :derived_remaining_hours).to(sibling_remaining_hours) - end - - it "updates the derived_done_ratio, derived_estimated_hours, and derived_remaining_hours of the former grandparent" do - expect do - subject - grandparent.reload - end - .to change(grandparent, :derived_done_ratio).to(62) # 8.0h derived_work_done / 13.0h derived_estimated_hours - .and change(grandparent, :derived_estimated_hours).to(grandparent_estimated_hours + - parent_estimated_hours + - sibling_estimated_hours) - .and change(grandparent, :derived_remaining_hours).to(sibling_remaining_hours + - grandparent_remaining_hours) - end end context "for new ancestors" do - shared_let(:estimated_hours) { 7.0 } - shared_let(:remaining_hours) { 3.5 } - shared_let(:parent_estimated_hours) { 3.0 } - shared_let(:parent_remaining_hours) { 1.5 } - - shared_let(:grandparent) do - create(:work_package, - subject: "grandparent") - end - shared_let(:parent) do - create(:work_package, - subject: "parent", - estimated_hours: parent_estimated_hours, - remaining_hours: parent_remaining_hours, - parent: grandparent) - end - shared_let(:work_package) do - create(:work_package, - subject: "subject - gains a new parent and grandparent", - estimated_hours:, - remaining_hours:) - end - - shared_examples_for "updates the attributes within the new hierarchy" do - it "is successful" do - expect(subject) - .to be_success - end - - it "returns the new ancestors in the dependent results" do - expect(subject.dependent_results.map(&:result)) - .to contain_exactly(parent, grandparent) - end - - it "updates the derived_done_ratio, derived_estimated_hours, and derived_remaining_hours of the new parent" do - expect do - subject - parent.reload - end - .to change(parent, :derived_done_ratio).to(50) # 5.0h derived_work_done / 10.0h derived_estimated_hours - .and change(parent, :derived_estimated_hours).to(parent_estimated_hours + estimated_hours) - .and change(parent, :derived_remaining_hours).to(parent_remaining_hours + remaining_hours) - end - - it "updates the derived_done_ratio, derived_estimated_hours, and derived_remaining_hours " \ - "of the new grandparent" do - expect do - subject - grandparent.reload - end - .to change(grandparent, :derived_done_ratio).to(50) # 5.0h derived_work_done / 10.0h derived_estimated_hours - .and change(grandparent, :derived_estimated_hours).to(parent_estimated_hours + estimated_hours) - .and change(grandparent, :derived_remaining_hours).to(parent_remaining_hours + remaining_hours) - end - end - - context "if setting the parent" do + shared_context "if setting the parent" do subject do work_package.parent = parent work_package.save! @@ -740,11 +396,9 @@ def call_update_ancestors_service(work_package) work_package:) .call(%i(parent)) end - - it_behaves_like "updates the attributes within the new hierarchy" end - context "if setting the parent_id" do + shared_context "if setting the parent_id" do subject do work_package.parent_id = parent.id work_package.save! @@ -754,59 +408,61 @@ def call_update_ancestors_service(work_package) work_package:) .call(%i(parent_id)) end + end + + shared_let_work_packages(<<~TABLE) + hierarchy | work | remaining work | % complete + grandparent | | | + parent | 3h | 1.5h | 50% + work package | 7h | 3.5h | 50% + TABLE + + for_each_context "if setting the parent", + "if setting the parent_id" do + it "is successful" do + expect(subject) + .to be_success + end + + it "returns the new ancestors in the dependent results" do + expect(subject.dependent_results.map(&:result)) + .to contain_exactly(parent, grandparent) + end - it_behaves_like "updates the attributes within the new hierarchy" + it "updates the totals of the ancestors" do + subject + expect_work_packages([grandparent, parent, work_package], <<~TABLE) + hierarchy | work | remaining work | % complete | ∑ work | ∑ remaining work | ∑ % complete + grandparent | | | | 10h | 5h | 50% + parent | 3h | 1.5h | 50% | 10h | 5h | 50% + work package | 7h | 3.5h | 50% | | | + TABLE + end end end context "with old and new parent having a common ancestor" do - shared_let(:estimated_hours) { 7.0 } - shared_let(:remaining_hours) { 3.5 } - shared_let(:new_estimated_hours) { 10.0 } - shared_let(:new_remaining_hours) { 2 } - - shared_let(:grandparent) do - create(:work_package, - subject: "common grandparent", - derived_done_ratio: 50, # two children having [done_ratio, 0] - derived_estimated_hours: estimated_hours, - derived_remaining_hours: remaining_hours) - end - shared_let(:old_parent) do - create(:work_package, - subject: "old parent", - parent: grandparent, - derived_done_ratio: 50, - derived_estimated_hours: estimated_hours, - derived_remaining_hours: remaining_hours) - end - shared_let(:new_parent) do - create(:work_package, - subject: "new parent", - parent: grandparent) - end - shared_let(:work_package) do - create(:work_package, - subject: "subject - parent changes from old parent to new parent, same grandparent", - parent: old_parent, - estimated_hours:, - remaining_hours:) - end + # work_package's parent will change from old parent to new parent, same grandparent + shared_let_work_packages(<<~TABLE) + hierarchy | work | remaining work | % complete | ∑ work | ∑ remaining work | ∑ % complete + grandparent | | | | 7h | 3.5h | 50% + old parent | | | | 7h | 3.5h | 50% + work package | 7h | 3.5h | 50% | | | + new parent | | | | | | + TABLE subject do - work_package.parent = new_parent # In this test case, done_ratio, derived_estimated_hours, and - # derived_remaining_hours would not inherently change on grandparent. - # However, if work_package has siblings then changing its parent could - # cause done_ratio, derived_estimated_hours, and/or - # derived_remaining_hours on grandparent to inherently change. To verify - # that grandparent can be properly updated in that case without making - # this test dependent on the implementation details of the calculations, - # done_ratio, derived_estimated_hours, and derived_remaining_hours are - # forced to change at the same time as the parent. + # derived_remaining_hours would not inherently change on grandparent + # if work package keeps the same progress values. + # + # To verify that grandparent can be properly updated in this scenario, + # work and remaining work are also changed on the work package to force + # grandparent totals to be updated. set_attributes_on(work_package, - estimated_hours: new_estimated_hours, - remaining_hours: new_remaining_hours) + parent: new_parent, + estimated_hours: 10, + remaining_hours: 2) work_package.save! described_class @@ -820,49 +476,29 @@ def call_update_ancestors_service(work_package) .to be_success end + it "updates the totals of the new parent and the former parent" do + subject + expect_work_packages([grandparent, old_parent, new_parent, work_package], <<~TABLE) + hierarchy | work | remaining work | % complete | ∑ work | ∑ remaining work | ∑ % complete + grandparent | | | | 10h | 2h | 80% + old parent | | | | | | + new parent | | | | 10h | 2h | 80% + work package | 10h | 2h | 80% | | | + TABLE + end + it "returns both the former and new ancestors in the dependent results without duplicates" do expect(subject.dependent_results.map(&:result)) .to contain_exactly(new_parent, grandparent, old_parent) end - - it "updates the derived_done_ratio, derived_estimated_hours, and derived_remaining_hours " \ - "of the former parent to nil" do - expect do - subject - old_parent.reload - end - .to change(old_parent, :derived_done_ratio).to(nil) - .and change(old_parent, :derived_estimated_hours).to(nil) - .and change(old_parent, :derived_remaining_hours).to(nil) - end - - it "updates the derived_done_ratio, derived_estimated_hours, and derived_remaining_hours of the new parent" do - expect do - subject - new_parent.reload - end - .to change(new_parent, :derived_done_ratio).to(80) - .and change(new_parent, :derived_estimated_hours).to(new_estimated_hours) - .and change(new_parent, :derived_remaining_hours).to(new_remaining_hours) - end - - it "updates the derived_done_ratio, derived_estimated_hours, and derived_remaining_hours of the grandparent" do - expect do - subject - grandparent.reload - end - .to change(grandparent, :derived_done_ratio).to(80) - .and change(grandparent, :derived_estimated_hours).to(new_estimated_hours) - .and change(grandparent, :derived_remaining_hours).to(new_remaining_hours) - end end end describe "work propagation" do - shared_let(:parent) { create(:work_package, subject: "parent") } - shared_let(:child) { create(:work_package, subject: "child", parent:) } - context "when setting work of a work package having children without any work value" do + shared_let(:parent) { create(:work_package, subject: "parent") } + shared_let(:child) { create(:work_package, subject: "child", parent:) } + before do parent.estimated_hours = 2.0 end @@ -1050,7 +686,7 @@ def call_update_ancestors_service(work_package) end end - describe "done_ratio propagation" do + describe "% complete propagation" do shared_let(:parent) { create(:work_package, subject: "parent") } context "given child with work, when remaining work being set on parent" do diff --git a/spec/support/for_each_context.rb b/spec/support/for_each_context.rb new file mode 100644 index 000000000000..78fdee1f77d7 --- /dev/null +++ b/spec/support/for_each_context.rb @@ -0,0 +1,73 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2012-2024 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +module RSpecOpExt + module ForEachContext + # Runs the same example group multiple times: once for each given named + # context. + # + # For each named context, the context is applied and the tests are run. It + # allows to have multiple shared contexts and only one example group, + # instead of having shared examples and multiple contexts including the + # shared examples. It generally reads better. + # + # @example + # + # RSpec.describe "something" do + # shared_context "early in the morning" do + # let(:time) { "06:30" } + # end + # + # shared_context "late in the evening" do + # let(:time) { "23:00" } + # end + # + # for_each_context "early in the morning", + # "late in the evening" do + # it "has energy" do + # expect(body.energy_level).to eq(100) + # end + # end + # end + def for_each_context(*context_names, &blk) + context_names.each do |context_name| + context context_name do + include_context context_name + + instance_exec(&blk) + end + end + end + end +end + +RSpec.configure do |config| + config.extend RSpecOpExt::ForEachContext +end diff --git a/spec/support/table_helpers/example_methods.rb b/spec/support/table_helpers/example_methods.rb index 5843b2744ac8..f7ea096f8eb5 100644 --- a/spec/support/table_helpers/example_methods.rb +++ b/spec/support/table_helpers/example_methods.rb @@ -51,7 +51,8 @@ def create_table(table_representation) # Expect the given work packages to match a visual table representation. # - # It uses +match_table+ internally. + # It uses +match_table+ internally and reloads the work packages from + # database before comparing. # # For instance: # @@ -66,6 +67,7 @@ def create_table(table_representation) # is equivalent to: # # it 'is scheduled' do + # work_packages.each(&:reload) # expect(work_packages).to match_table(<<~TABLE) # subject | work | derived work | # parent | 1h | 3h | @@ -73,6 +75,7 @@ def create_table(table_representation) # TABLE # end def expect_work_packages(work_packages, table_representation) + work_packages.each(&:reload) expect(work_packages).to match_table(table_representation) end end diff --git a/spec/support/table_helpers/let_work_packages.rb b/spec/support/table_helpers/let_work_packages.rb index c7982c267a7e..bc62f2cf3da0 100644 --- a/spec/support/table_helpers/let_work_packages.rb +++ b/spec/support/table_helpers/let_work_packages.rb @@ -49,7 +49,7 @@ module LetWorkPackages # let!(:_table) do # create_table(table_representation) # end - # let!(:table_work_packages) do + # let(:table_work_packages) do # _table.work_packages # end # let(:parent) do @@ -70,5 +70,48 @@ def let_work_packages(table_representation) let(identifier) { _table.work_package(identifier) } end end + + # Declare work packages and relations from a visual chart representation. + # + # It uses +create_table+ internally and is useful to have direct access + # to the created work packages. + # + # To see supported columns, see +TableHelpers::Column+. + # + # For instance: + # + # shared_let_work_packages(<<~TABLE) + # hierarchy | work | + # parent | 1h | + # child | 2.5h | + # another one | | + # TABLE + # + # is equivalent to: + # + # shared_let(:_table) do + # create_table(table_representation) + # end + # shared_let(:table_work_packages) do + # _table.work_packages + # end + # shared_let(:parent) do + # _table.work_package(:parent) + # end + # shared_let(:child) do + # _table.work_package(:child) + # end + # shared_let(:another_one) do + # _table.work_package(:another_one) + # end + def shared_let_work_packages(table_representation) + shared_let(:_table) { create_table(table_representation) } + + table_data = TableData.for(table_representation) + shared_let(:table_work_packages) { _table.work_packages } + table_data.work_package_identifiers.each do |identifier| + shared_let(identifier) { _table.work_package(identifier) } + end + end end end From ea7fe80eaad08431b519387d189e387121d7d35d Mon Sep 17 00:00:00 2001 From: Christophe Bliard Date: Thu, 2 May 2024 09:44:03 +0200 Subject: [PATCH 002/176] refactor: Remove unused methods about leaves The leaves are no more used in `UpdateAncestorsService`. --- .../work_packages/update_ancestors/loader.rb | 38 ++++++------------- 1 file changed, 11 insertions(+), 27 deletions(-) diff --git a/app/services/work_packages/update_ancestors/loader.rb b/app/services/work_packages/update_ancestors/loader.rb index 435301050231..bebb80880e22 100644 --- a/app/services/work_packages/update_ancestors/loader.rb +++ b/app/services/work_packages/update_ancestors/loader.rb @@ -40,7 +40,7 @@ def select def descendants_of(queried_work_package) @descendants ||= Hash.new do |hash, wp| - hash[wp] = replaced_related_of(wp, :descendants) + hash[wp] = replaced_related_descendants(wp) end @descendants[queried_work_package] @@ -72,7 +72,7 @@ def ancestors end end - # Replace descendants/leaves by ancestors if they are the same. + # Replace descendants by ancestors if they are the same. # This can e.g. be the case in scenario of # grandparent # | @@ -84,31 +84,27 @@ def ancestors # Then grandparent and parent are already in ancestors. # Parent might be modified during the UpdateAncestorsService run, # and the descendants of grandparent need to have the updated value. - def replaced_related_of(queried_work_package, relation_type) - related_of(queried_work_package, relation_type).map do |leaf| + def replaced_related_descendants(queried_work_package) + related_descendants(queried_work_package).map do |leaf| if work_package.id == leaf.id work_package elsif (ancestor = ancestors.detect { |a| a.id == leaf.id }) ancestor else - yield leaf if block_given? leaf end end end - def related_of(queried_work_package, relation_type) + def related_descendants(queried_work_package) scope = queried_work_package - .send(relation_type) + .descendants .where.not(id: queried_work_package.id) - if send(:"#{relation_type}_joins") - scope = scope.joins(send(:"#{relation_type}_joins")) - end - + attributes = selected_descendants_attributes scope - .pluck(*send(:"selected_#{relation_type}_attributes")) - .map { |p| LoaderStruct.new(send(:"selected_#{relation_type}_attributes").zip(p).to_h) } + .pluck(*attributes) + .map { |p| LoaderStruct.new(attributes.zip(p).to_h) } end # Returns the current ancestors sorted by distance (called generations in the table) @@ -130,19 +126,7 @@ def former_ancestors def selected_descendants_attributes # By having the id in here, we can avoid DISTINCT queries squashing duplicate values - %i(id estimated_hours parent_id schedule_manually ignore_non_working_days remaining_hours) - end - - def descendants_joins - nil - end - - def selected_leaves_attributes - %i(id done_ratio derived_estimated_hours estimated_hours is_closed remaining_hours derived_remaining_hours) - end - - def leaves_joins - :status + %i[id estimated_hours parent_id schedule_manually ignore_non_working_days remaining_hours] end ## @@ -165,7 +149,7 @@ def previous_change_parent_id previous_parent_changes = previous[:parent_id] || previous[:parent] - previous_parent_changes ? previous_parent_changes.first : nil + previous_parent_changes&.first end class LoaderStruct < Hashie::Mash; end From 83564887c62f9118421ef21c472758ee14985cca Mon Sep 17 00:00:00 2001 From: Christophe Bliard Date: Thu, 2 May 2024 13:28:04 +0200 Subject: [PATCH 003/176] refactor: avoid using Hashie::Mash --- .../work_packages/update_ancestors/loader.rb | 9 ++-- .../update_ancestors/loader_spec.rb | 54 ++++++++----------- 2 files changed, 26 insertions(+), 37 deletions(-) diff --git a/app/services/work_packages/update_ancestors/loader.rb b/app/services/work_packages/update_ancestors/loader.rb index bebb80880e22..21eda6038a1e 100644 --- a/app/services/work_packages/update_ancestors/loader.rb +++ b/app/services/work_packages/update_ancestors/loader.rb @@ -104,7 +104,7 @@ def related_descendants(queried_work_package) attributes = selected_descendants_attributes scope .pluck(*attributes) - .map { |p| LoaderStruct.new(attributes.zip(p).to_h) } + .map { |p| WorkPackageLikeStruct.new(**attributes.zip(p).to_h) } end # Returns the current ancestors sorted by distance (called generations in the table) @@ -126,7 +126,7 @@ def former_ancestors def selected_descendants_attributes # By having the id in here, we can avoid DISTINCT queries squashing duplicate values - %i[id estimated_hours parent_id schedule_manually ignore_non_working_days remaining_hours] + %i[id parent_id estimated_hours remaining_hours schedule_manually ignore_non_working_days] end ## @@ -152,6 +152,7 @@ def previous_change_parent_id previous_parent_changes&.first end - class LoaderStruct < Hashie::Mash; end - LoaderStruct.disable_warnings + WorkPackageLikeStruct = Data.define(:id, :parent_id, + :estimated_hours, :remaining_hours, + :schedule_manually, :ignore_non_working_days) end diff --git a/spec/services/work_packages/update_ancestors/loader_spec.rb b/spec/services/work_packages/update_ancestors/loader_spec.rb index 0b4f7c70bd24..6e20a2ca707f 100644 --- a/spec/services/work_packages/update_ancestors/loader_spec.rb +++ b/spec/services/work_packages/update_ancestors/loader_spec.rb @@ -223,67 +223,55 @@ end end - describe "#descendants_of" do - def descendants_of_hash(hashed_work_package) - { "estimated_hours" => nil, - "id" => hashed_work_package.id, - "ignore_non_working_days" => false, - "parent_id" => hashed_work_package.parent_id, - "remaining_hours" => nil, - "schedule_manually" => false } - end + def work_package_struct(work_package) + attribute_names = WorkPackages::UpdateAncestors::Loader::WorkPackageLikeStruct.members.map(&:to_s) + attributes = work_package.attributes.slice(*attribute_names) + WorkPackages::UpdateAncestors::Loader::WorkPackageLikeStruct.new(**attributes) + end + describe "#descendants_of" do context "for the work_package" do - it "is its child (as a hash)" do + it "is its child (as a struct)" do expect(instance.descendants_of(work_package)) - .to contain_exactly(descendants_of_hash(child)) + .to contain_exactly(work_package_struct(child)) end end context "for the parent" do - it "is the work package, its child (as a hash) and its sibling (as a hash)" do + it "is the work package, its child (as a struct) and its sibling (as a struct)" do expect(instance.descendants_of(parent)) - .to contain_exactly(descendants_of_hash(child), work_package, descendants_of_hash(sibling)) + .to contain_exactly(work_package_struct(child), work_package, work_package_struct(sibling)) end end context "for the grandparent" do - it "is the parent, the work package, its child (as a hash) and its sibling (as a hash)" do + it "is the parent, the work package, its child (as a struct) and its sibling (as a struct)" do expect(instance.descendants_of(grandparent)) - .to contain_exactly(parent, work_package, descendants_of_hash(child), descendants_of_hash(sibling)) + .to contain_exactly(parent, work_package, work_package_struct(child), work_package_struct(sibling)) end end context "for the grandgrandparent (the root)" do - it "is the complete tree, partly as a hash and partly as the preloaded work packages" do + it "is the complete tree, partly as a struct and partly as the preloaded work packages" do expect(instance.descendants_of(grandgrandparent)) - .to contain_exactly(descendants_of_hash(grandparent_sibling), grandparent, parent, work_package, - descendants_of_hash(child), descendants_of_hash(sibling)) + .to contain_exactly(work_package_struct(grandparent_sibling), grandparent, parent, work_package, + work_package_struct(child), work_package_struct(sibling)) end end end describe "#children_of" do - def children_of_hash(hashed_work_package) - { "estimated_hours" => nil, - "id" => hashed_work_package.id, - "ignore_non_working_days" => false, - "parent_id" => hashed_work_package.parent_id, - "remaining_hours" => nil, - "schedule_manually" => false } - end - context "for the work_package" do - it "is its child (as a hash)" do + it "is its child (as a struct)" do expect(instance.children_of(work_package)) - .to contain_exactly(children_of_hash(child)) + .to contain_exactly(work_package_struct(child)) end end context "for the parent" do - it "is the work package and its sibling (as a hash)" do + it "is the work package and its sibling (as a struct)" do expect(instance.children_of(parent)) - .to contain_exactly(work_package, children_of_hash(sibling)) + .to contain_exactly(work_package, work_package_struct(sibling)) end end @@ -295,9 +283,9 @@ def children_of_hash(hashed_work_package) end context "for the grandgrandparent" do - it "is the grandparent and its sibling (as a hash)" do + it "is the grandparent and its sibling (as a struct)" do expect(instance.children_of(grandgrandparent)) - .to contain_exactly(children_of_hash(grandparent_sibling), grandparent) + .to contain_exactly(work_package_struct(grandparent_sibling), grandparent) end end end From a89cfa43211eea577fef7e74fe5bf3dce7acf8c4 Mon Sep 17 00:00:00 2001 From: Christophe Bliard Date: Thu, 2 May 2024 17:44:41 +0200 Subject: [PATCH 004/176] Make `match_table` work regardless of the order of the work packages --- spec/support/table_helpers.rb | 1 + spec/support/table_helpers/table_data.rb | 9 +++ .../table_helpers/table_data_spec.rb | 64 +++++++++++++++++++ 3 files changed, 74 insertions(+) diff --git a/spec/support/table_helpers.rb b/spec/support/table_helpers.rb index e4597d06e140..7819e5c8fa06 100644 --- a/spec/support/table_helpers.rb +++ b/spec/support/table_helpers.rb @@ -36,6 +36,7 @@ match do |actual_work_packages| expected_data = TableHelpers::TableData.for(expected) actual_data = TableHelpers::TableData.from_work_packages(actual_work_packages, expected_data.columns) + actual_data.order_like!(expected_data) representer = TableHelpers::TableRepresenter.new(tables_data: [expected_data, actual_data], columns: expected_data.columns) diff --git a/spec/support/table_helpers/table_data.rb b/spec/support/table_helpers/table_data.rb index 0659f89280f3..59186d3463aa 100644 --- a/spec/support/table_helpers/table_data.rb +++ b/spec/support/table_helpers/table_data.rb @@ -83,6 +83,15 @@ def create_work_packages Table.new(work_packages_by_identifier) end + def order_like!(other_table) + ordered_identifiers = other_table.work_package_identifiers + extra_identifiers = work_package_identifiers - ordered_identifiers + @work_packages_data = work_packages_data + .index_by { _1[:identifier] } + .values_at(*(ordered_identifiers + extra_identifiers)) + .compact + end + class Factory attr_reader :table_data, :work_packages_by_identifier diff --git a/spec/support_spec/table_helpers/table_data_spec.rb b/spec/support_spec/table_helpers/table_data_spec.rb index 0fbecea1677c..f6ffe8581941 100644 --- a/spec/support_spec/table_helpers/table_data_spec.rb +++ b/spec/support_spec/table_helpers/table_data_spec.rb @@ -145,5 +145,69 @@ module TableHelpers .not_to raise_error end end + + describe "#order_like" do + it "orders the table data like the given table" do + table_representation = <<~TABLE + | subject | remaining work | + | work package | 3h | + | another one | | + TABLE + table_data = described_class.for(table_representation) + + other_table_representation = <<~TABLE + | subject | remaining work | + | another one | | + | work package | 3h | + TABLE + other_table_data = described_class.for(other_table_representation) + expect(table_data.work_package_identifiers).to eq(%i[work_package another_one]) + + table_data.order_like!(other_table_data) + expect(table_data.work_package_identifiers).to eq(%i[another_one work_package]) + end + + it "ignores unknown rows from the given table" do + table_representation = <<~TABLE + | subject | remaining work | + | work package | 3h | + | another one | | + TABLE + table_data = described_class.for(table_representation) + + other_table_representation = <<~TABLE + | subject | remaining work | + | another one | | + | work package | 3h | + | unknown one | | + TABLE + other_table_data = described_class.for(other_table_representation) + expect(table_data.work_package_identifiers).to eq(%i[work_package another_one]) + + table_data.order_like!(other_table_data) + expect(table_data.work_package_identifiers).to eq(%i[another_one work_package]) + end + + it "appends to the bottom the rows missing in the given table" do + table_representation = <<~TABLE + | subject | remaining work | + | work package | 3h | + | extra one | | + | another one | | + TABLE + table_data = described_class.for(table_representation) + + other_table_representation = <<~TABLE + | subject | remaining work | + | another one | | + | work package | 3h | + TABLE + other_table_data = described_class.for(other_table_representation) + expect(table_data.work_package_identifiers).to eq(%i[work_package extra_one another_one]) + + table_data.order_like!(other_table_data) + expect(table_data.work_package_identifiers).to eq(%i[another_one work_package extra_one]) + end + end end end From 2563d84e9207c9122439266e1800de55a35905b8 Mon Sep 17 00:00:00 2001 From: Christophe Bliard Date: Thu, 2 May 2024 17:48:19 +0200 Subject: [PATCH 005/176] [49409] Exclude work packages with excluded status from totals computation https://community.openproject.org/wp/49409 --- app/models/work_package.rb | 4 ++ .../work_packages/update_ancestors/loader.rb | 31 +++++---- .../work_packages/update_ancestors_service.rb | 6 +- ...11_add_excluded_from_totals_to_statuses.rb | 5 ++ spec/factories/status_factory.rb | 10 +++ .../update_ancestors/loader_spec.rb | 34 ++++++++++ .../update_ancestors_service_spec.rb | 63 ++++++++++++++++++- 7 files changed, 138 insertions(+), 15 deletions(-) create mode 100644 db/migrate/20240424093311_add_excluded_from_totals_to_statuses.rb diff --git a/app/models/work_package.rb b/app/models/work_package.rb index 6b6450db188b..828ddc2d26e9 100644 --- a/app/models/work_package.rb +++ b/app/models/work_package.rb @@ -293,6 +293,10 @@ def milestone? end alias_method :is_milestone?, :milestone? + def included_in_totals_calculation? + !status.excluded_from_totals + end + def done_ratio if WorkPackage.use_status_for_done_ratio? && status && status.default_done_ratio status.default_done_ratio diff --git a/app/services/work_packages/update_ancestors/loader.rb b/app/services/work_packages/update_ancestors/loader.rb index 21eda6038a1e..3e9646e5f99e 100644 --- a/app/services/work_packages/update_ancestors/loader.rb +++ b/app/services/work_packages/update_ancestors/loader.rb @@ -25,6 +25,22 @@ # See COPYRIGHT and LICENSE files for more details. class WorkPackages::UpdateAncestors::Loader + DESCENDANT_ATTRIBUTES = { + id: "id", + parent_id: "parent_id", + estimated_hours: "estimated_hours", + remaining_hours: "remaining_hours", + status_excluded_from_totals: "statuses.excluded_from_totals", + schedule_manually: "schedule_manually", + ignore_non_working_days: "ignore_non_working_days" + }.freeze + + WorkPackageLikeStruct = Data.define(*DESCENDANT_ATTRIBUTES.keys) do + def included_in_totals_calculation? + !status_excluded_from_totals + end + end + def initialize(work_package, include_former_ancestors) self.work_package = work_package self.include_former_ancestors = include_former_ancestors @@ -101,10 +117,10 @@ def related_descendants(queried_work_package) .descendants .where.not(id: queried_work_package.id) - attributes = selected_descendants_attributes scope - .pluck(*attributes) - .map { |p| WorkPackageLikeStruct.new(**attributes.zip(p).to_h) } + .left_joins(:status) + .pluck(*DESCENDANT_ATTRIBUTES.values) + .map { |p| WorkPackageLikeStruct.new(**DESCENDANT_ATTRIBUTES.keys.zip(p).to_h) } end # Returns the current ancestors sorted by distance (called generations in the table) @@ -124,11 +140,6 @@ def former_ancestors end end - def selected_descendants_attributes - # By having the id in here, we can avoid DISTINCT queries squashing duplicate values - %i[id parent_id estimated_hours remaining_hours schedule_manually ignore_non_working_days] - end - ## # Get the previous parent ID # This could either be +parent_id_was+ if parent was changed @@ -151,8 +162,4 @@ def previous_change_parent_id previous_parent_changes&.first end - - WorkPackageLikeStruct = Data.define(:id, :parent_id, - :estimated_hours, :remaining_hours, - :schedule_manually, :ignore_non_working_days) end diff --git a/app/services/work_packages/update_ancestors_service.rb b/app/services/work_packages/update_ancestors_service.rb index 7627840b4886..0ced628eac74 100644 --- a/app/services/work_packages/update_ancestors_service.rb +++ b/app/services/work_packages/update_ancestors_service.rb @@ -99,7 +99,7 @@ def derive_attributes(work_package, loader, attributes) # or the derived remaining hours, depending on the % Complete mode # currently active. # - %i[estimated_hours remaining_hours] => :derive_total_estimated_and_remaining_hours, + %i[estimated_hours remaining_hours status status_id] => :derive_total_estimated_and_remaining_hours, %i[estimated_hours remaining_hours done_ratio status status_id] => :derive_done_ratio, %i[ignore_non_working_days] => :derive_ignore_non_working_days }.each do |derivative_attributes, method| @@ -155,7 +155,9 @@ def derive_total(work_package, attribute, loader) return if no_children?(work_package, loader) work_packages = [work_package] + loader.descendants_of(work_package) - values = work_packages.filter_map(&attribute) + values = work_packages + .filter(&:included_in_totals_calculation?) + .filter_map(&attribute) return if values.empty? values.sum.to_f diff --git a/db/migrate/20240424093311_add_excluded_from_totals_to_statuses.rb b/db/migrate/20240424093311_add_excluded_from_totals_to_statuses.rb new file mode 100644 index 000000000000..dd3e6fbb96dd --- /dev/null +++ b/db/migrate/20240424093311_add_excluded_from_totals_to_statuses.rb @@ -0,0 +1,5 @@ +class AddExcludedFromTotalsToStatuses < ActiveRecord::Migration[7.1] + def change + add_column :statuses, :excluded_from_totals, :boolean, default: false, null: false + end +end diff --git a/spec/factories/status_factory.rb b/spec/factories/status_factory.rb index ddaba8fc5872..586a9082c566 100644 --- a/spec/factories/status_factory.rb +++ b/spec/factories/status_factory.rb @@ -31,11 +31,21 @@ sequence(:name) { |n| "status #{n}" } is_closed { false } is_readonly { false } + excluded_from_totals { false } + + trait :excluded_from_totals do + excluded_from_totals { true } + end factory :closed_status do is_closed { true } end + factory :rejected_status do + excluded_from_totals + name { "Rejected" } + end + factory :default_status do is_default { true } end diff --git a/spec/services/work_packages/update_ancestors/loader_spec.rb b/spec/services/work_packages/update_ancestors/loader_spec.rb index 6e20a2ca707f..8986890fcdbc 100644 --- a/spec/services/work_packages/update_ancestors/loader_spec.rb +++ b/spec/services/work_packages/update_ancestors/loader_spec.rb @@ -27,6 +27,17 @@ require "spec_helper" RSpec.describe WorkPackages::UpdateAncestors::Loader, type: :model do + shared_let(:user) { create(:user) } + shared_let(:project) { create(:project_with_types) } + shared_let(:included_status) { create(:status) } + shared_let(:excluded_status) { create(:rejected_status) } + + before_all do + set_factory_default(:project_with_types, project) + set_factory_default(:status, included_status) + set_factory_default(:user, user) + end + shared_let(:grandgrandparent) do create(:work_package, subject: "grandgrandparent") @@ -226,6 +237,7 @@ def work_package_struct(work_package) attribute_names = WorkPackages::UpdateAncestors::Loader::WorkPackageLikeStruct.members.map(&:to_s) attributes = work_package.attributes.slice(*attribute_names) + attributes[:status_excluded_from_totals] = false WorkPackages::UpdateAncestors::Loader::WorkPackageLikeStruct.new(**attributes) end @@ -235,6 +247,28 @@ def work_package_struct(work_package) expect(instance.descendants_of(work_package)) .to contain_exactly(work_package_struct(child)) end + + context "with the child having a status not being excluded from totals calculation" do + before do + child.update(status: included_status) + end + + it "correctly responds true to #included_in_totals_calculation? like a WorkPackage instance" do + child = instance.descendants_of(work_package).first + expect(child.included_in_totals_calculation?).to be true + end + end + + context "with the child having a status being excluded from totals calculation" do + before do + child.update(status: excluded_status) + end + + it "correctly responds false to #included_in_totals_calculation? like a WorkPackage instance" do + child = instance.descendants_of(work_package).first + expect(child.included_in_totals_calculation?).to be false + end + end end context "for the parent" do diff --git a/spec/services/work_packages/update_ancestors_service_spec.rb b/spec/services/work_packages/update_ancestors_service_spec.rb index 1361de2f830b..3ea159cd7a6d 100644 --- a/spec/services/work_packages/update_ancestors_service_spec.rb +++ b/spec/services/work_packages/update_ancestors_service_spec.rb @@ -34,6 +34,7 @@ shared_association_default(:priority) { create(:priority) } shared_association_default(:open_status, factory_name: :status) { create(:status, name: "Open", default_done_ratio: 0) } shared_let(:closed_status) { create(:closed_status, name: "Closed", default_done_ratio: 100) } + shared_let(:rejected_status) { create(:rejected_status, default_done_ratio: 20) } shared_let(:user) { create(:user) } # In order to have dependent values computed, this leverages @@ -85,6 +86,21 @@ def call_update_ancestors_service(work_package) end end end + + context "when changing child status to a status excluded from totals calculation" do + before do + set_attributes_on(child, status: rejected_status) + call_update_ancestors_service(child) + end + + it "still recomputes child remaining work and updates ancestors total % complete excluding it" do + expect_work_packages([parent, child], <<~TABLE) + | subject | status | work | ∑ work | remaining work | ∑ remaining work | % complete | ∑ % complete | + | parent | Open | 10h | 10h | 10h | 10h | 0% | 0% | + | child | Rejected | 5h | | 4h | | 20% | | + TABLE + end + end end context "with parent having nothing set, and 2 children having values set (bug #54179)" do @@ -102,7 +118,6 @@ def call_update_ancestors_service(work_package) end it "sets parent total % complete to 100% and its total remaining work to 0h" do - table_work_packages.map(&:reload) expect_work_packages(table_work_packages, <<~TABLE) hierarchy | status | work | ∑ work | remaining work | ∑ remaining work | % complete | ∑ % complete parent | Open | | 15h | | 0h | 0% | 100% @@ -732,6 +747,52 @@ def call_update_ancestors_service(work_package) TABLE end end + + context "given child becomes excluded from totals calculation because of its status changed to rejected" do + shared_let_work_packages(<<~TABLE) + hierarchy | status | work | ∑ work | remaining work | ∑ remaining work | % complete | ∑ % complete + parent | Open | 10h | 12h | 1h | 8h | 90% | 33% + child | Open | 2h | | 7h | | 29% | + TABLE + + subject(:call_result) do + set_attributes_on(child, status: rejected_status) + call_update_ancestors_service(child) + end + + it "computes parent totals excluding the child from calculations accordingly" do + expect(call_result).to be_success + updated_work_packages = call_result.all_results + expect_work_packages(updated_work_packages, <<~TABLE) + hierarchy | status | work | ∑ work | remaining work | ∑ remaining work | % complete | ∑ % complete + parent | Open | 10h | 10h | 1h | 1h | 90% | 90% + child | Rejected | 2h | | 7h | | 29% | + TABLE + end + end + + context "given child is no longer excluded from totals calculation because of its status changed from rejected" do + shared_let_work_packages(<<~TABLE) + hierarchy | status | work | ∑ work | remaining work | ∑ remaining work | % complete | ∑ % complete + parent | Open | 10h | 10h | 1h | 1h | 90% | 90% + child | Rejected | 2h | | 7h | | 29% | + TABLE + + subject(:call_result) do + set_attributes_on(child, status: open_status) + call_update_ancestors_service(child) + end + + it "computes parent totals excluding the child from calculations accordingly" do + expect(call_result).to be_success + updated_work_packages = call_result.all_results + expect_work_packages(updated_work_packages, <<~TABLE) + hierarchy | status | work | ∑ work | remaining work | ∑ remaining work | % complete | ∑ % complete + parent | Open | 10h | 12h | 1h | 8h | 90% | 33% + child | Open | 2h | | 7h | | 29% | + TABLE + end + end end describe "ignore_non_working_days propagation" do From 5994857b30bba10e0b2d059ee7eec2232c04430b Mon Sep 17 00:00:00 2001 From: Aaron Contreras Date: Tue, 23 Apr 2024 12:31:41 -0500 Subject: [PATCH 006/176] Add `gitlab_chronic_duration` See: https://gitlab.com/gitlab-org/ruby/gems/gitlab-chronic-duration Really nice gem to handle parsing and outputting durations in multiple units. --- Gemfile | 2 ++ Gemfile.lock | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/Gemfile b/Gemfile index c003640842be..81c44704a56c 100644 --- a/Gemfile +++ b/Gemfile @@ -227,6 +227,8 @@ gem "turbo-rails", "~> 2.0.0" gem "httpx" +gem "gitlab_chronic_duration" + group :test do gem "launchy", "~> 3.0.0" gem "rack-test", "~> 2.1.0" diff --git a/Gemfile.lock b/Gemfile.lock index 327b2e5ab26c..8b99d3ff3466 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -556,6 +556,8 @@ GEM fuubar (2.5.1) rspec-core (~> 3.0) ruby-progressbar (~> 1.4) + gitlab_chronic_duration (0.12.0) + numerizer (~> 0.2) glob (0.4.0) globalid (1.2.1) activesupport (>= 6.1) @@ -748,6 +750,7 @@ GEM nokogiri (1.16.4) mini_portile2 (~> 2.8.2) racc (~> 1.4) + numerizer (0.2.0) oj (3.16.3) bigdecimal (>= 3.0) okcomputer (1.18.5) @@ -1216,6 +1219,7 @@ DEPENDENCIES fog-aws friendly_id (~> 5.5.0) fuubar (~> 2.5.0) + gitlab_chronic_duration gon (~> 6.4.0) good_job (= 3.26.2) google-apis-gmail_v1 From ec5b0300d66608753e5e23d8dac459f6332b1a81 Mon Sep 17 00:00:00 2001 From: Aaron Contreras Date: Tue, 23 Apr 2024 14:38:23 -0500 Subject: [PATCH 007/176] Parse and format modal progress fields --- .../work_packages/progress_controller.rb | 21 ++++++++++++------- app/forms/work_packages/progress_form.rb | 13 ++++++++++-- .../work_packages/progress_modal_spec.rb | 21 +++++++++---------- 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/app/controllers/work_packages/progress_controller.rb b/app/controllers/work_packages/progress_controller.rb index a1024129733d..4c64000f87fb 100644 --- a/app/controllers/work_packages/progress_controller.rb +++ b/app/controllers/work_packages/progress_controller.rb @@ -130,7 +130,20 @@ def extract_persisted_progress_attributes def work_package_params params.require(:work_package) - .permit(allowed_params) + .permit(allowed_params).tap do |wp_params| + if wp_params["estimated_hours"].present? + wp_params["estimated_hours"] = + convert_duration_to_hours(wp_params["estimated_hours"]) + end + if wp_params["remaining_hours"].present? + wp_params["remaining_hours"] = + convert_duration_to_hours(wp_params["remaining_hours"]) + end + end + end + + def convert_duration_to_hours(duration) + ChronicDuration.parse(duration, keep_zero: true) / 3600.to_f end def allowed_params @@ -141,12 +154,6 @@ def allowed_params end end - def reject_params_that_dont_differ_from_persisted_values - work_package_params.reject do |key, value| - @persisted_progress_attributes[key.to_s].to_f.to_s == value.to_f.to_s - end - end - def filtered_work_package_params {}.tap do |filtered_params| filtered_params[:estimated_hours] = work_package_params["estimated_hours"] if estimated_hours_touched? diff --git a/app/forms/work_packages/progress_form.rb b/app/forms/work_packages/progress_form.rb index baf36ce3d0ea..f74a1ba00d61 100644 --- a/app/forms/work_packages/progress_form.rb +++ b/app/forms/work_packages/progress_form.rb @@ -97,7 +97,7 @@ def initialize(work_package:, def ensure_only_one_error_for_remaining_work_exceeding_work if work_package.errors.added?(:remaining_hours, :cant_exceed_work) && - work_package.errors.added?(:estimated_hours, :cant_be_inferior_to_remaining_work) + work_package.errors.added?(:estimated_hours, :cant_be_inferior_to_remaining_work) error_to_delete = if @focused_field == :estimated_hours :remaining_hours @@ -156,8 +156,10 @@ def field_value(name) errors = @work_package.errors.where(name) if user_value = errors.map { |error| error.options[:value] }.find { !_1.nil? } user_value - else + elsif name == :done_ratio format_to_smallest_fractional_part(@work_package.public_send(name)) + else + format_to_duration(@work_package.public_send(name)) end end @@ -167,6 +169,13 @@ def format_to_smallest_fractional_part(number) number % 1 == 0 ? number.to_i : number end + def format_to_duration(number) + return number if number.nil? + + # Multiply by 3600 to convert hours to seconds + ChronicDuration.output(number * 3600, keep_zero: true) + end + def default_field_options(name) data = { "work-packages--progress--preview-progress-target": "progressInput", "work-packages--progress--touched-field-marker-target": "progressInput", diff --git a/spec/features/work_packages/progress_modal_spec.rb b/spec/features/work_packages/progress_modal_spec.rb index fee8996468c3..3ce425906147 100644 --- a/spec/features/work_packages/progress_modal_spec.rb +++ b/spec/features/work_packages/progress_modal_spec.rb @@ -340,8 +340,7 @@ def update_work_package_with(work_package, attributes) context "with all values set" do before { update_work_package_with(work_package, estimated_hours: 10.0, remaining_hours: 2.12345) } - it "populates fields with correctly values formatted " \ - "with the minimum fractional part if present, and 2 decimals max" do + it "populates fields with correctly values formatted" do work_package_table.visit_query(progress_query) work_package_table.expect_work_package_listed(work_package) @@ -351,8 +350,8 @@ def update_work_package_with(work_package, attributes) work_edit_field.activate! - work_edit_field.expect_modal_field_value("10") - remaining_work_edit_field.expect_modal_field_value("2.12") + work_edit_field.expect_modal_field_value("10h") + remaining_work_edit_field.expect_modal_field_value("2h 7m 12s") percent_complete_edit_field.expect_modal_field_value("78", readonly: true) end end @@ -382,10 +381,10 @@ def update_work_package_with(work_package, attributes) expect(work_package.estimated_hours).to eq(2.56) expect(work_package.remaining_hours).to eq(0.28) - # work should be displayed as 2.56, and remaining work as 0.28 + # work should be displayed as "2h 33m 36s", and remaining work as "16m 48s" work_edit_field.activate! - work_edit_field.expect_modal_field_value("2.56") - remaining_work_edit_field.expect_modal_field_value("0.28") + work_edit_field.expect_modal_field_value("2h 33m 36s") + remaining_work_edit_field.expect_modal_field_value("16m 48s") end end @@ -534,11 +533,11 @@ def update_work_package_with(work_package, attributes) work_edit_field.set_value("12") page.driver.wait_for_network_idle # Wait for live-update to finish - remaining_work_edit_field.expect_modal_field_value("6") + remaining_work_edit_field.expect_modal_field_value("6h") work_edit_field.set_value("14") page.driver.wait_for_network_idle # Wait for live-update to finish - remaining_work_edit_field.expect_modal_field_value("8") + remaining_work_edit_field.expect_modal_field_value("8h") end specify "Case 3: when work is set to 2h, " \ @@ -556,11 +555,11 @@ def update_work_package_with(work_package, attributes) work_edit_field.set_value("2") page.driver.wait_for_network_idle # Wait for live-update to finish - remaining_work_edit_field.expect_modal_field_value("0") + remaining_work_edit_field.expect_modal_field_value("0h") work_edit_field.set_value("12") page.driver.wait_for_network_idle # Wait for live-update to finish - remaining_work_edit_field.expect_modal_field_value("6") + remaining_work_edit_field.expect_modal_field_value("6h") end end end From f844feb58ecfa98cc48751553876e45dc7a3d8fe Mon Sep 17 00:00:00 2001 From: Aaron Contreras Date: Tue, 7 May 2024 11:02:58 -0500 Subject: [PATCH 008/176] Extract parsing and formatting logic for duration into service --- .../work_packages/progress_controller.rb | 8 +-- app/forms/work_packages/progress_form.rb | 11 +-- app/services/duration_converter.rb | 68 +++++++++++++++++++ spec/services/duration_converter_spec.rb | 67 ++++++++++++++++++ 4 files changed, 139 insertions(+), 15 deletions(-) create mode 100644 app/services/duration_converter.rb create mode 100644 spec/services/duration_converter_spec.rb diff --git a/app/controllers/work_packages/progress_controller.rb b/app/controllers/work_packages/progress_controller.rb index 4c64000f87fb..e56e7c558d12 100644 --- a/app/controllers/work_packages/progress_controller.rb +++ b/app/controllers/work_packages/progress_controller.rb @@ -133,19 +133,15 @@ def work_package_params .permit(allowed_params).tap do |wp_params| if wp_params["estimated_hours"].present? wp_params["estimated_hours"] = - convert_duration_to_hours(wp_params["estimated_hours"]) + DurationConverter.parse(wp_params["estimated_hours"]) end if wp_params["remaining_hours"].present? wp_params["remaining_hours"] = - convert_duration_to_hours(wp_params["remaining_hours"]) + DurationConverter.parse(wp_params["remaining_hours"]) end end end - def convert_duration_to_hours(duration) - ChronicDuration.parse(duration, keep_zero: true) / 3600.to_f - end - def allowed_params if WorkPackage.use_status_for_done_ratio? %i[estimated_hours status_id] diff --git a/app/forms/work_packages/progress_form.rb b/app/forms/work_packages/progress_form.rb index f74a1ba00d61..0e662e9b177e 100644 --- a/app/forms/work_packages/progress_form.rb +++ b/app/forms/work_packages/progress_form.rb @@ -154,12 +154,12 @@ def render_readonly_text_field(group, def field_value(name) errors = @work_package.errors.where(name) - if user_value = errors.map { |error| error.options[:value] }.find { !_1.nil? } + if (user_value = errors.map { |error| error.options[:value] }.find { !_1.nil? }) user_value elsif name == :done_ratio format_to_smallest_fractional_part(@work_package.public_send(name)) else - format_to_duration(@work_package.public_send(name)) + DurationConverter.output(@work_package.public_send(name)) end end @@ -169,13 +169,6 @@ def format_to_smallest_fractional_part(number) number % 1 == 0 ? number.to_i : number end - def format_to_duration(number) - return number if number.nil? - - # Multiply by 3600 to convert hours to seconds - ChronicDuration.output(number * 3600, keep_zero: true) - end - def default_field_options(name) data = { "work-packages--progress--preview-progress-target": "progressInput", "work-packages--progress--touched-field-marker-target": "progressInput", diff --git a/app/services/duration_converter.rb b/app/services/duration_converter.rb new file mode 100644 index 000000000000..757c49281781 --- /dev/null +++ b/app/services/duration_converter.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true + +# -- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2024 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +# ++ + +# We use BigDecimal to handle floating point arithmetic and avoid +# weird floating point results on decimal operations when converting +# hours to seconds on duration outputting. +require "bigdecimal" + +class DurationConverter + class << self + def parse(duration_string) + # Keep 0 values and convert the extracted duration to hours + # by dividing by 3600. + ChronicDuration.parse(duration_string, keep_zero: true, default_unit: "hours") / 3600.to_f + end + + def output(duration_in_hours) + return duration_in_hours if duration_in_hours.nil? + + duration_in_seconds = convert_duration_to_seconds(duration_in_hours) + + # return "0 h" if parsing 0. + # ChronicDuration returns nil when parsing 0. + # By default, its unit is seconds and if we were + # keeping zeroes, we'd format this as "0 secs". + # + # We want to override this behavior. + if ChronicDuration.output(duration_in_seconds, default_unit: "hours").nil? + "0h" + else + ChronicDuration.output(duration_in_seconds, default_unit: "hours", format: :short) + end + end + + private + + def convert_duration_to_seconds(duration_in_hours) + (BigDecimal(duration_in_hours.to_s) * 3600).to_f + end + end +end diff --git a/spec/services/duration_converter_spec.rb b/spec/services/duration_converter_spec.rb new file mode 100644 index 000000000000..e2346afac081 --- /dev/null +++ b/spec/services/duration_converter_spec.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +# -- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2024 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +# ++ + +require "spec_helper" + +RSpec.describe DurationConverter do + describe ".parse" do + it "returns 0 when given 0 duration" do + expect(described_class.parse("0 hrs")).to eq(0) + end + + it "works with ChronicDuration defaults otherwise" do + expect(described_class.parse("5 hrs 30 mins")).to eq(5.5) + end + + it "assumes hours as the default unit for input" do + expect(described_class.parse("5.75")).to eq(5.75) + end + end + + describe ".output" do + it "returns nil when given nil" do + expect(described_class.output(nil)).to be_nil + end + + it "returns 0 h when given 0" do + expect(described_class.output(0)).to eq("0h") + end + + it "works with ChronicDuration defaults otherwise in :short format" do + expect(described_class.output(5.75)) + .to eq("5h 45m") + end + + it "handles floating point numbers gracefully" do + expect(described_class.output(0.28)) + .to eq("16m 48s") + end + end +end From a4ec7b7a81b1a335d11d2c2e22a4a2f43a68d52c Mon Sep 17 00:00:00 2001 From: Aaron Contreras Date: Thu, 9 May 2024 10:11:52 -0500 Subject: [PATCH 009/176] Display chronic durations on all work package contexts --- .../src/app/core/datetime/timezone.service.ts | 5 + .../field-types/work-display-field.module.ts | 12 +- .../progress-popover-edit-field.component.ts | 2 +- .../app/shared/helpers/chronic_duration.d.ts | 31 ++ .../app/shared/helpers/chronic_duration.js | 418 ++++++++++++++++++ 5 files changed, 463 insertions(+), 5 deletions(-) create mode 100644 frontend/src/app/shared/helpers/chronic_duration.d.ts create mode 100644 frontend/src/app/shared/helpers/chronic_duration.js diff --git a/frontend/src/app/core/datetime/timezone.service.ts b/frontend/src/app/core/datetime/timezone.service.ts index e7a152eb572d..2d5a073479e6 100644 --- a/frontend/src/app/core/datetime/timezone.service.ts +++ b/frontend/src/app/core/datetime/timezone.service.ts @@ -31,6 +31,7 @@ import { ConfigurationService } from 'core-app/core/config/configuration.service import { I18nService } from 'core-app/core/i18n/i18n.service'; import * as moment from 'moment-timezone'; import { Moment } from 'moment'; +import { outputChronicDuration } from '../../shared/helpers/chronic_duration'; @Injectable({ providedIn: 'root' }) export class TimezoneService { @@ -139,6 +140,10 @@ export class TimezoneService { } } + public formattedChronicDuration(durationString:string, opts = { format: 'short' }):string { + return outputChronicDuration(this.toHours(durationString) * 3600, opts) || '0h'; + } + public formattedISODate(date:any):string { return this.parseDate(date).format('YYYY-MM-DD'); } diff --git a/frontend/src/app/shared/components/fields/display/field-types/work-display-field.module.ts b/frontend/src/app/shared/components/fields/display/field-types/work-display-field.module.ts index bb7414126d03..db658fc811cc 100644 --- a/frontend/src/app/shared/components/fields/display/field-types/work-display-field.module.ts +++ b/frontend/src/app/shared/components/fields/display/field-types/work-display-field.module.ts @@ -31,8 +31,12 @@ import { InjectField } from 'core-app/shared/helpers/angular/inject-field.decora import { TimezoneService } from 'core-app/core/datetime/timezone.service'; import { ApiV3Service } from 'core-app/core/apiv3/api-v3.service'; import { PathHelperService } from 'core-app/core/path-helper/path-helper.service'; -import { uiStateLinkClass } from 'core-app/features/work-packages/components/wp-fast-table/builders/ui-state-link-builder'; -import { HierarchyQueryLinkHelperService } from 'core-app/shared/components/fields/display/field-types/hierarchy-query-link-helper.service'; +import { + uiStateLinkClass, +} from 'core-app/features/work-packages/components/wp-fast-table/builders/ui-state-link-builder'; +import { + HierarchyQueryLinkHelperService, +} from 'core-app/shared/components/fields/display/field-types/hierarchy-query-link-helper.service'; export class WorkDisplayField extends DisplayField { @InjectField() timezoneService:TimezoneService; @@ -46,7 +50,7 @@ export class WorkDisplayField extends DisplayField { private derivedText = this.I18n.t('js.label_value_derived_from_children'); public get valueString():string { - return this.timezoneService.formattedDuration(this.value as string); + return this.timezoneService.formattedChronicDuration(this.value as string); } /** @@ -65,7 +69,7 @@ export class WorkDisplayField extends DisplayField { const value = this.derivedValue; if (value) { - return this.timezoneService.formattedDuration(value); + return this.timezoneService.formattedChronicDuration(value); } return this.placeholder; } diff --git a/frontend/src/app/shared/components/fields/edit/field-types/progress-popover-edit-field.component.ts b/frontend/src/app/shared/components/fields/edit/field-types/progress-popover-edit-field.component.ts index 1bf2fad7be6d..5f4bd085ff11 100644 --- a/frontend/src/app/shared/components/fields/edit/field-types/progress-popover-edit-field.component.ts +++ b/frontend/src/app/shared/components/fields/edit/field-types/progress-popover-edit-field.component.ts @@ -126,7 +126,7 @@ export class ProgressPopoverEditFieldComponent extends ProgressEditFieldComponen public get asHours():string { if (this.value) { // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - return this.timezoneService.formattedDuration(this.value); + return this.timezoneService.formattedChronicDuration(this.value); } return this.text.placeholder; diff --git a/frontend/src/app/shared/helpers/chronic_duration.d.ts b/frontend/src/app/shared/helpers/chronic_duration.d.ts new file mode 100644 index 000000000000..1d643f08a7b9 --- /dev/null +++ b/frontend/src/app/shared/helpers/chronic_duration.d.ts @@ -0,0 +1,31 @@ +/* + * -- copyright + * OpenProject is an open source project management software. + * Copyright (C) 2024 the OpenProject GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 3. + * + * OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: + * Copyright (C) 2006-2013 Jean-Philippe Lang + * Copyright (C) 2010-2013 the ChiliProject Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * See COPYRIGHT and LICENSE files for more details. + * ++ + */ + +export function outputChronicDuration(duration:number, opts = {}):string|null; diff --git a/frontend/src/app/shared/helpers/chronic_duration.js b/frontend/src/app/shared/helpers/chronic_duration.js new file mode 100644 index 000000000000..1be327fdf633 --- /dev/null +++ b/frontend/src/app/shared/helpers/chronic_duration.js @@ -0,0 +1,418 @@ +/* + * -- copyright + * OpenProject is an open source project management software. + * Copyright (C) 2024 the OpenProject GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 3. + * + * OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: + * Copyright (C) 2006-2013 Jean-Philippe Lang + * Copyright (C) 2010-2013 the ChiliProject Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * See COPYRIGHT and LICENSE files for more details. + * ++ + */ + +/* + * NOTE: + * Changes to this file should be kept in sync with + * https://gitlab.com/gitlab-org/gitlab-chronic-duration/-/blob/master/lib/gitlab_chronic_duration.rb. + */ + +/* eslint-disable */ +export class DurationParseError extends Error { +} + +// On average, there's a little over 4 weeks in month. +const FULL_WEEKS_PER_MONTH = 4; + +const HOURS_PER_DAY = 24; +const DAYS_PER_MONTH = 30; + +const FLOAT_MATCHER = /[0-9]*\.?[0-9]+/g; +const DURATION_UNITS_LIST = ['seconds', 'minutes', 'hours', 'days', 'weeks', 'months', 'years']; + +const MAPPINGS = { + seconds: 'seconds', + second: 'seconds', + secs: 'seconds', + sec: 'seconds', + s: 'seconds', + minutes: 'minutes', + minute: 'minutes', + mins: 'minutes', + min: 'minutes', + m: 'minutes', + hours: 'hours', + hour: 'hours', + hrs: 'hours', + hr: 'hours', + h: 'hours', + days: 'days', + day: 'days', + dy: 'days', + d: 'days', + weeks: 'weeks', + week: 'weeks', + wks: 'weeks', + wk: 'weeks', + w: 'weeks', + months: 'months', + mo: 'months', + mos: 'months', + month: 'months', + years: 'years', + year: 'years', + yrs: 'years', + yr: 'years', + y: 'years', +}; + +const JOIN_WORDS = ['and', 'with', 'plus']; + +function convertToNumber(string) { + const f = parseFloat(string); + return f % 1 > 0 ? f : parseInt(string, 10); +} + +function durationUnitsSecondsMultiplier(unit, opts) { + if (!DURATION_UNITS_LIST.includes(unit)) { + return 0; + } + + const hoursPerDay = opts.hoursPerDay || HOURS_PER_DAY; + const daysPerMonth = opts.daysPerMonth || DAYS_PER_MONTH; + const daysPerWeek = Math.trunc(daysPerMonth / FULL_WEEKS_PER_MONTH); + + switch (unit) { + case 'years': + return 31557600; + case 'months': + return 3600 * hoursPerDay * daysPerMonth; + case 'weeks': + return 3600 * hoursPerDay * daysPerWeek; + case 'days': + return 3600 * hoursPerDay; + case 'hours': + return 3600; + case 'minutes': + return 60; + case 'seconds': + return 1; + default: + return 0; + } +} + +function calculateFromWords(string, opts) { + let val = 0; + const words = string.split(' '); + words.forEach((v, k) => { + if (v === '') { + return; + } + if (v.search(FLOAT_MATCHER) >= 0) { + val += + convertToNumber(v) * + durationUnitsSecondsMultiplier( + words[parseInt(k, 10) + 1] || opts.defaultUnit || 'seconds', + opts, + ); + } + }); + return val; +} + +// Parse 3:41:59 and return 3 hours 41 minutes 59 seconds +function filterByType(string) { + const chronoUnitsList = DURATION_UNITS_LIST.filter((v) => v !== 'weeks'); + if ( + string + .replace(/ +/g, '') + .search(RegExp(`${FLOAT_MATCHER.source}(:${FLOAT_MATCHER.source})+`, 'g')) >= 0 + ) { + const res = []; + string + .replace(/ +/g, '') + .split(':') + .reverse() + .forEach((v, k) => { + if (!chronoUnitsList[k]) { + return; + } + res.push(`${v} ${chronoUnitsList[k]}`); + }); + return res.reverse().join(' '); + } + return string; +} + +// Get rid of unknown words and map found +// words to defined time units +function filterThroughWhiteList(string, opts) { + const res = []; + string.split(' ').forEach((word) => { + if (word === '') { + return; + } + if (word.search(FLOAT_MATCHER) >= 0) { + res.push(word.trim()); + return; + } + const strippedWord = word.trim().replace(/^,/g, '').replace(/,$/g, ''); + if (MAPPINGS[strippedWord] !== undefined) { + res.push(MAPPINGS[strippedWord]); + } else if (!JOIN_WORDS.includes(strippedWord) && opts.raiseExceptions) { + throw new DurationParseError( + `An invalid word ${JSON.stringify(word)} was used in the string to be parsed.`, + ); + } + }); + // add '1' at front if string starts with something recognizable but not with a number, like 'day' or 'minute 30sec' + if (res.length > 0 && MAPPINGS[res[0]]) { + res.splice(0, 0, 1); + } + return res.join(' '); +} + +function cleanup(string, opts) { + let res = string.toLowerCase(); + /* + * TODO The Ruby implementation of this algorithm uses the Numerizer module, + * which converts strings like "forty two" to "42", but there is no + * JavaScript equivalent of Numerizer. Skip it for now until Numerizer is + * ported to JavaScript. + */ + res = filterByType(res); + res = res + .replace(FLOAT_MATCHER, (n) => ` ${n} `) + .replace(/ +/g, ' ') + .trim(); + return filterThroughWhiteList(res, opts); +} + +function humanizeTimeUnit(number, unit, pluralize, keepZero) { + if (number === '0' && !keepZero) { + return null; + } + let res = number + unit; + // A poor man's pluralizer + if (number !== '1' && pluralize) { + res += 's'; + } + return res; +} + +// Given a string representation of elapsed time, +// return an integer (or float, if fractions of a +// second are input) +export function parseChronicDuration(string, opts = {}) { + const result = calculateFromWords(cleanup(string, opts), opts); + return !opts.keepZero && result === 0 ? null : result; +} + +// Given an integer and an optional format, +// returns a formatted string representing elapsed time +export function outputChronicDuration(seconds, opts = {}) { + const units = { + years: 0, + months: 0, + weeks: 0, + days: 0, + hours: 0, + minutes: 0, + seconds, + }; + + const hoursPerDay = opts.hoursPerDay || HOURS_PER_DAY; + const daysPerMonth = opts.daysPerMonth || DAYS_PER_MONTH; + const daysPerWeek = Math.trunc(daysPerMonth / FULL_WEEKS_PER_MONTH); + + const decimalPlaces = + seconds % 1 !== 0 ? seconds.toString().split('.').reverse()[0].length : null; + + const minute = 60; + const hour = 60 * minute; + const day = hoursPerDay * hour; + const month = daysPerMonth * day; + const year = 31557600; + + if (units.seconds >= 31557600 && units.seconds % year < units.seconds % month) { + units.years = Math.trunc(units.seconds / year); + units.months = Math.trunc((units.seconds % year) / month); + units.days = Math.trunc(((units.seconds % year) % month) / day); + units.hours = Math.trunc((((units.seconds % year) % month) % day) / hour); + units.minutes = Math.trunc(((((units.seconds % year) % month) % day) % hour) / minute); + units.seconds = Math.trunc(((((units.seconds % year) % month) % day) % hour) % minute); + } else if (seconds >= 60) { + units.minutes = Math.trunc(seconds / 60); + units.seconds %= 60; + if (units.minutes >= 60) { + units.hours = Math.trunc(units.minutes / 60); + units.minutes = Math.trunc(units.minutes % 60); + if (!opts.limitToHours) { + if (units.hours >= hoursPerDay) { + units.days = Math.trunc(units.hours / hoursPerDay); + units.hours = Math.trunc(units.hours % hoursPerDay); + if (opts.weeks) { + if (units.days >= daysPerWeek) { + units.weeks = Math.trunc(units.days / daysPerWeek); + units.days = Math.trunc(units.days % daysPerWeek); + if (units.weeks >= FULL_WEEKS_PER_MONTH) { + units.months = Math.trunc(units.weeks / FULL_WEEKS_PER_MONTH); + units.weeks = Math.trunc(units.weeks % FULL_WEEKS_PER_MONTH); + } + } + } else if (units.days >= daysPerMonth) { + units.months = Math.trunc(units.days / daysPerMonth); + units.days = Math.trunc(units.days % daysPerMonth); + } + } + } + } + } + + let joiner = opts.joiner || ' '; + let process = null; + + let dividers; + switch (opts.format) { + case 'micro': + dividers = { + years: 'y', + months: 'mo', + weeks: 'w', + days: 'd', + hours: 'h', + minutes: 'm', + seconds: 's', + }; + joiner = ''; + break; + case 'short': + dividers = { + years: 'y', + months: 'mo', + weeks: 'w', + days: 'd', + hours: 'h', + minutes: 'm', + seconds: 's', + }; + break; + case 'long': + dividers = { + /* eslint-disable @gitlab/require-i18n-strings */ + years: ' year', + months: ' month', + weeks: ' week', + days: ' day', + hours: ' hour', + minutes: ' minute', + seconds: ' second', + /* eslint-enable @gitlab/require-i18n-strings */ + pluralize: true, + }; + break; + case 'chrono': + dividers = { + years: ':', + months: ':', + weeks: ':', + days: ':', + hours: ':', + minutes: ':', + seconds: ':', + keepZero: true, + }; + process = (str) => { + // Pad zeros + // Get rid of lead off times if they are zero + // Get rid of lead off zero + // Get rid of trailing: + const divider = ':'; + const processed = []; + str.split(divider).forEach((n) => { + if (n === '') { + return; + } + // add zeros only if n is an integer + if (n.search('\\.') >= 0) { + processed.push( + parseFloat(n) + .toFixed(decimalPlaces) + .padStart(3 + decimalPlaces, '0'), + ); + } else { + processed.push(n.padStart(2, '0')); + } + }); + return processed + .join(divider) + .replace(/^(00:)+/g, '') + .replace(/^0/g, '') + .replace(/:$/g, ''); + }; + joiner = ''; + break; + default: + dividers = { + /* eslint-disable @gitlab/require-i18n-strings */ + years: ' yr', + months: ' mo', + weeks: ' wk', + days: ' day', + hours: ' hr', + minutes: ' min', + seconds: ' sec', + /* eslint-enable @gitlab/require-i18n-strings */ + pluralize: true, + }; + break; + } + + let result = []; + ['years', 'months', 'weeks', 'days', 'hours', 'minutes', 'seconds'].forEach((t) => { + if (t === 'weeks' && !opts.weeks) { + return; + } + let num = units[t]; + if (t === 'seconds' && num % 0 !== 0) { + num = num.toFixed(decimalPlaces); + } else { + num = num.toString(); + } + const keepZero = !dividers.keepZero && t === 'seconds' ? opts.keepZero : dividers.keepZero; + const humanized = humanizeTimeUnit(num, dividers[t], dividers.pluralize, keepZero); + if (humanized !== null) { + result.push(humanized); + } + }); + + if (opts.units) { + result = result.slice(0, opts.units); + } + + result = result.join(joiner); + + if (process) { + result = process(result); + } + + return result.length === 0 ? null : result; +} From 438887d23c3c9f04f60ddebdc60e68617e7f4346 Mon Sep 17 00:00:00 2001 From: Aaron Contreras Date: Thu, 9 May 2024 10:21:10 -0500 Subject: [PATCH 010/176] Format journal entries chronically for work/remaining work --- app/models/work_package/journalized.rb | 2 +- .../lib/journal_formatter.rb | 2 + .../lib/journal_formatter/chronic_duration.rb | 41 +++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 lib_static/plugins/acts_as_journalized/lib/journal_formatter/chronic_duration.rb diff --git a/app/models/work_package/journalized.rb b/app/models/work_package/journalized.rb index 2a8bac58a9aa..310e70c561c4 100644 --- a/app/models/work_package/journalized.rb +++ b/app/models/work_package/journalized.rb @@ -78,7 +78,7 @@ def self.event_url url: JournalizedProcs.event_url register_journal_formatted_fields(:id, "parent_id") - register_journal_formatted_fields(:fraction, + register_journal_formatted_fields(:chronic_duration, "estimated_hours", "derived_estimated_hours", "remaining_hours", "derived_remaining_hours") register_journal_formatted_fields(:percentage, "done_ratio", "derived_done_ratio") diff --git a/lib_static/plugins/acts_as_journalized/lib/journal_formatter.rb b/lib_static/plugins/acts_as_journalized/lib/journal_formatter.rb index e551577fc5e1..4eef2b950f1b 100644 --- a/lib_static/plugins/acts_as_journalized/lib/journal_formatter.rb +++ b/lib_static/plugins/acts_as_journalized/lib/journal_formatter.rb @@ -52,6 +52,7 @@ require_relative "journal_formatter_cache" require_relative "journal_formatter/base" require_relative "journal_formatter/attribute" +require_relative "journal_formatter/chronic_duration" require_relative "journal_formatter/datetime" require_relative "journal_formatter/day_count" require_relative "journal_formatter/decimal" @@ -76,6 +77,7 @@ def self.register_formatted_field(journal_data_type, field, formatter_key) def self.default_formatters { + chronic_duration: JournalFormatter::ChronicDuration, datetime: JournalFormatter::Datetime, day_count: JournalFormatter::DayCount, decimal: JournalFormatter::Decimal, diff --git a/lib_static/plugins/acts_as_journalized/lib/journal_formatter/chronic_duration.rb b/lib_static/plugins/acts_as_journalized/lib/journal_formatter/chronic_duration.rb new file mode 100644 index 000000000000..e83b035f6aa9 --- /dev/null +++ b/lib_static/plugins/acts_as_journalized/lib/journal_formatter/chronic_duration.rb @@ -0,0 +1,41 @@ +# -- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2010-2024 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +# ++ + +module JournalFormatter + class ChronicDuration < Attribute + def format_values(values) + values.map do |v| + if v.nil? + nil + else + ::DurationConverter.output(v.to_f) + end + end + end + end +end From 67b52fdcc1fa1af8ea9dbb02108a5f84a2fbb818 Mon Sep 17 00:00:00 2001 From: Aaron Contreras Date: Mon, 13 May 2024 18:12:38 -0500 Subject: [PATCH 011/176] Adjust specs to new duration formats --- .../costs/spec/features/time_entries_spec.rb | 6 +- .../spec/features/view_own_rates_spec.rb | 2 +- .../activities/work_package_activity_spec.rb | 10 +- .../features/types/form_configuration_spec.rb | 2 +- .../display_fields/spent_time_display_spec.rb | 16 +- .../display_fields/work_display_spec.rb | 26 +-- .../work_packages/edit_work_package_spec.rb | 4 +- .../features/work_packages/index_sums_spec.rb | 172 ++++++++++-------- .../work_packages/remaining_time_spec.rb | 6 +- 9 files changed, 132 insertions(+), 112 deletions(-) diff --git a/modules/costs/spec/features/time_entries_spec.rb b/modules/costs/spec/features/time_entries_spec.rb index 3d6002cc3689..eb7c5c03a421 100644 --- a/modules/costs/spec/features/time_entries_spec.rb +++ b/modules/costs/spec/features/time_entries_spec.rb @@ -54,7 +54,7 @@ let(:wp_table) { Pages::WorkPackagesTable.new(project) } let(:query) do - query = build(:query, user:, project:) + query = build(:query, user:, project:) query.column_names = %w(id subject spent_hours) query.save! @@ -73,8 +73,8 @@ parent_row = wp_table.row(parent) wp_row = wp_table.row(work_package) - expect(parent_row).to have_css(".inline-edit--container.spentTime", text: "12.5 h") - expect(wp_row).to have_css(".inline-edit--container.spentTime", text: "2.5 h") + expect(parent_row).to have_css(".inline-edit--container.spentTime", text: "12h 30m") + expect(wp_row).to have_css(".inline-edit--container.spentTime", text: "2h 30m") end it "creates an activity" do diff --git a/modules/costs/spec/features/view_own_rates_spec.rb b/modules/costs/spec/features/view_own_rates_spec.rb index ae9d5b4b798f..34c5a072d34d 100644 --- a/modules/costs/spec/features/view_own_rates_spec.rb +++ b/modules/costs/spec/features/view_own_rates_spec.rb @@ -109,7 +109,7 @@ it "only displays own entries and rates" do # All the values do not include the entries made by the other user - wp_page.expect_attributes spent_time: "1 h", + wp_page.expect_attributes spent_time: "1h", costs_by_type: "2 Translations", overall_costs: "24.00 EUR", labor_costs: "10.00 EUR", diff --git a/spec/features/activities/work_package_activity_spec.rb b/spec/features/activities/work_package_activity_spec.rb index 7604f302926e..fd72f6f943b8 100644 --- a/spec/features/activities/work_package_activity_spec.rb +++ b/spec/features/activities/work_package_activity_spec.rb @@ -58,13 +58,13 @@ wp_page.expect_and_dismiss_toaster(message: "Successful update.") end - it "displays changed attributes in the activity tab" do + it "displays changed attributes in the activity tab", :aggregate_failures do within("activity-entry", text: admin.name) do expect(page).to have_list_item(text: "% Complete set to 50%") - expect(page).to have_list_item(text: "Work set to 10.00") - expect(page).to have_list_item(text: "Remaining work set to 5.00") - expect(page).to have_list_item(text: "Total work set to 20.00") - expect(page).to have_list_item(text: "Total remaining work set to 8.00") + expect(page).to have_list_item(text: "Work set to 10h") + expect(page).to have_list_item(text: "Remaining work set to 5h") + expect(page).to have_list_item(text: "Total work set to 20h") + expect(page).to have_list_item(text: "Total remaining work set to 8h") expect(page).to have_list_item(text: "Total % complete set to 60%") end end diff --git a/spec/features/types/form_configuration_spec.rb b/spec/features/types/form_configuration_spec.rb index 2b8c93a0a32c..fd4751c28241 100644 --- a/spec/features/types/form_configuration_spec.rb +++ b/spec/features/types/form_configuration_spec.rb @@ -227,7 +227,7 @@ wp_page.expect_group("Estimates and progress") do wp_page.expect_attributes estimated_time: "-" - wp_page.expect_attributes spent_time: "0 h" + wp_page.expect_attributes spent_time: "0h" end # New work package has the same configuration diff --git a/spec/features/work_packages/display_fields/spent_time_display_spec.rb b/spec/features/work_packages/display_fields/spent_time_display_spec.rb index ed7da8592b33..e5db5620d112 100644 --- a/spec/features/work_packages/display_fields/spent_time_display_spec.rb +++ b/spec/features/work_packages/display_fields/spent_time_display_spec.rb @@ -85,7 +85,7 @@ def log_time_via_modal(user_field_visible: true, log_for_user: nil, date: Time.z end.to change(TimeEntry, :count).by(1) # the value is updated automatically - spent_time_field.expect_display_value "1 h" + spent_time_field.expect_display_value "1h" TimeEntry.last.tap do |te| expect(te.work_package).to eq(work_package) @@ -112,7 +112,7 @@ def log_time_via_modal(user_field_visible: true, log_for_user: nil, date: Time.z log_time_via_modal log_for_user: other_user # the value is updated automatically - spent_time_field.expect_display_value "1 h" + spent_time_field.expect_display_value "1h" time_entry = TimeEntry.last expect(time_entry.user).to eq other_user @@ -128,7 +128,7 @@ def log_time_via_modal(user_field_visible: true, log_for_user: nil, date: Time.z log_time_via_modal # the value is updated automatically - spent_time_field.expect_display_value "1 h" + spent_time_field.expect_display_value "1h" end context "with a user with non-one unit numbers", with_settings: { available_languages: %w[en ja] } do @@ -145,7 +145,7 @@ def log_time_via_modal(user_field_visible: true, log_for_user: nil, date: Time.z log_time_via_modal # the value is updated automatically - spent_time_field.expect_display_value "1 h" + spent_time_field.expect_display_value "1h" end end end @@ -164,7 +164,7 @@ def log_time_via_modal(user_field_visible: true, log_for_user: nil, date: Time.z it "shows no logging button within the display field" do spent_time_field.time_log_icon_visible false - spent_time_field.expect_display_value "0 h" + spent_time_field.expect_display_value "0h" end end @@ -188,7 +188,7 @@ def log_time_via_modal(user_field_visible: true, log_for_user: nil, date: Time.z log_time_via_modal user_field_visible: false # the value is updated automatically - spent_time_field.expect_display_value "1 h" + spent_time_field.expect_display_value "1h" end end @@ -213,8 +213,8 @@ def log_time_via_modal(user_field_visible: true, log_for_user: nil, date: Time.z log_time_via_modal - expect(page).to have_css("tr:nth-of-type(1) .wp-table--cell-td.spentTime", text: "1 h") - expect(page).to have_css("tr:nth-of-type(2) .wp-table--cell-td.spentTime", text: "0 h") + expect(page).to have_css("tr:nth-of-type(1) .wp-table--cell-td.spentTime", text: "1h") + expect(page).to have_css("tr:nth-of-type(2) .wp-table--cell-td.spentTime", text: "0h") end end end diff --git a/spec/features/work_packages/display_fields/work_display_spec.rb b/spec/features/work_packages/display_fields/work_display_spec.rb index 2770e732fb37..7bbd7a756e40 100644 --- a/spec/features/work_packages/display_fields/work_display_spec.rb +++ b/spec/features/work_packages/display_fields/work_display_spec.rb @@ -91,7 +91,7 @@ child | 3h | TABLE - include_examples "work display", expected_text: "1 h·Σ 4 h" + include_examples "work display", expected_text: "1h·Σ 4h" end context "with just work" do @@ -101,7 +101,7 @@ child | 0h | TABLE - include_examples "work display", expected_text: "1 h" + include_examples "work display", expected_text: "1h" end context "with just total work with (parent work 0 h)" do @@ -111,7 +111,7 @@ child | 3h | TABLE - include_examples "work display", expected_text: "0 h·Σ 3 h" + include_examples "work display", expected_text: "0h·Σ 3h" end context "with just total work (parent work unset)" do @@ -121,7 +121,7 @@ child | 3h | TABLE - include_examples "work display", expected_text: "-·Σ 3 h" + include_examples "work display", expected_text: "-·Σ 3h" end context "with neither work nor total work (both 0 h)" do @@ -131,7 +131,7 @@ child | 0h | TABLE - include_examples "work display", expected_text: "0 h" + include_examples "work display", expected_text: "0h" end context "with just total work being 0h" do @@ -141,7 +141,7 @@ child | 0h | TABLE - include_examples "work display", expected_text: "-·Σ 0 h" + include_examples "work display", expected_text: "-·Σ 0h" end context "with neither work nor total work (both unset)" do @@ -172,11 +172,11 @@ wp_table.visit_query query # parent - expect(page).to have_content("5 h·Σ 20 h") - expect(page).to have_link("Σ 20 h") + expect(page).to have_content("5h·Σ 20h") + expect(page).to have_link("Σ 20h") # child 2 - expect(page).to have_content("3 h·Σ 15 h") - expect(page).to have_link("Σ 15 h") + expect(page).to have_content("3h·Σ 15h") + expect(page).to have_link("Σ 15h") end context "when clicking the link of a top parent" do @@ -185,7 +185,7 @@ end it "shows a work package table with a parent filter to list the direct children" do - click_on("Σ 20 h") + click_on("Σ 20h") wp_table.expect_work_package_count(4) wp_table.expect_work_package_listed(parent, child1, child2, child3) @@ -202,8 +202,8 @@ end it "shows also all ancestors in the work package table" do - expect(page).to have_content("Work\n3 h·Σ 15 h") - click_on("Σ 15 h") + expect(page).to have_content("Work\n3h·Σ 15h") + click_on("Σ 15h") wp_table.expect_work_package_count(3) wp_table.expect_work_package_listed(parent, child2, grand_child21) diff --git a/spec/features/work_packages/edit_work_package_spec.rb b/spec/features/work_packages/edit_work_package_spec.rb index 8e38c7247872..e7308a5f04ba 100644 --- a/spec/features/work_packages/edit_work_package_spec.rb +++ b/spec/features/work_packages/edit_work_package_spec.rb @@ -143,8 +143,8 @@ def visit! responsible: manager.name, assignee: manager.name, combinedDate: "03/04/2013 - 03/20/2013", - estimatedTime: "10 h", - remainingTime: "7 h", + estimatedTime: "10h", + remainingTime: "7h", percentageDone: "30%", subject: "a new subject", description: "a new description", diff --git a/spec/features/work_packages/index_sums_spec.rb b/spec/features/work_packages/index_sums_spec.rb index 5c894d85da34..f94ea54f76cf 100644 --- a/spec/features/work_packages/index_sums_spec.rb +++ b/spec/features/work_packages/index_sums_spec.rb @@ -144,14 +144,16 @@ wp_table.expect_work_package_listed work_package1, work_package2 # Expect the total sums row - within(:row, "Total sum") do |row| - expect(row).to have_css(".estimatedTime", text: "25 h") - expect(row).to have_css(".remainingTime", text: "12.5 h") - expect(row).to have_css(".#{int_cf.attribute_name(:camel_case)}", text: "12") - expect(row).to have_css(".#{float_cf.attribute_name(:camel_case)}", text: "13.2") - expect(row).to have_css(".laborCosts", text: "15.00 EUR") - expect(row).to have_css(".materialCosts", text: "7.50 EUR") # Unit costs - expect(row).to have_css(".overallCosts", text: "22.50 EUR") + aggregate_failures do + within(:row, "Total sum") do |row| + expect(row).to have_css(".estimatedTime", text: "1d 1h") + expect(row).to have_css(".remainingTime", text: "12h 30m") + expect(row).to have_css(".#{int_cf.attribute_name(:camel_case)}", text: "12") + expect(row).to have_css(".#{float_cf.attribute_name(:camel_case)}", text: "13.2") + expect(row).to have_css(".laborCosts", text: "15.00 EUR") + expect(row).to have_css(".materialCosts", text: "7.50 EUR") # Unit costs + expect(row).to have_css(".overallCosts", text: "22.50 EUR") + end end # Update the sum @@ -160,14 +162,16 @@ wp_table.edit_field(work_package1, :remainingTime) .update "12" - within(:row, "Total sum") do |row| - expect(row).to have_css(".estimatedTime", text: "35 h") - expect(row).to have_css(".remainingTime", text: "19.5 h") - expect(row).to have_css(".#{int_cf.attribute_name(:camel_case)}", text: "12") - expect(row).to have_css(".#{float_cf.attribute_name(:camel_case)}", text: "13.2") - expect(row).to have_css(".laborCosts", text: "15.00 EUR") - expect(row).to have_css(".materialCosts", text: "7.50 EUR") # Unit costs - expect(row).to have_css(".overallCosts", text: "22.50 EUR") + aggregate_failures do + within(:row, "Total sum") do |row| + expect(row).to have_css(".estimatedTime", text: "1d 11h") + expect(row).to have_css(".remainingTime", text: "19h 30m") + expect(row).to have_css(".#{int_cf.attribute_name(:camel_case)}", text: "12") + expect(row).to have_css(".#{float_cf.attribute_name(:camel_case)}", text: "13.2") + expect(row).to have_css(".laborCosts", text: "15.00 EUR") + expect(row).to have_css(".materialCosts", text: "7.50 EUR") # Unit costs + expect(row).to have_css(".overallCosts", text: "22.50 EUR") + end end # Enable groups @@ -179,32 +183,38 @@ first_sum_row, second_sum_row = *find_all(:row, "Sum") # First status row - expect(first_sum_row).to have_css(".estimatedTime", text: "20 h") - expect(first_sum_row).to have_css(".remainingTime", text: "12 h") - expect(first_sum_row).to have_css(".#{int_cf.attribute_name(:camel_case)}", text: "5") - expect(first_sum_row).to have_css(".#{float_cf.attribute_name(:camel_case)}", text: "5.5") - expect(first_sum_row).to have_css(".laborCosts", text: "15.00 EUR") - expect(first_sum_row).to have_css(".materialCosts", text: "7.50 EUR") # Unit costs - expect(first_sum_row).to have_css(".overallCosts", text: "22.50 EUR") + aggregate_failures do + expect(first_sum_row).to have_css(".estimatedTime", text: "20h") + expect(first_sum_row).to have_css(".remainingTime", text: "12h") + expect(first_sum_row).to have_css(".#{int_cf.attribute_name(:camel_case)}", text: "5") + expect(first_sum_row).to have_css(".#{float_cf.attribute_name(:camel_case)}", text: "5.5") + expect(first_sum_row).to have_css(".laborCosts", text: "15.00 EUR") + expect(first_sum_row).to have_css(".materialCosts", text: "7.50 EUR") # Unit costs + expect(first_sum_row).to have_css(".overallCosts", text: "22.50 EUR") + end # Second status row - expect(second_sum_row).to have_css(".estimatedTime", text: "15 h") - expect(second_sum_row).to have_css(".remainingTime", text: "7.5 h") - expect(second_sum_row).to have_css(".#{int_cf.attribute_name(:camel_case)}", text: "7") - expect(second_sum_row).to have_css(".#{float_cf.attribute_name(:camel_case)}", text: "7.7") - expect(second_sum_row).to have_css(".laborCosts", text: "", exact_text: true) - expect(second_sum_row).to have_css(".materialCosts", text: "", exact_text: true) # Unit costs - expect(second_sum_row).to have_css(".overallCosts", text: "", exact_text: true) + aggregate_failures do + expect(second_sum_row).to have_css(".estimatedTime", text: "15h") + expect(second_sum_row).to have_css(".remainingTime", text: "7h 30m") + expect(second_sum_row).to have_css(".#{int_cf.attribute_name(:camel_case)}", text: "7") + expect(second_sum_row).to have_css(".#{float_cf.attribute_name(:camel_case)}", text: "7.7") + expect(second_sum_row).to have_css(".laborCosts", text: "", exact_text: true) + expect(second_sum_row).to have_css(".materialCosts", text: "", exact_text: true) # Unit costs + expect(second_sum_row).to have_css(".overallCosts", text: "", exact_text: true) + end # Total sums row is unchanged - within(:row, "Total sum") do |row| - expect(row).to have_css(".estimatedTime", text: "35 h") - expect(row).to have_css(".remainingTime", text: "19.5 h") - expect(row).to have_css(".#{int_cf.attribute_name(:camel_case)}", text: "12") - expect(row).to have_css(".#{float_cf.attribute_name(:camel_case)}", text: "13.2") - expect(row).to have_css(".laborCosts", text: "15.00 EUR") - expect(row).to have_css(".materialCosts", text: "7.50 EUR") # Unit costs - expect(row).to have_css(".overallCosts", text: "22.50 EUR") + aggregate_failures do + within(:row, "Total sum") do |row| + expect(row).to have_css(".estimatedTime", text: "1d 11h") + expect(row).to have_css(".remainingTime", text: "19h 30m") + expect(row).to have_css(".#{int_cf.attribute_name(:camel_case)}", text: "12") + expect(row).to have_css(".#{float_cf.attribute_name(:camel_case)}", text: "13.2") + expect(row).to have_css(".laborCosts", text: "15.00 EUR") + expect(row).to have_css(".materialCosts", text: "7.50 EUR") # Unit costs + expect(row).to have_css(".overallCosts", text: "22.50 EUR") + end end # Collapsing groups will also hide the sums row @@ -270,14 +280,16 @@ wp_table.expect_work_package_listed work_package1, work_package2, work_package3, work_package4 # Expect the total sums row without filtering - within(:row, "Total sum") do |row| - expect(row).to have_css(".estimatedTime", text: "50 h") - expect(row).to have_css(".remainingTime", text: "25 h") - expect(row).to have_css(".#{int_cf.attribute_name(:camel_case)}", text: "24") - expect(row).to have_css(".#{float_cf.attribute_name(:camel_case)}", text: "26.4") - expect(row).to have_css(".laborCosts", text: "40.00 EUR") - expect(row).to have_css(".materialCosts", text: "18.00 EUR") # Unit costs - expect(row).to have_css(".overallCosts", text: "58.00 EUR") + aggregate_failures do + within(:row, "Total sum") do |row| + expect(row).to have_css(".estimatedTime", text: "2d 2h") + expect(row).to have_css(".remainingTime", text: "1d 1h") + expect(row).to have_css(".#{int_cf.attribute_name(:camel_case)}", text: "24") + expect(row).to have_css(".#{float_cf.attribute_name(:camel_case)}", text: "26.4") + expect(row).to have_css(".laborCosts", text: "40.00 EUR") + expect(row).to have_css(".materialCosts", text: "18.00 EUR") # Unit costs + expect(row).to have_css(".overallCosts", text: "58.00 EUR") + end end # Filter @@ -289,14 +301,16 @@ expect(page).to have_row("WorkPackage", count: 2) # works because the subject name includes "WorkPackage" # Expect the total sums row to have changed - within(:row, "Total sum") do |row| - expect(row).to have_css(".estimatedTime", text: "30 h") - expect(row).to have_css(".remainingTime", text: "15 h") - expect(row).to have_css(".#{int_cf.attribute_name(:camel_case)}", text: "14") - expect(row).to have_css(".#{float_cf.attribute_name(:camel_case)}", text: "15.4") - expect(row).to have_css(".laborCosts", text: "", exact_text: true) - expect(row).to have_css(".materialCosts", text: "", exact_text: true) # Unit costs - expect(row).to have_css(".overallCosts", text: "", exact_text: true) + aggregate_failures do + within(:row, "Total sum") do |row| + expect(row).to have_css(".estimatedTime", text: "1d 6h") + expect(row).to have_css(".remainingTime", text: "15h") + expect(row).to have_css(".#{int_cf.attribute_name(:camel_case)}", text: "14") + expect(row).to have_css(".#{float_cf.attribute_name(:camel_case)}", text: "15.4") + expect(row).to have_css(".laborCosts", text: "", exact_text: true) + expect(row).to have_css(".materialCosts", text: "", exact_text: true) # Unit costs + expect(row).to have_css(".overallCosts", text: "", exact_text: true) + end end # Filter by status open @@ -313,32 +327,38 @@ first_sum_row, second_sum_row = *find_all(:row, "Sum") # First status row - expect(first_sum_row).to have_css(".estimatedTime", text: "10 h") - expect(first_sum_row).to have_css(".remainingTime", text: "5 h") - expect(first_sum_row).to have_css(".#{int_cf.attribute_name(:camel_case)}", text: "5") - expect(first_sum_row).to have_css(".#{float_cf.attribute_name(:camel_case)}", text: "5.5") - expect(first_sum_row).to have_css(".laborCosts", text: "15.00 EUR") - expect(first_sum_row).to have_css(".materialCosts", text: "7.50 EUR") # Unit costs - expect(first_sum_row).to have_css(".overallCosts", text: "22.50 EUR") + aggregate_failures do + expect(first_sum_row).to have_css(".estimatedTime", text: "10h") + expect(first_sum_row).to have_css(".remainingTime", text: "5h") + expect(first_sum_row).to have_css(".#{int_cf.attribute_name(:camel_case)}", text: "5") + expect(first_sum_row).to have_css(".#{float_cf.attribute_name(:camel_case)}", text: "5.5") + expect(first_sum_row).to have_css(".laborCosts", text: "15.00 EUR") + expect(first_sum_row).to have_css(".materialCosts", text: "7.50 EUR") # Unit costs + expect(first_sum_row).to have_css(".overallCosts", text: "22.50 EUR") + end # Second status row - expect(second_sum_row).to have_css(".estimatedTime", text: "15 h") - expect(second_sum_row).to have_css(".remainingTime", text: "7.5 h") - expect(second_sum_row).to have_css(".#{int_cf.attribute_name(:camel_case)}", text: "7") - expect(second_sum_row).to have_css(".#{float_cf.attribute_name(:camel_case)}", text: "7.7") - expect(second_sum_row).to have_css(".laborCosts", text: "", exact_text: true) - expect(second_sum_row).to have_css(".materialCosts", text: "", exact_text: true) # Unit costs - expect(second_sum_row).to have_css(".overallCosts", text: "", exact_text: true) + aggregate_failures do + expect(second_sum_row).to have_css(".estimatedTime", text: "15h") + expect(second_sum_row).to have_css(".remainingTime", text: "7h 30m") + expect(second_sum_row).to have_css(".#{int_cf.attribute_name(:camel_case)}", text: "7") + expect(second_sum_row).to have_css(".#{float_cf.attribute_name(:camel_case)}", text: "7.7") + expect(second_sum_row).to have_css(".laborCosts", text: "", exact_text: true) + expect(second_sum_row).to have_css(".materialCosts", text: "", exact_text: true) # Unit costs + expect(second_sum_row).to have_css(".overallCosts", text: "", exact_text: true) + end # Total sum - within(:row, "Total sum") do |row| - expect(row).to have_css(".estimatedTime", text: "25 h") - expect(row).to have_css(".remainingTime", text: "12.5 h") - expect(row).to have_css(".#{int_cf.attribute_name(:camel_case)}", text: "12") - expect(row).to have_css(".#{float_cf.attribute_name(:camel_case)}", text: "13.2") - expect(row).to have_css(".laborCosts", text: "15.00 EUR") - expect(row).to have_css(".materialCosts", text: "7.50 EUR") # Unit costs - expect(row).to have_css(".overallCosts", text: "22.50 EUR") + aggregate_failures do + within(:row, "Total sum") do |row| + expect(row).to have_css(".estimatedTime", text: "1d 1h") + expect(row).to have_css(".remainingTime", text: "12h 30m") + expect(row).to have_css(".#{int_cf.attribute_name(:camel_case)}", text: "12") + expect(row).to have_css(".#{float_cf.attribute_name(:camel_case)}", text: "13.2") + expect(row).to have_css(".laborCosts", text: "15.00 EUR") + expect(row).to have_css(".materialCosts", text: "7.50 EUR") # Unit costs + expect(row).to have_css(".overallCosts", text: "22.50 EUR") + end end end end diff --git a/spec/features/work_packages/remaining_time_spec.rb b/spec/features/work_packages/remaining_time_spec.rb index 7d253396f69b..7283d7142db5 100644 --- a/spec/features/work_packages/remaining_time_spec.rb +++ b/spec/features/work_packages/remaining_time_spec.rb @@ -50,7 +50,7 @@ # need to update work first to enable the remaining work field wp_page.update_attributes estimatedTime: "200" # rubocop:disable Rails/ActiveRecordAliases wp_page.update_attributes remainingTime: "125" # rubocop:disable Rails/ActiveRecordAliases - wp_page.expect_attributes remainingTime: "125 h" + wp_page.expect_attributes remainingTime: "5d 5h" work_package.reload expect(work_package.remaining_hours).to eq 125.0 @@ -70,8 +70,8 @@ # need to update work first to enable the remaining work field wp_table_page.update_work_package_attributes work_package, estimatedTime: "200" wp_table_page.update_work_package_attributes work_package, remainingTime: "125" - wp_table_page.expect_work_package_with_attributes work_package, remainingTime: "125 h" - wp_table_page.expect_sums_row_with_attributes remainingTime: "125 h" + wp_table_page.expect_work_package_with_attributes work_package, remainingTime: "5d 5h" + wp_table_page.expect_sums_row_with_attributes remainingTime: "5d 5h" work_package.reload expect(work_package.remaining_hours).to eq 125.0 From 58498c9e5e30fbd82519b4e1f195ff684fed5afe Mon Sep 17 00:00:00 2001 From: Aaron Contreras Date: Mon, 13 May 2024 19:04:33 -0500 Subject: [PATCH 012/176] Fix `bin/setup_dev` script Missing dependency in `package-lock.json` --- frontend/package-lock.json | 357 +++++++++++++++++++++++++++++++++++-- 1 file changed, 339 insertions(+), 18 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index a601cbf82fae..4b2bb0aec05d 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -70,7 +70,7 @@ "dragula": "^3.7.3", "expose-loader": "^0.7.5", "flatpickr": "^4.6.13", - "glob": "^7.1.4", + "glob": "^9.0.0", "hammerjs": "^2.0.8", "i18n-js": "^4.3.0", "idiomorph": "^0.3.0", @@ -6305,6 +6305,25 @@ "node": ">= 10" } }, + "node_modules/@vusion/webfonts-generator/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@vusion/webfonts-generator/node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -10861,6 +10880,26 @@ "eslint": ">=7" } }, + "node_modules/esprint/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/esquery": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", @@ -11901,19 +11940,17 @@ "integrity": "sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA==" }, "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "version": "9.3.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", + "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", "dependencies": { "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "minimatch": "^8.0.2", + "minipass": "^4.2.4", + "path-scurry": "^1.6.1" }, "engines": { - "node": "*" + "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -11935,6 +11972,36 @@ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", + "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob/node_modules/minipass": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", + "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "engines": { + "node": ">=8" + } + }, "node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -14364,6 +14431,26 @@ "url": "https://github.com/sponsors/mattlewis92" } }, + "node_modules/karma-coverage-istanbul-reporter/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/karma-coverage-istanbul-reporter/node_modules/istanbul-lib-source-maps": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", @@ -14456,6 +14543,26 @@ "karma": ">=0.9" } }, + "node_modules/karma/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/karma/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -15807,6 +15914,25 @@ "node-gyp-build-test": "build-test.js" } }, + "node_modules/node-gyp/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -18110,6 +18236,25 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/rollup": { "version": "4.14.3", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.14.3.tgz", @@ -19082,6 +19227,26 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/source-map-explorer/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/source-map-explorer/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -19923,6 +20088,25 @@ "node": ">=8" } }, + "node_modules/test-exclude/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/text-encoding-utf-8": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", @@ -26553,6 +26737,19 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -30023,6 +30220,22 @@ "jest-worker": "^27.4.6", "sane": "^5.0.1", "yargs": "^17.3.1" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } } }, "esquery": { @@ -30822,16 +31035,37 @@ "integrity": "sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA==" }, "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "version": "9.3.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", + "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", "requires": { "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "minimatch": "^8.0.2", + "minipass": "^4.2.4", + "path-scurry": "^1.6.1" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", + "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "minipass": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", + "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==" + } } }, "glob-parent": { @@ -32579,6 +32813,20 @@ "yargs": "^16.1.1" }, "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -32655,6 +32903,20 @@ "minimatch": "^3.0.4" }, "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "istanbul-lib-source-maps": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", @@ -33729,6 +33991,21 @@ "semver": "^7.3.5", "tar": "^6.1.2", "which": "^2.0.2" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } } }, "node-gyp-build": { @@ -35409,6 +35686,21 @@ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "requires": { "glob": "^7.1.3" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } } }, "rollup": { @@ -36138,6 +36430,20 @@ "supports-color": "^7.1.0" } }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -36768,6 +37074,21 @@ "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", "minimatch": "^3.0.4" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } } }, "text-encoding-utf-8": { From 4e05da24c1260c098a0bf63a412e5622600a88bc Mon Sep 17 00:00:00 2001 From: Christophe Bliard Date: Tue, 14 May 2024 15:31:12 +0200 Subject: [PATCH 013/176] Table helper can have first line being a comment --- spec/support/table_helpers/table_parser.rb | 15 ++++++--------- .../table_helpers/table_parser_spec.rb | 1 + 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/spec/support/table_helpers/table_parser.rb b/spec/support/table_helpers/table_parser.rb index 80466f3e45d3..4ac10ceee87f 100644 --- a/spec/support/table_helpers/table_parser.rb +++ b/spec/support/table_helpers/table_parser.rb @@ -31,14 +31,12 @@ module TableHelpers class TableParser def parse(representation) - headers, *rows = representation.split("\n") - headers = split(headers) - rows = rows.filter_map { |row| parse_row(row, headers) } - work_packages_data = rows.map.with_index do |row, index| + headers, *rows = representation.split("\n").filter_map { |line| split_line_into_cells(line) } + work_packages_data = rows.map.with_index do |cells, index| { attributes: {}, index:, - row: + row: headers.zip(cells).to_h } end headers.each do |header| @@ -50,13 +48,12 @@ def parse(representation) private - def parse_row(row, headers) - case row + def split_line_into_cells(line) + case line when "", /^\s*#/ # noop else - values = split(row) - headers.zip(values).to_h + split(line) end end diff --git a/spec/support_spec/table_helpers/table_parser_spec.rb b/spec/support_spec/table_helpers/table_parser_spec.rb index 12d0b34e2f16..843d500cd13f 100644 --- a/spec/support_spec/table_helpers/table_parser_spec.rb +++ b/spec/support_spec/table_helpers/table_parser_spec.rb @@ -53,6 +53,7 @@ it "ignores comments and empty lines" do table = <<~TABLE + # this comment is ignored | subject | # this comment and the following empty line are ignored From 2df21d828112d18726878f62c603cbc6b70b82f6 Mon Sep 17 00:00:00 2001 From: Aaron Contreras Date: Tue, 14 May 2024 09:15:25 -0500 Subject: [PATCH 014/176] Ignore chronic_duration.js from eslint This file is sourced from Gitlab's Rails application and provided as `.js`. We therefore don't want to enforce eslint rules on it to keep it prisitine with its upstream source. --- frontend/.eslintignore | 3 ++- frontend/.eslintrc.js | 36 +++++++++++++++++------------------- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/frontend/.eslintignore b/frontend/.eslintignore index 1c7abcc8fb96..97b5851b7071 100644 --- a/frontend/.eslintignore +++ b/frontend/.eslintignore @@ -1,2 +1,3 @@ .eslintrc.js -vendor \ No newline at end of file +vendor +src/app/shared/helpers/chronic_duration.js diff --git a/frontend/.eslintrc.js b/frontend/.eslintrc.js index 0481eb6edfca..79d2b8796959 100644 --- a/frontend/.eslintrc.js +++ b/frontend/.eslintrc.js @@ -25,7 +25,7 @@ module.exports = { project: "./src/tsconfig.app.json", tsconfigRootDir: __dirname, sourceType: "module", - createDefaultProgram: true + createDefaultProgram: true, }, extends: [ "plugin:@typescript-eslint/recommended", @@ -49,11 +49,10 @@ module.exports = { "error", {"type": "element", "prefix": ["op", "opce"], "style": "kebab-case"}, ], - "@angular-eslint/component-class-suffix": ["error", { "suffixes": ["Component", "Example"] }], + "@angular-eslint/component-class-suffix": ["error", {"suffixes": ["Component", "Example"]}], // Warn when new components are being created without OnPush "change-detection-strategy/on-push": "error", - "no-console": [ "error", { @@ -65,8 +64,8 @@ module.exports = { ], // Sometimes we need to shush the TypeScript compiler - "no-unused-vars": ["error", { "varsIgnorePattern": "^_", "argsIgnorePattern": "^_" }], - "@typescript-eslint/no-unused-vars": ["error", { "varsIgnorePattern": "^_", "argsIgnorePattern": "^_" }], + "no-unused-vars": ["error", {"varsIgnorePattern": "^_", "argsIgnorePattern": "^_"}], + "@typescript-eslint/no-unused-vars": ["error", {"varsIgnorePattern": "^_", "argsIgnorePattern": "^_"}], // Who cares about line length "max-len": "off", @@ -75,11 +74,11 @@ module.exports = { "object-curly-newline": "off", // Allow short circuit evaluations - "@typescript-eslint/no-unused-expressions": ["error", { "allowShortCircuit": true }], + "@typescript-eslint/no-unused-expressions": ["error", {"allowShortCircuit": true}], // Force single quotes to align with ruby quotes: "off", - "@typescript-eslint/quotes": ["error", "single", { avoidEscape: true }], + "@typescript-eslint/quotes": ["error", "single", {avoidEscape: true}], // Disable webpack loader definitions "import/no-webpack-loader-syntax": "off", @@ -103,14 +102,14 @@ module.exports = { // No void at all collides with `@typescript-eslint/no-floating-promises` which wants us to handle each promise. // Until we do that, `void` is a good way to explicitly mark unhandled promises. - "no-void": ["error", { allowAsStatement: true }], + "no-void": ["error", {allowAsStatement: true}], // Disable no-use for functions and classes - "no-use-before-define": ["error", { "functions": false, "classes": false }], - "@typescript-eslint/no-use-before-define": ["error", { "functions": false, "classes": false }], + "no-use-before-define": ["error", {"functions": false, "classes": false}], + "@typescript-eslint/no-use-before-define": ["error", {"functions": false, "classes": false}], // Allow subsequent single fields in typescript classes - "@typescript-eslint/lines-between-class-members": ["error", "always", { "exceptAfterSingleLine": true }], + "@typescript-eslint/lines-between-class-members": ["error", "always", {"exceptAfterSingleLine": true}], // Disable indentation rule as it breaks in edge cases and is covered by editorconfig "indent": "off", @@ -162,14 +161,14 @@ module.exports = { allowAfterThisConstructor: false, enforceInMethodNames: true, allowFunctionParams: true, - } + }, ], "no-return-assign": ["error", "except-parens"], - "no-plusplus": ["error", { "allowForLoopAfterthoughts": true }], + "no-plusplus": ["error", {"allowForLoopAfterthoughts": true}], // https://typescript-eslint.io/rules/no-base-to-string/ Disable false positives due to missing types - "@typescript-eslint/no-base-to-string": ["error", { "ignoredTypeNames": ["URI", "Error", "RegExp", "URL", "URLSearchParams"] }], + "@typescript-eslint/no-base-to-string": ["error", {"ignoredTypeNames": ["URI", "Error", "RegExp", "URL", "URLSearchParams"]}], ////////////////////////////////////////////////////////////////////// // Anything below this line should be turned on again at some point // @@ -177,13 +176,12 @@ module.exports = { // It's common in Angular to wrap even pure functions in classes for injection purposes "class-methods-use-this": "off", - } + }, }, { files: ["*.html"], extends: ["plugin:@angular-eslint/template/recommended"], - rules: { - } + rules: {}, }, { files: ["*.spec.ts"], @@ -200,7 +198,7 @@ module.exports = { // Allow more than one class definitions per file (test components) "max-classes-per-file": "off", - } - } + }, + }, ], }; From 147d6ea63c9f14ae23a826ada7da6be07ab0cba2 Mon Sep 17 00:00:00 2001 From: Aaron Contreras Date: Tue, 14 May 2024 09:49:14 -0500 Subject: [PATCH 015/176] Fix eslint complaint about 'eqeqeq' rule --- .../board/add-list-modal/add-list-modal.html | 6 +++--- .../query-filter/query-filter.component.html | 2 +- .../query-filters/query-filters.component.html | 2 +- .../table-pagination.component.html | 14 +++++++------- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/frontend/src/app/features/boards/board/add-list-modal/add-list-modal.html b/frontend/src/app/features/boards/board/add-list-modal/add-list-modal.html index 951c507063a0..b2bc7f75f559 100644 --- a/frontend/src/app/features/boards/board/add-list-modal/add-list-modal.html +++ b/frontend/src/app/features/boards/board/add-list-modal/add-list-modal.html @@ -2,7 +2,7 @@ class="spot-modal spot-modal_autoheight confirm-form-submit--modal loading-indicator--location" data-indicator-name="modal" > -
{{text.title}}
+
{{ text.title }}
@@ -28,14 +28,14 @@ [getOptionsFn]=autocompleterOptions.getOptionsFn (change)="onModelChange($event)" > - + diff --git a/frontend/src/app/features/work-packages/components/filters/query-filter/query-filter.component.html b/frontend/src/app/features/work-packages/components/filters/query-filter/query-filter.component.html index b5b4ff78f2c2..3c750853b7f0 100644 --- a/frontend/src/app/features/work-packages/components/filters/query-filter/query-filter.component.html +++ b/frontend/src/app/features/work-packages/components/filters/query-filter/query-filter.component.html @@ -44,7 +44,7 @@
    -
  • +
  • - + - {{ perPageOption }} + {{ perPageOption }}
From 0be7415a818f220fd29881d9c8a545982ab7c8f4 Mon Sep 17 00:00:00 2001 From: Aaron Contreras Date: Tue, 14 May 2024 15:09:05 -0500 Subject: [PATCH 016/176] Rename WorkingDays constant and route to WorkingDaysAndHours --- ... working_days_and_hours_settings_controller.rb} | 6 +++--- .../show.html.erb | 10 +++++----- config/initializers/menus.rb | 14 +++++++------- config/locales/en.yml | 2 +- config/routes.rb | 2 +- ...ing_days_and_hours_settings_controller_spec.rb} | 7 ++++--- spec/features/admin/working_days_spec.rb | 4 ++-- 7 files changed, 23 insertions(+), 22 deletions(-) rename app/controllers/admin/settings/{working_days_settings_controller.rb => working_days_and_hours_settings_controller.rb} (94%) rename app/views/admin/settings/{working_days_settings => working_days_and_hours_settings}/show.html.erb (88%) rename spec/controllers/admin/settings/{working_days_settings_controller_spec.rb => working_days_and_hours_settings_controller_spec.rb} (91%) diff --git a/app/controllers/admin/settings/working_days_settings_controller.rb b/app/controllers/admin/settings/working_days_and_hours_settings_controller.rb similarity index 94% rename from app/controllers/admin/settings/working_days_settings_controller.rb rename to app/controllers/admin/settings/working_days_and_hours_settings_controller.rb index fa0d390f7e49..15366b7adb52 100644 --- a/app/controllers/admin/settings/working_days_settings_controller.rb +++ b/app/controllers/admin/settings/working_days_and_hours_settings_controller.rb @@ -27,11 +27,11 @@ #++ module Admin::Settings - class WorkingDaysSettingsController < ::Admin::SettingsController - menu_item :working_days + class WorkingDaysAndHoursSettingsController < ::Admin::SettingsController + menu_item :working_days_and_hours def default_breadcrumb - t(:label_working_days) + t(:label_working_days_and_hours) end def failure_callback(call) diff --git a/app/views/admin/settings/working_days_settings/show.html.erb b/app/views/admin/settings/working_days_and_hours_settings/show.html.erb similarity index 88% rename from app/views/admin/settings/working_days_settings/show.html.erb rename to app/views/admin/settings/working_days_and_hours_settings/show.html.erb index da9d61f9fc0e..44314edcb325 100644 --- a/app/views/admin/settings/working_days_settings/show.html.erb +++ b/app/views/admin/settings/working_days_and_hours_settings/show.html.erb @@ -27,18 +27,18 @@ See COPYRIGHT and LICENSE files for more details. ++#%> -<%= toolbar title: t(:label_working_days) %> +<%= toolbar title: t(:label_working_days_and_hours) %>

- <%= t("working_days.warning").html_safe %> + <%= t("working_days.warning").html_safe %>

<%= styled_form_tag( - admin_settings_working_days_path, + admin_settings_working_days_and_hours_path, method: :patch, class: 'op-working-days-admin-settings' ) do %> @@ -54,8 +54,8 @@ See COPYRIGHT and LICENSE files for more details.
<%= setting_multiselect :working_days, - I18n.t('date.day_names').rotate.zip(WeekDay::DAY_RANGE), - direction: :horizontal %> + I18n.t('date.day_names').rotate.zip(WeekDay::DAY_RANGE), + direction: :horizontal %>
diff --git a/config/initializers/menus.rb b/config/initializers/menus.rb index c71ea9bea60d..160e294296d9 100644 --- a/config/initializers/menus.rb +++ b/config/initializers/menus.rb @@ -238,9 +238,9 @@ menu.push :users, { controller: "/users" }, if: Proc.new { - !User.current.admin? && - (User.current.allowed_globally?(:manage_user) || User.current.allowed_globally?(:create_user)) - }, + !User.current.admin? && + (User.current.allowed_globally?(:manage_user) || User.current.allowed_globally?(:create_user)) + }, caption: :label_user_plural, icon: "group" @@ -380,15 +380,15 @@ icon: "enumerations" menu.push :calendars_and_dates, - { controller: "/admin/settings/working_days_settings", action: :show }, + { controller: "/admin/settings/working_days_and_hours_settings", action: :show }, if: Proc.new { User.current.admin? }, caption: :label_calendars_and_dates, icon: "calendar" - menu.push :working_days, - { controller: "/admin/settings/working_days_settings", action: :show }, + menu.push :working_days_and_hours, + { controller: "/admin/settings/working_days_and_hours_settings", action: :show }, if: Proc.new { User.current.admin? }, - caption: :label_working_days, + caption: :label_working_days_and_hours, parent: :calendars_and_dates menu.push :date_format, diff --git a/config/locales/en.yml b/config/locales/en.yml index b5f0bf8751cf..d9906f57c96d 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -2433,7 +2433,7 @@ Project attributes and sections are defined in the "Christmas Eve", "date" => "2022-12-24"), hash_including("name" => "Christmas Eve2", "date" => "2022-12-24"), - hash_including(nwd_to_delete.as_json(only: %i[id name date]).merge("_destroy" => true)) + hash_including(nwd_to_delete.as_json(only: %i[id name + date]).merge("_destroy" => true)) ) end diff --git a/spec/features/admin/working_days_spec.rb b/spec/features/admin/working_days_spec.rb index 23c605c5f76e..516f5900b1f0 100644 --- a/spec/features/admin/working_days_spec.rb +++ b/spec/features/admin/working_days_spec.rb @@ -47,7 +47,7 @@ current_user { admin } before do - visit admin_settings_working_days_path + visit admin_settings_working_days_and_hours_path end describe "week days" do @@ -284,7 +284,7 @@ def working_days_setting # rubocop:disable RSpec/AnyInstance allow_any_instance_of(NonWorkingDay) .to receive(:errors) - .and_return(errors) + .and_return(errors) # rubocop:enable RSpec/AnyInstance delete_button = page.first(".op-non-working-days-list--delete-icon .icon-delete", visible: :all) From 6b4c0dccf203d0f0cf8da404afe1cb0f9b3ee41b Mon Sep 17 00:00:00 2001 From: Christophe Bliard Date: Wed, 15 May 2024 12:35:47 +0200 Subject: [PATCH 017/176] [49409] Handle excluded statuses from totals in update job The job has been updated to excluded work packages having a status with `excluded_from_totals` set to true. The journal entry has valid values so that the cause renders correctly. The job is not yet triggered properly when the "excluded from totals" attribute of a status is changed in the administration. --- app/controllers/statuses_controller.rb | 2 +- app/models/journal.rb | 2 + ..._by_status_excluded_from_totals_changed.rb | 39 ++++++ app/services/settings/update_service.rb | 2 +- ...te_job.rb => apply_statuses_change_job.rb} | 69 +++++++--- ...totals_from_childless_work_packages_job.rb | 2 + .../progress/migrate_values_job.rb | 2 + .../work_packages/progress/sql_commands.rb | 2 + .../progress/sql_commands_for_migration.rb | 59 +++++++++ config/locales/en.yml | 5 + lib/open_project/journal_formatter/cause.rb | 13 ++ .../work_packages_settings_controller_spec.rb | 6 +- spec/controllers/statuses_controller_spec.rb | 8 +- spec/lib/journal_formatter/cause_spec.rb | 84 ++++++++++++ ...c.rb => apply_statuses_change_job_spec.rb} | 120 +++++++++++++++++- 15 files changed, 383 insertions(+), 32 deletions(-) create mode 100644 app/models/journal/caused_by_status_excluded_from_totals_changed.rb rename app/workers/work_packages/progress/{apply_statuses_p_complete_job.rb => apply_statuses_change_job.rb} (60%) create mode 100644 app/workers/work_packages/progress/sql_commands_for_migration.rb rename spec/workers/work_packages/progress/{apply_statuses_p_complete_job_spec.rb => apply_statuses_change_job_spec.rb} (65%) diff --git a/app/controllers/statuses_controller.rb b/app/controllers/statuses_controller.rb index 74bd847206b0..53f549af30b2 100644 --- a/app/controllers/statuses_controller.rb +++ b/app/controllers/statuses_controller.rb @@ -101,7 +101,7 @@ def apply_status_p_complete_change return unless WorkPackage.use_status_for_done_ratio? return unless @status.default_done_ratio_previously_changed? - WorkPackages::Progress::ApplyStatusesPCompleteJob + WorkPackages::Progress::ApplyStatusesChangeJob .perform_later(cause_type: "status_p_complete_changed", status_name: @status.name, status_id: @status.id, diff --git a/app/models/journal.rb b/app/models/journal.rb index fb5f3f329a38..d5e07c2e2751 100644 --- a/app/models/journal.rb +++ b/app/models/journal.rb @@ -71,12 +71,14 @@ class Journal < ApplicationRecord changed_days status_name status_id + status_excluded_from_totals_change status_p_complete_change ], prefix: true VALID_CAUSE_TYPES = %w[ default_attribute_written progress_mode_changed_to_status_based + status_excluded_from_totals_changed status_p_complete_changed system_update work_package_children_changed_times diff --git a/app/models/journal/caused_by_status_excluded_from_totals_changed.rb b/app/models/journal/caused_by_status_excluded_from_totals_changed.rb new file mode 100644 index 000000000000..e80b5b33bda7 --- /dev/null +++ b/app/models/journal/caused_by_status_excluded_from_totals_changed.rb @@ -0,0 +1,39 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2012-2023 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +class Journal::CausedByStatusExcludedFromTotalsChanged < CauseOfChange::Base + def initialize(status_name:, status_id:, status_excluded_from_totals_change:) + additional = { + "status_name" => status_name, + "status_id" => status_id, + "status_excluded_from_totals_change" => status_excluded_from_totals_change + } + + super("status_excluded_from_totals_changed", additional) + end +end diff --git a/app/services/settings/update_service.rb b/app/services/settings/update_service.rb index 836a7381ca2f..255f7af69bee 100644 --- a/app/services/settings/update_service.rb +++ b/app/services/settings/update_service.rb @@ -46,7 +46,7 @@ def set_setting_value(name, value) new_value = derive_value(value) Setting[name] = new_value if name == :work_package_done_ratio && old_value != "status" && new_value == "status" - WorkPackages::Progress::ApplyStatusesPCompleteJob.perform_later(cause_type: "progress_mode_changed_to_status_based") + WorkPackages::Progress::ApplyStatusesChangeJob.perform_later(cause_type: "progress_mode_changed_to_status_based") end end diff --git a/app/workers/work_packages/progress/apply_statuses_p_complete_job.rb b/app/workers/work_packages/progress/apply_statuses_change_job.rb similarity index 60% rename from app/workers/work_packages/progress/apply_statuses_p_complete_job.rb rename to app/workers/work_packages/progress/apply_statuses_change_job.rb index e85e3b0cca63..b5f52315c023 100644 --- a/app/workers/work_packages/progress/apply_statuses_p_complete_job.rb +++ b/app/workers/work_packages/progress/apply_statuses_change_job.rb @@ -28,12 +28,15 @@ # See COPYRIGHT and LICENSE files for more details. #++ -class WorkPackages::Progress::ApplyStatusesPCompleteJob < WorkPackages::Progress::Job +class WorkPackages::Progress::ApplyStatusesChangeJob < WorkPackages::Progress::Job VALID_CAUSE_TYPES = %w[ progress_mode_changed_to_status_based + status_excluded_from_totals_changed status_p_complete_changed ].freeze + attr_reader :cause_type, :status_name, :status_id, :change + # Updates % complete and remaining work of all work packages after a status % # complete value has been changed or the progress calculation mode was set to # status-based. @@ -49,13 +52,16 @@ class WorkPackages::Progress::ApplyStatusesPCompleteJob < WorkPackages::Progress # values of the change. # @return [void] def perform(cause_type:, status_name: nil, status_id: nil, change: nil) - return if WorkPackage.use_field_for_done_ratio? - - journal_cause = journal_cause_from(cause_type, status_name:, status_id:, change:) + @cause_type = cause_type + @status_name = status_name + @status_id = status_id + @change = change with_temporary_progress_table do - set_p_complete_from_status - derive_remaining_work_from_work_and_p_complete + if WorkPackage.use_status_for_done_ratio? + set_p_complete_from_status + derive_remaining_work_from_work_and_p_complete + end update_totals copy_progress_values_to_work_packages_and_update_journals(journal_cause) @@ -64,23 +70,50 @@ def perform(cause_type:, status_name: nil, status_id: nil, change: nil) private - def journal_cause_from(cause_type, status_name:, status_id:, change:) - if VALID_CAUSE_TYPES.exclude?(cause_type) + def journal_cause + assert_valid_cause_type! + + @journal_cause ||= + case cause_type + when "progress_mode_changed_to_status_based" + Journal::CausedByProgressModeChangedToStatusBased.new + when "status_excluded_from_totals_changed" + assert_status_information_present! + Journal::CausedByStatusExcludedFromTotalsChanged.new( + status_name:, + status_id:, + status_excluded_from_totals_change: change + ) + when "status_p_complete_changed" + assert_status_information_present! + Journal::CausedByStatusPCompleteChanged.new( + status_name:, + status_id:, + status_p_complete_change: change + ) + else + raise "Unable to handle cause type #{cause_type.inspect}" + end + end + + def assert_valid_cause_type! + unless VALID_CAUSE_TYPES.include?(cause_type) raise ArgumentError, "Invalid cause type #{cause_type.inspect}. " \ "Valid values are #{VALID_CAUSE_TYPES.inspect}" end + end + + def assert_status_information_present! + if status_name.blank? + raise ArgumentError, "status_name must be provided" + end - case cause_type - when "progress_mode_changed_to_status_based" - { type: cause_type } - when "status_p_complete_changed" - raise ArgumentError, "status_name must be provided" if status_name.blank? - raise ArgumentError, "status_id must be provided" if status_id.nil? - raise ArgumentError, "change must be provided" if change.nil? + if status_id.nil? + raise ArgumentError, "status_id must be provided" + end - { type: cause_type, status_name:, status_id:, status_p_complete_change: change } - else - raise "Unable to handle cause type #{cause_type.inspect}" + if change.nil? + raise ArgumentError, "change must be provided" end end end diff --git a/app/workers/work_packages/progress/migrate_remove_totals_from_childless_work_packages_job.rb b/app/workers/work_packages/progress/migrate_remove_totals_from_childless_work_packages_job.rb index d49f81493b8d..d01e42f7f567 100644 --- a/app/workers/work_packages/progress/migrate_remove_totals_from_childless_work_packages_job.rb +++ b/app/workers/work_packages/progress/migrate_remove_totals_from_childless_work_packages_job.rb @@ -27,6 +27,8 @@ #++ class WorkPackages::Progress::MigrateRemoveTotalsFromChildlessWorkPackagesJob < WorkPackages::Progress::Job + include WorkPackages::Progress::SqlCommandsForMigration + def perform updated_work_package_ids = remove_totals_from_childless_work_packages create_journals_for_updated_work_packages(updated_work_package_ids, cause: journal_cause) diff --git a/app/workers/work_packages/progress/migrate_values_job.rb b/app/workers/work_packages/progress/migrate_values_job.rb index 6e77ee790e3f..212f912d8244 100644 --- a/app/workers/work_packages/progress/migrate_values_job.rb +++ b/app/workers/work_packages/progress/migrate_values_job.rb @@ -27,6 +27,8 @@ #++ class WorkPackages::Progress::MigrateValuesJob < WorkPackages::Progress::Job + include WorkPackages::Progress::SqlCommandsForMigration + attr_reader :current_mode, :previous_mode def perform(current_mode:, previous_mode:) diff --git a/app/workers/work_packages/progress/sql_commands.rb b/app/workers/work_packages/progress/sql_commands.rb index 9ad890a17690..1430503de911 100644 --- a/app/workers/work_packages/progress/sql_commands.rb +++ b/app/workers/work_packages/progress/sql_commands.rb @@ -101,6 +101,8 @@ def update_totals SUM(remaining_hours) AS total_remaining_work FROM work_package_hierarchies wp_tree LEFT JOIN temp_wp_progress_values wp_progress ON wp_tree.descendant_id = wp_progress.id + LEFT JOIN statuses ON wp_progress.status_id = statuses.id + WHERE statuses.excluded_from_totals = FALSE GROUP BY wp_tree.ancestor_id ) totals WHERE temp_wp_progress_values.id = totals.id diff --git a/app/workers/work_packages/progress/sql_commands_for_migration.rb b/app/workers/work_packages/progress/sql_commands_for_migration.rb new file mode 100644 index 000000000000..6842c7e22543 --- /dev/null +++ b/app/workers/work_packages/progress/sql_commands_for_migration.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2012-2024 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +# Specific SQL commands for updating work package progress values during +# migrations, as some methods in `WorkPackages::Progress::SqlCommands` rely on +# fields that may not exist yet. +module WorkPackages::Progress::SqlCommandsForMigration + # Computes total work, total remaining work and total % complete for all work + # packages having children. + def update_totals + execute(<<~SQL.squish) + UPDATE temp_wp_progress_values + SET total_work = totals.total_work, + total_remaining_work = totals.total_remaining_work, + total_p_complete = CASE + WHEN totals.total_work = 0 THEN NULL + ELSE (1 - (totals.total_remaining_work / totals.total_work)) * 100 + END + FROM ( + SELECT wp_tree.ancestor_id AS id, + MAX(generations) AS generations, + SUM(estimated_hours) AS total_work, + SUM(remaining_hours) AS total_remaining_work + FROM work_package_hierarchies wp_tree + LEFT JOIN temp_wp_progress_values wp_progress ON wp_tree.descendant_id = wp_progress.id + GROUP BY wp_tree.ancestor_id + ) totals + WHERE temp_wp_progress_values.id = totals.id + AND totals.generations > 0 + SQL + end +end diff --git a/config/locales/en.yml b/config/locales/en.yml index 538a0bad18ef..169751efa9cc 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1742,6 +1742,7 @@ Project attributes and sections are defined in the - + status '%{status_name}' was included in totals calculations + status_excluded_from_totals_set_to_true_message: >- + status '%{status_name}' was excluded from totals calculations status_p_complete_changed: >- % complete value for status '%{status_name}' changed from %{old_value}% to %{new_value}% system_update: diff --git a/lib/open_project/journal_formatter/cause.rb b/lib/open_project/journal_formatter/cause.rb index cd316b8fcd67..69bc85837de5 100644 --- a/lib/open_project/journal_formatter/cause.rb +++ b/lib/open_project/journal_formatter/cause.rb @@ -64,6 +64,8 @@ def cause_description(cause, html) system_update_message(cause, html) when "working_days_changed" working_days_changed_message(cause["changed_days"]) + when "status_excluded_from_totals_changed" + status_excluded_from_totals_changed_message(cause, html) when "status_p_complete_changed" status_p_complete_changed_message(cause, html) when "progress_mode_changed_to_status_based" @@ -112,6 +114,17 @@ def working_date_change_message(date, working) date: I18n.l(Date.parse(date))) end + def status_excluded_from_totals_changed_message(cause, html) + cause.symbolize_keys => { status_name:, status_excluded_from_totals_change: change} + status_name = html_escape(status_name) if html + + if change == [false, true] + I18n.t("journals.cause_descriptions.status_excluded_from_totals_set_to_true_message", status_name:) + elsif change == [true, false] + I18n.t("journals.cause_descriptions.status_excluded_from_totals_set_to_false_message", status_name:) + end + end + def status_p_complete_changed_message(cause, html) cause.symbolize_keys => { status_name:, status_p_complete_change: [old_value, new_value]} status_name = html_escape(status_name) if html diff --git a/spec/controllers/admin/settings/work_packages_settings_controller_spec.rb b/spec/controllers/admin/settings/work_packages_settings_controller_spec.rb index 93d9a06c2824..0f162cd8b9f9 100644 --- a/spec/controllers/admin/settings/work_packages_settings_controller_spec.rb +++ b/spec/controllers/admin/settings/work_packages_settings_controller_spec.rb @@ -54,7 +54,7 @@ } } expect(Setting.work_package_done_ratio).to eq("status") - expect(WorkPackages::Progress::ApplyStatusesPCompleteJob) + expect(WorkPackages::Progress::ApplyStatusesChangeJob) .to have_been_enqueued.with(cause_type: "progress_mode_changed_to_status_based") perform_enqueued_jobs @@ -76,7 +76,7 @@ work_package_done_ratio: "status" } } - expect(WorkPackages::Progress::ApplyStatusesPCompleteJob) + expect(WorkPackages::Progress::ApplyStatusesChangeJob) .not_to have_been_enqueued end end @@ -93,7 +93,7 @@ work_package_done_ratio: "field" } } - expect(WorkPackages::Progress::ApplyStatusesPCompleteJob) + expect(WorkPackages::Progress::ApplyStatusesChangeJob) .not_to have_been_enqueued end end diff --git a/spec/controllers/statuses_controller_spec.rb b/spec/controllers/statuses_controller_spec.rb index da8e941e2c8e..d0cf513f71fd 100644 --- a/spec/controllers/statuses_controller_spec.rb +++ b/spec/controllers/statuses_controller_spec.rb @@ -143,7 +143,7 @@ it "does not start any jobs to update work packages % complete values" do expect(status.reload).to have_attributes(default_done_ratio: new_default_done_ratio) - expect(WorkPackages::Progress::ApplyStatusesPCompleteJob) + expect(WorkPackages::Progress::ApplyStatusesChangeJob) .not_to have_been_enqueued end end @@ -158,7 +158,7 @@ it "starts a job to update work packages % complete values" do old_default_done_ratio = status.default_done_ratio expect(status.reload).to have_attributes(default_done_ratio: new_default_done_ratio) - expect(WorkPackages::Progress::ApplyStatusesPCompleteJob) + expect(WorkPackages::Progress::ApplyStatusesChangeJob) .to have_been_enqueued.with(cause_type: "status_p_complete_changed", status_name: status.name, status_id: status.id, @@ -175,7 +175,7 @@ let(:status_params) { { default_done_ratio: status.default_done_ratio } } it "does not start any jobs" do - expect(WorkPackages::Progress::ApplyStatusesPCompleteJob) + expect(WorkPackages::Progress::ApplyStatusesChangeJob) .not_to have_been_enqueued end end @@ -184,7 +184,7 @@ let(:status_params) { { name: "Another status name" } } it "does not start any jobs" do - expect(WorkPackages::Progress::ApplyStatusesPCompleteJob) + expect(WorkPackages::Progress::ApplyStatusesChangeJob) .not_to have_been_enqueued end end diff --git a/spec/lib/journal_formatter/cause_spec.rb b/spec/lib/journal_formatter/cause_spec.rb index f85369703a05..85eb7cf5b451 100644 --- a/spec/lib/journal_formatter/cause_spec.rb +++ b/spec/lib/journal_formatter/cause_spec.rb @@ -333,6 +333,90 @@ end end + context "when a status being excluded from totals is the cause" do + shared_let(:status) { create(:status, name: "Rejected") } + let(:cause) do + { + "type" => "status_excluded_from_totals_changed", + "status_name" => status.name, + "status_id" => status.id, + "status_excluded_from_totals_change" => [false, true] + } + end + + context "when rendering HTML variant" do + let(:html) { true } + + it do + expect(subject).to eq "#{I18n.t('journals.caused_changes.status_excluded_from_totals_changed')} " \ + "status 'Rejected' was excluded from totals calculations" + end + + it "escapes the status name" do + cause["status_name"] = "" + expect(subject).to eq "#{I18n.t('journals.caused_changes.status_excluded_from_totals_changed')} " \ + "status '<script>alert('xss')</script>' was excluded from totals calculations" + end + end + + context "when rendering raw variant" do + let(:html) { false } + + it do + expect(subject).to eq "#{I18n.t('journals.caused_changes.status_excluded_from_totals_changed')} " \ + "status 'Rejected' was excluded from totals calculations" + end + + it "does not escape the status name" do + cause["status_name"] = "" + expect(subject).to eq "#{I18n.t('journals.caused_changes.status_excluded_from_totals_changed')} " \ + "status '' was excluded from totals calculations" + end + end + end + + context "when a status being no longer excluded from totals is the cause" do + shared_let(:status) { create(:status, name: "Rejected") } + let(:cause) do + { + "type" => "status_excluded_from_totals_changed", + "status_name" => status.name, + "status_id" => status.id, + "status_excluded_from_totals_change" => [true, false] + } + end + + context "when rendering HTML variant" do + let(:html) { true } + + it do + expect(subject).to eq "#{I18n.t('journals.caused_changes.status_excluded_from_totals_changed')} " \ + "status 'Rejected' was included in totals calculations" + end + + it "escapes the status name" do + cause["status_name"] = "" + expect(subject).to eq "#{I18n.t('journals.caused_changes.status_excluded_from_totals_changed')} " \ + "status '<script>alert('xss')</script>' was included in totals calculations" + end + end + + context "when rendering raw variant" do + let(:html) { false } + + it do + expect(subject).to eq "#{I18n.t('journals.caused_changes.status_excluded_from_totals_changed')} " \ + "status 'Rejected' was included in totals calculations" + end + + it "does not escape the status name" do + cause["status_name"] = "" + expect(subject).to eq "#{I18n.t('journals.caused_changes.status_excluded_from_totals_changed')} " \ + "status '' was included in totals calculations" + end + end + end + context "when a change of progress calculation mode to status-based is the cause" do let(:cause) do { diff --git a/spec/workers/work_packages/progress/apply_statuses_p_complete_job_spec.rb b/spec/workers/work_packages/progress/apply_statuses_change_job_spec.rb similarity index 65% rename from spec/workers/work_packages/progress/apply_statuses_p_complete_job_spec.rb rename to spec/workers/work_packages/progress/apply_statuses_change_job_spec.rb index 185fead8735d..bb7b4ec8266c 100644 --- a/spec/workers/work_packages/progress/apply_statuses_p_complete_job_spec.rb +++ b/spec/workers/work_packages/progress/apply_statuses_change_job_spec.rb @@ -28,11 +28,23 @@ require "rails_helper" -RSpec.describe WorkPackages::Progress::ApplyStatusesPCompleteJob do +RSpec.describe WorkPackages::Progress::ApplyStatusesChangeJob do shared_let(:author) { create(:user) } shared_let(:priority) { create(:priority, name: "Normal") } shared_let(:project) { create(:project, name: "Main project") } + + # statuses for work-based mode shared_let(:status_new) { create(:status, name: "New") } + shared_let(:status_wip) { create(:status, name: "In progress") } + shared_let(:status_closed) { create(:status, name: "Closed") } + + # statuses for status-based mode + shared_let(:status_0p_todo) { create(:status, name: "To do (0%)", default_done_ratio: 0) } + shared_let(:status_40p_doing) { create(:status, name: "Doing (40%)", default_done_ratio: 40) } + shared_let(:status_100p_done) { create(:status, name: "Done (100%)", default_done_ratio: 100) } + + # statuses for both work-based and status-based modes + shared_let(:status_excluded) { create(:status, :excluded_from_totals, name: "Excluded") } before_all do set_factory_default(:user, author) @@ -42,10 +54,6 @@ set_factory_default(:status, status_new) end - shared_let(:status_0p_todo) { create(:status, name: "To do (0%)", default_done_ratio: 0) } - shared_let(:status_40p_doing) { create(:status, name: "Doing (40%)", default_done_ratio: 40) } - shared_let(:status_100p_done) { create(:status, name: "Done (100%)", default_done_ratio: 100) } - subject(:job) { described_class } def expect_performing_job_changes(from:, to:, @@ -85,6 +93,57 @@ def expect_performing_job_changes(from:, to:, ) end end + + context "when a status is being excluded from progress calculation" do + # The work packages are created like if the status is not excluded yet + shared_let_work_packages(<<~TABLE) + hierarchy | status | work | remaining work | % complete | ∑ work | ∑ remaining work | ∑ % complete + grandparent | New | 1h | 0.6h | 40% | 24h | 11.3h | 53% + parent | Excluded | 4h | 1h | 75% | 23h | 10.7h | 53% + child 1 | Excluded | 9h | 7.2h | 20% | | | + child 2 | In progress | 5h | 2.5h | 50% | | | + child 3 | Closed | 5h | 0h | 100% | | | + TABLE + + before do + job.perform_now( + cause_type: "status_excluded_from_totals_changed", + status_name: status_excluded.name, + status_id: status_excluded.id, + change: [false, true] + ) + table_work_packages.map(&:reload) + end + + it "recomputes totals without the values from work packages having the excluded status" do + expect_work_packages(table_work_packages, <<~TABLE) + subject | status | work | remaining work | % complete | ∑ work | ∑ remaining work | ∑ % complete + grandparent | New | 1h | 0.6h | 40% | 11h | 3.1h | 72% + parent | Excluded | 4h | 1h | 75% | 10H | 2.5h | 75% + child 1 | Excluded | 9h | 7.2h | 20% | | | + child 2 | In progress | 5h | 2.5h | 50% | | | + child 3 | Closed | 5h | 0h | 100% | | | + TABLE + end + + it "adds a relevant journal entry for the parent with recomputed total" do + changed_worked_packages = [grandparent, parent] + changed_worked_packages.each do |work_package| + expect(work_package.journals.count).to eq(2), "expected #{work_package} to have a new journal" + last_journal = work_package.last_journal + expect(last_journal.user).to eq(User.system) + expect(last_journal.cause_type).to eq("status_excluded_from_totals_changed") + expect(last_journal.cause_status_name).to eq("Excluded") + expect(last_journal.cause_status_id).to eq(status_excluded.id) + expect(last_journal.cause_status_excluded_from_totals_change).to eq([false, true]) + end + + unchanged_work_packages = table_work_packages - changed_worked_packages + unchanged_work_packages.each do |work_package| + expect(work_package.journals.count).to eq(1), "expected #{work_package} not to have new journals" + end + end + end end context "when in status-based mode", @@ -155,6 +214,57 @@ def expect_performing_job_changes(from:, to:, end end + context "when a status is being excluded from progress calculation" do + # The work packages are created like if the status is not excluded yet + shared_let_work_packages(<<~TABLE) + hierarchy | status | work | remaining work | % complete | ∑ work | ∑ remaining work | ∑ % complete + grandparent | Doing (40%) | 1h | 0.6h | 40% | 24h | 16.6h | 31% + parent | Excluded | 4h | 4h | 0% | 23h | 16h | 30% + child 1 | Excluded | 9h | 9h | 0% | | | + child 2 | Doing (40%) | 5h | 3h | 40% | | | + child 3 | Done (100%) | 5h | 0h | 100% | | | + TABLE + + before do + job.perform_now( + cause_type: "status_excluded_from_totals_changed", + status_name: status_excluded.name, + status_id: status_excluded.id, + change: [false, true] + ) + table_work_packages.map(&:reload) + end + + it "recomputes totals without the values from work packages having the excluded status" do + expect_work_packages(table_work_packages, <<~TABLE) + subject | status | work | remaining work | % complete | ∑ work | ∑ remaining work | ∑ % complete + grandparent | Doing (40%) | 1h | 0.6h | 40% | 11h | 3.6h | 67% + parent | Excluded | 4h | 4h | 0% | 10h | 3h | 70% + child 1 | Excluded | 9h | 9h | 0% | | | + child 2 | Doing (40%) | 5h | 3h | 40% | | | + child 3 | Done (100%) | 5h | 0h | 100% | | | + TABLE + end + + it "adds a relevant journal entry for the parent with recomputed total" do + changed_worked_packages = [grandparent, parent] + changed_worked_packages.each do |work_package| + expect(work_package.journals.count).to eq(2), "expected #{work_package} to have a new journal" + last_journal = work_package.last_journal + expect(last_journal.user).to eq(User.system) + expect(last_journal.cause_type).to eq("status_excluded_from_totals_changed") + expect(last_journal.cause_status_name).to eq("Excluded") + expect(last_journal.cause_status_id).to eq(status_excluded.id) + expect(last_journal.cause_status_excluded_from_totals_change).to eq([false, true]) + end + + unchanged_work_packages = table_work_packages - changed_worked_packages + unchanged_work_packages.each do |work_package| + expect(work_package.journals.count).to eq(1), "expected #{work_package} not to have new journals" + end + end + end + describe "journals" do # rubocop:disable RSpec/ExampleLength it "creates journal entries for modified work packages on status % complete change" do From 4dae890c89c156acc6ed6978ddce93b21113081c Mon Sep 17 00:00:00 2001 From: Christophe Bliard Date: Fri, 17 May 2024 10:48:53 +0200 Subject: [PATCH 018/176] refactor: Make spec more focused and legible Use 2 custom matchers to test rendering. It avoids creating contexts to set different values fro `html`. The rspec output with documentation formatter also looks nicer. --- spec/lib/journal_formatter/cause_spec.rb | 607 ++++++++++------------- 1 file changed, 275 insertions(+), 332 deletions(-) diff --git a/spec/lib/journal_formatter/cause_spec.rb b/spec/lib/journal_formatter/cause_spec.rb index 85eb7cf5b451..b8c6995e8080 100644 --- a/spec/lib/journal_formatter/cause_spec.rb +++ b/spec/lib/journal_formatter/cause_spec.rb @@ -36,14 +36,15 @@ shared_let(:work_package) { create(:work_package) } let(:instance) { described_class.new(build(:work_package_journal)) } - let(:link) do + let(:work_package_html_link) do link_to_work_package(work_package, all_link: true) end + let(:work_package_raw_link) { "##{work_package.id}" } # we need to tell the url_helper that there is not controller to get url_options so that we can call link_to let(:controller) { nil } - subject do + def render(cause, html:) if Journal::VALID_CAUSE_TYPES.exclude?(cause["type"]) raise "#{cause['type'].inspect} is not a valid cause type from Journal::VALID_CAUSE_TYPES. " \ "Please use one of #{Journal::VALID_CAUSE_TYPES}" @@ -52,197 +53,211 @@ instance.render("cause", [nil, cause], html:) end + RSpec::Matchers.define :render_html_variant do |expected| + match do |cause| + @cause = cause + @actual = render(cause, html: true) + values_match? expected, @actual + end + + description do + "render HTML variant with #{surface_descriptions_in(expected).inspect}" + end + + failure_message do |actual| + "expected #{@cause} to render HTML variant as expected\n " \ + "expected: #{surface_descriptions_in(expected).inspect}\n " \ + "actual: #{actual.inspect}" + end + end + + RSpec::Matchers.define :render_raw_variant do |expected| + match do |cause| + @cause = cause + @actual = render(cause, html: false) + values_match? expected, @actual + end + + description do + "render raw text variant with #{surface_descriptions_in(expected).inspect}" + end + + failure_message do |actual| + "expected #{@cause} to render raw text variant as expected\n " \ + "expected: #{surface_descriptions_in(expected).inspect}\n " \ + "actual: #{actual.inspect}" + end + end + + shared_examples "XSS-proof rendering of status name" do + before do + cause["status_name"] = "" + end + + it "escapes the status name when rendering HTML" do + expect(cause).to render_html_variant(a_string_including("<script>alert('xss')</script>")) + end + + it "does not escape the status name when rendering raw text" do + expect(cause).to render_raw_variant(a_string_including("")) + end + end + context "when the change was caused by a change to the parent" do - let(:cause) do + subject(:cause) do { "type" => "work_package_parent_changed_times", "work_package_id" => work_package.id } end - context "when rendering HTML variant" do - let(:html) { true } - - context "when the user is able to access the related work package" do - before do - allow(WorkPackage).to receive(:visible).with(User.current).and_return(WorkPackage.where(id: work_package.id)) - end - - it do - expect(subject).to eq "#{I18n.t('journals.caused_changes.dates_changed')} " \ - "#{I18n.t('journals.cause_descriptions.work_package_parent_changed_times', link:)}" - end + context "when the user is able to access the related work package" do + before do + allow(WorkPackage).to receive(:visible).with(User.current).and_return(WorkPackage.where(id: work_package.id)) end - context "when the user is not able to access the related work package" do - before do - allow(WorkPackage).to receive(:visible).with(User.current).and_return(WorkPackage.none) - end + it do + link = work_package_html_link + expect(cause).to render_html_variant( + "#{I18n.t('journals.caused_changes.dates_changed')} " \ + "#{I18n.t('journals.cause_descriptions.work_package_parent_changed_times', link:)}" + ) + end - it do - expect(subject).to eq "#{I18n.t('journals.caused_changes.dates_changed')} " \ - "#{I18n.t('journals.cause_descriptions.unaccessable_work_package_changed')}" - end + it do + link = work_package_raw_link + expect(cause).to render_raw_variant( + "#{I18n.t('journals.caused_changes.dates_changed')} " \ + "#{I18n.t('journals.cause_descriptions.work_package_parent_changed_times', link:)}" + ) end end - context "when rendering raw variant" do - let(:html) { false } - - context "when the user is able to access the related work package" do - before do - allow(WorkPackage).to receive(:visible).with(User.current).and_return(WorkPackage.where(id: work_package.id)) - end - - let(:link) { "##{work_package.id}" } - - it do - expect(subject).to eq "#{I18n.t('journals.caused_changes.dates_changed')} " \ - "#{I18n.t('journals.cause_descriptions.work_package_parent_changed_times', link:)}" - end + context "when the user is not able to access the related work package" do + before do + allow(WorkPackage).to receive(:visible).with(User.current).and_return(WorkPackage.none) end - context "when the user is not able to access the related work package" do - before do - allow(WorkPackage).to receive(:visible).with(User.current).and_return(WorkPackage.none) - end + it do + expect(cause).to render_html_variant( + "#{I18n.t('journals.caused_changes.dates_changed')} " \ + "#{I18n.t('journals.cause_descriptions.unaccessable_work_package_changed')}" + ) + end - it do - expect(subject).to eq "#{I18n.t('journals.caused_changes.dates_changed')} " \ - "#{I18n.t('journals.cause_descriptions.unaccessable_work_package_changed')}" - end + it do + expect(cause).to render_raw_variant( + "#{I18n.t('journals.caused_changes.dates_changed')} " \ + "#{I18n.t('journals.cause_descriptions.unaccessable_work_package_changed')}" + ) end end end context "when the change was caused by a change to a predecessor" do - let(:cause) do + subject(:cause) do { "type" => "work_package_predecessor_changed_times", "work_package_id" => work_package.id } end - context "when rendering HTML variant" do - let(:html) { true } - - context "when the user is able to access the related work package" do - before do - allow(WorkPackage).to receive(:visible).with(User.current).and_return(WorkPackage.where(id: work_package.id)) - end - - it do - expect(subject).to eq "#{I18n.t('journals.caused_changes.dates_changed')} " \ - "#{I18n.t('journals.cause_descriptions.work_package_predecessor_changed_times', link:)}" - end + context "when the user is able to access the related work package" do + before do + allow(WorkPackage).to receive(:visible).with(User.current).and_return(WorkPackage.where(id: work_package.id)) end - context "when the user is not able to access the related work package" do - before do - allow(WorkPackage).to receive(:visible).with(User.current).and_return(WorkPackage.none) - end + it do + link = work_package_html_link + expect(cause).to render_html_variant( + "#{I18n.t('journals.caused_changes.dates_changed')} " \ + "#{I18n.t('journals.cause_descriptions.work_package_predecessor_changed_times', link:)}" + ) + end - it do - expect(subject).to eq "#{I18n.t('journals.caused_changes.dates_changed')} " \ - "#{I18n.t('journals.cause_descriptions.unaccessable_work_package_changed')}" - end + it do + link = work_package_raw_link + expect(cause).to render_raw_variant( + "#{I18n.t('journals.caused_changes.dates_changed')} " \ + "#{I18n.t('journals.cause_descriptions.work_package_predecessor_changed_times', link:)}" + ) end end - context "when rendering raw variant" do - let(:html) { false } - - context "when the user is able to access the related work package" do - before do - allow(WorkPackage).to receive(:visible).with(User.current).and_return(WorkPackage.where(id: work_package.id)) - end - - let(:link) { "##{work_package.id}" } - - it do - expect(subject).to eq "#{I18n.t('journals.caused_changes.dates_changed')} " \ - "#{I18n.t('journals.cause_descriptions.work_package_predecessor_changed_times', link:)}" - end + context "when the user is not able to access the related work package" do + before do + allow(WorkPackage).to receive(:visible).with(User.current).and_return(WorkPackage.none) end - context "when the user is not able to access the related work package" do - before do - allow(WorkPackage).to receive(:visible).with(User.current).and_return(WorkPackage.none) - end + it do + expect(cause).to render_html_variant( + "#{I18n.t('journals.caused_changes.dates_changed')} " \ + "#{I18n.t('journals.cause_descriptions.unaccessable_work_package_changed')}" + ) + end - it do - expect(subject).to eq "#{I18n.t('journals.caused_changes.dates_changed')} " \ - "#{I18n.t('journals.cause_descriptions.unaccessable_work_package_changed')}" - end + it do + expect(cause).to render_raw_variant( + "#{I18n.t('journals.caused_changes.dates_changed')} " \ + "#{I18n.t('journals.cause_descriptions.unaccessable_work_package_changed')}" + ) end end end context "when the change was caused by a change to a child" do - let(:cause) do + subject(:cause) do { "type" => "work_package_children_changed_times", "work_package_id" => work_package.id } end - context "when rendering HTML variant" do - let(:html) { true } - - context "when the user is able to access the related work package" do - before do - allow(WorkPackage).to receive(:visible).with(User.current).and_return(WorkPackage.where(id: work_package.id)) - end - - it do - expect(subject).to eq "#{I18n.t('journals.caused_changes.dates_changed')} " \ - "#{I18n.t('journals.cause_descriptions.work_package_children_changed_times', link:)}" - end + context "when the user is able to access the related work package" do + before do + allow(WorkPackage).to receive(:visible).with(User.current).and_return(WorkPackage.where(id: work_package.id)) end - context "when the user is not able to access the related work package" do - before do - allow(WorkPackage).to receive(:visible).with(User.current).and_return(WorkPackage.none) - end + it do + link = work_package_html_link + expect(cause).to render_html_variant( + "#{I18n.t('journals.caused_changes.dates_changed')} " \ + "#{I18n.t('journals.cause_descriptions.work_package_children_changed_times', link:)}" + ) + end - it do - expect(subject).to eq "#{I18n.t('journals.caused_changes.dates_changed')} " \ - "#{I18n.t('journals.cause_descriptions.unaccessable_work_package_changed')}" - end + it do + link = work_package_raw_link + expect(cause).to render_raw_variant( + "#{I18n.t('journals.caused_changes.dates_changed')} " \ + "#{I18n.t('journals.cause_descriptions.work_package_children_changed_times', link:)}" + ) end end - context "when rendering raw variant" do - let(:html) { false } - - context "when the user is able to access the related work package" do - before do - allow(WorkPackage).to receive(:visible).with(User.current).and_return(WorkPackage.where(id: work_package.id)) - end - - let(:link) { "##{work_package.id}" } - - it do - expect(subject).to eq "#{I18n.t('journals.caused_changes.dates_changed')} " \ - "#{I18n.t('journals.cause_descriptions.work_package_children_changed_times', link:)}" - end + context "when the user is not able to access the related work package" do + before do + allow(WorkPackage).to receive(:visible).with(User.current).and_return(WorkPackage.none) end - context "when the user is not able to access the related work package" do - before do - allow(WorkPackage).to receive(:visible).with(User.current).and_return(WorkPackage.none) - end + it do + expect(cause).to render_html_variant( + "#{I18n.t('journals.caused_changes.dates_changed')} " \ + "#{I18n.t('journals.cause_descriptions.unaccessable_work_package_changed')}" + ) + end - it do - expect(subject).to eq "#{I18n.t('journals.caused_changes.dates_changed')} " \ - "#{I18n.t('journals.cause_descriptions.unaccessable_work_package_changed')}" - end + it do + expect(cause).to render_raw_variant( + "#{I18n.t('journals.caused_changes.dates_changed')} " \ + "#{I18n.t('journals.cause_descriptions.unaccessable_work_package_changed')}" + ) end end end context "when the change was caused by working day changes" do - let(:cause) do + subject(:cause) do { "type" => "working_days_changed", "changed_days" => { @@ -259,40 +274,36 @@ } end - context "when rendering HTML variant" do - let(:html) { true } - - it do - changes = [ - I18n.t("journals.cause_descriptions.working_days_changed.days.non_working", day: WeekDay.find_by!(day: 2).name), - I18n.t("journals.cause_descriptions.working_days_changed.days.working", day: WeekDay.find_by!(day: 6).name), - I18n.t("journals.cause_descriptions.working_days_changed.dates.working", date: I18n.l(Date.new(2023, 1, 1))), - I18n.t("journals.cause_descriptions.working_days_changed.dates.non_working", date: I18n.l(Date.new(2023, 12, 24))) - ].join(", ") - expect(subject).to eq "#{I18n.t('journals.caused_changes.dates_changed')} " \ - "#{I18n.t('journals.cause_descriptions.working_days_changed.changed', changes:)}" - end - end - - context "when rendering raw variant" do - let(:html) { false } - - it do - changes = [ - I18n.t("journals.cause_descriptions.working_days_changed.days.non_working", day: WeekDay.find_by!(day: 2).name), - I18n.t("journals.cause_descriptions.working_days_changed.days.working", day: WeekDay.find_by!(day: 6).name), - I18n.t("journals.cause_descriptions.working_days_changed.dates.working", date: I18n.l(Date.new(2023, 1, 1))), - I18n.t("journals.cause_descriptions.working_days_changed.dates.non_working", date: I18n.l(Date.new(2023, 12, 24))) - ].join(", ") - expect(subject).to eq "#{I18n.t('journals.caused_changes.dates_changed')} " \ - "#{I18n.t('journals.cause_descriptions.working_days_changed.changed', changes:)}" - end + it do + changes = [ + I18n.t("journals.cause_descriptions.working_days_changed.days.non_working", day: WeekDay.find_by!(day: 2).name), + I18n.t("journals.cause_descriptions.working_days_changed.days.working", day: WeekDay.find_by!(day: 6).name), + I18n.t("journals.cause_descriptions.working_days_changed.dates.working", date: I18n.l(Date.new(2023, 1, 1))), + I18n.t("journals.cause_descriptions.working_days_changed.dates.non_working", date: I18n.l(Date.new(2023, 12, 24))) + ].join(", ") + expect(cause).to render_html_variant( + "#{I18n.t('journals.caused_changes.dates_changed')} " \ + "#{I18n.t('journals.cause_descriptions.working_days_changed.changed', changes:)}" + ) + end + + it do + changes = [ + I18n.t("journals.cause_descriptions.working_days_changed.days.non_working", day: WeekDay.find_by!(day: 2).name), + I18n.t("journals.cause_descriptions.working_days_changed.days.working", day: WeekDay.find_by!(day: 6).name), + I18n.t("journals.cause_descriptions.working_days_changed.dates.working", date: I18n.l(Date.new(2023, 1, 1))), + I18n.t("journals.cause_descriptions.working_days_changed.dates.non_working", date: I18n.l(Date.new(2023, 12, 24))) + ].join(", ") + expect(cause).to render_raw_variant( + "#{I18n.t('journals.caused_changes.dates_changed')} " \ + "#{I18n.t('journals.cause_descriptions.working_days_changed.changed', changes:)}" + ) end end context "when a change of status % complete is the cause" do shared_let(:status) { create(:status, name: "In progress", default_done_ratio: 40) } - let(:cause) do + subject(:cause) do { "type" => "status_p_complete_changed", "status_name" => status.name, @@ -301,41 +312,26 @@ } end - context "when rendering HTML variant" do - let(:html) { true } - - it do - expect(subject).to eq "#{I18n.t('journals.caused_changes.status_p_complete_changed')} " \ - "% complete value for status 'In progress' changed from 20% to 40%" - end - - it "escapes the status name" do - cause["status_name"] = "" - expect(subject).to eq "#{I18n.t('journals.caused_changes.status_p_complete_changed')} " \ - "% complete value for status '<script>alert('xss')</script>' " \ - "changed from 20% to 40%" - end + it do + expect(cause).to render_html_variant( + "#{I18n.t('journals.caused_changes.status_p_complete_changed')} " \ + "% complete value for status 'In progress' changed from 20% to 40%" + ) end - context "when rendering raw variant" do - let(:html) { false } - - it do - expect(subject).to eq "#{I18n.t('journals.caused_changes.status_p_complete_changed')} " \ - "% complete value for status 'In progress' changed from 20% to 40%" - end - - it "does not escape the status name" do - cause["status_name"] = "" - expect(subject).to eq "#{I18n.t('journals.caused_changes.status_p_complete_changed')} " \ - "% complete value for status '' changed from 20% to 40%" - end + it do + expect(cause).to render_raw_variant( + "#{I18n.t('journals.caused_changes.status_p_complete_changed')} " \ + "% complete value for status 'In progress' changed from 20% to 40%" + ) end + + it_behaves_like "XSS-proof rendering of status name" end context "when a status being excluded from totals is the cause" do shared_let(:status) { create(:status, name: "Rejected") } - let(:cause) do + subject(:cause) do { "type" => "status_excluded_from_totals_changed", "status_name" => status.name, @@ -344,40 +340,26 @@ } end - context "when rendering HTML variant" do - let(:html) { true } - - it do - expect(subject).to eq "#{I18n.t('journals.caused_changes.status_excluded_from_totals_changed')} " \ - "status 'Rejected' was excluded from totals calculations" - end - - it "escapes the status name" do - cause["status_name"] = "" - expect(subject).to eq "#{I18n.t('journals.caused_changes.status_excluded_from_totals_changed')} " \ - "status '<script>alert('xss')</script>' was excluded from totals calculations" - end + it do + expect(cause).to render_html_variant( + "Status Excluded from totals changed " \ + "status 'Rejected' was excluded from totals calculations" + ) end - context "when rendering raw variant" do - let(:html) { false } - - it do - expect(subject).to eq "#{I18n.t('journals.caused_changes.status_excluded_from_totals_changed')} " \ - "status 'Rejected' was excluded from totals calculations" - end - - it "does not escape the status name" do - cause["status_name"] = "" - expect(subject).to eq "#{I18n.t('journals.caused_changes.status_excluded_from_totals_changed')} " \ - "status '' was excluded from totals calculations" - end + it do + expect(cause).to render_raw_variant( + "Status Excluded from totals changed " \ + "status 'Rejected' was excluded from totals calculations" + ) end + + it_behaves_like "XSS-proof rendering of status name" end context "when a status being no longer excluded from totals is the cause" do shared_let(:status) { create(:status, name: "Rejected") } - let(:cause) do + subject(:cause) do { "type" => "status_excluded_from_totals_changed", "status_name" => status.name, @@ -386,190 +368,151 @@ } end - context "when rendering HTML variant" do - let(:html) { true } - - it do - expect(subject).to eq "#{I18n.t('journals.caused_changes.status_excluded_from_totals_changed')} " \ - "status 'Rejected' was included in totals calculations" - end - - it "escapes the status name" do - cause["status_name"] = "" - expect(subject).to eq "#{I18n.t('journals.caused_changes.status_excluded_from_totals_changed')} " \ - "status '<script>alert('xss')</script>' was included in totals calculations" - end + it do + expect(cause).to render_html_variant( + "Status Excluded from totals changed " \ + "status 'Rejected' was included in totals calculations" + ) end - context "when rendering raw variant" do - let(:html) { false } - - it do - expect(subject).to eq "#{I18n.t('journals.caused_changes.status_excluded_from_totals_changed')} " \ - "status 'Rejected' was included in totals calculations" - end - - it "does not escape the status name" do - cause["status_name"] = "" - expect(subject).to eq "#{I18n.t('journals.caused_changes.status_excluded_from_totals_changed')} " \ - "status '' was included in totals calculations" - end + it do + expect(cause).to render_raw_variant( + "Status Excluded from totals changed " \ + "status 'Rejected' was included in totals calculations" + ) end + + it_behaves_like "XSS-proof rendering of status name" end context "when a change of progress calculation mode to status-based is the cause" do - let(:cause) do + subject(:cause) do { "type" => "progress_mode_changed_to_status_based" } end - context "when rendering HTML variant" do - let(:html) { true } - - it do - expect(subject).to eq "#{I18n.t('journals.caused_changes.progress_mode_changed_to_status_based')} " \ - "Progress calculation mode set to status-based" - end + it do + expect(cause).to render_html_variant( + "Progress calculation updated " \ + "Progress calculation mode set to status-based" + ) end - context "when rendering raw variant" do - let(:html) { false } - - it do - expect(subject).to eq "#{I18n.t('journals.caused_changes.progress_mode_changed_to_status_based')} " \ - "Progress calculation mode set to status-based" - end + it do + expect(cause).to render_raw_variant( + "Progress calculation updated " \ + "Progress calculation mode set to status-based" + ) end end context "when cause is a system update: change of progress calculation mode from disabled to work-based" do - let(:cause) do + subject(:cause) do { "type" => "system_update", "feature" => "progress_calculation_adjusted_from_disabled_mode" } end - context "when rendering HTML variant" do - let(:html) { true } - - it do - href = OpenProject::Static::Links.links[:blog_article_progress_changes][:href] - expect(subject).to eq "OpenProject system update: Progress calculation automatically " \ - "set to work-based mode and adjusted with version update." - end + it do + href = OpenProject::Static::Links.links[:blog_article_progress_changes][:href] + expect(cause).to render_html_variant( + "OpenProject system update: Progress calculation automatically " \ + "set to work-based mode and adjusted with version update." + ) end - context "when rendering raw variant" do - let(:html) { false } - - it do - expect(subject).to eq "OpenProject system update: Progress calculation automatically " \ - "set to work-based mode and adjusted with version update." - end + it do + expect(cause).to render_raw_variant( + "OpenProject system update: Progress calculation automatically " \ + "set to work-based mode and adjusted with version update." + ) end end context "when cause is a system update: progress calculation adjusted" do - let(:cause) do + subject(:cause) do { "type" => "system_update", "feature" => "progress_calculation_adjusted" } end - context "when rendering HTML variant" do - let(:html) { true } - - it do - href = OpenProject::Static::Links.links[:blog_article_progress_changes][:href] - expect(subject).to eq "OpenProject system update: Progress calculation automatically " \ - "adjusted with version update." - end + it do + href = OpenProject::Static::Links.links[:blog_article_progress_changes][:href] + expect(cause).to render_html_variant( + "OpenProject system update: Progress calculation automatically " \ + "adjusted with version update." + ) end - context "when rendering raw variant" do - let(:html) { false } - - it do - expect(subject).to eq "OpenProject system update: Progress calculation automatically " \ - "adjusted with version update." - end + it do + expect(cause).to render_raw_variant( + "OpenProject system update: Progress calculation automatically adjusted with version update." + ) end context "with previous feature key 'progress_calculation_changed'" do - let(:cause) do - { - "type" => "system_update", - "feature" => "progress_calculation_changed" - } + before do + cause["feature"] = "progress_calculation_changed" end - let(:html) { false } it "is rendered like 'progress_calculation_adjusted'" do - expect(subject).to eq "OpenProject system update: Progress calculation automatically " \ - "adjusted with version update." + expect(cause).to render_raw_variant( + "OpenProject system update: Progress calculation automatically adjusted with version update." + ) end end end context "when cause is a system update: totals removed from childless work packages" do - let(:cause) do + subject(:cause) do { "type" => "system_update", "feature" => "totals_removed_from_childless_work_packages" } end - context "when rendering HTML variant" do - let(:html) { true } - - it do - href = OpenProject::Static::Links.links[:release_notes_14_0_1][:href] - expect(subject).to eq "OpenProject system update: Work and progress totals " \ - "automatically removed for non-parent work packages with " \ - "version update. " \ - "This is a maintenance task and can be safely ignored." - end + it do + href = OpenProject::Static::Links.links[:release_notes_14_0_1][:href] + expect(cause).to render_html_variant( + "OpenProject system update: Work and progress totals " \ + "automatically removed for non-parent work packages with " \ + "version update. " \ + "This is a maintenance task and can be safely ignored." + ) end - context "when rendering raw variant" do - let(:html) { false } - - it do - expect(subject).to eq "OpenProject system update: Work and progress totals " \ - "automatically removed for non-parent work packages with " \ - "version update. " \ - "This is a maintenance task and can be safely ignored." - end + it do + expect(cause).to render_raw_variant( + "OpenProject system update: Work and progress totals " \ + "automatically removed for non-parent work packages with version update. " \ + "This is a maintenance task and can be safely ignored." + ) end end context "when the change was caused by a system update" do - let(:cause) do + subject(:cause) do { "type" => "system_update", "feature" => "file_links_journal" } end - context "when rendering HTML variant" do - let(:html) { true } - - it do - expect(subject).to eq "#{I18n.t('journals.caused_changes.system_update')} " \ - "#{I18n.t('journals.cause_descriptions.system_update.file_links_journal')}" - end + it do + expect(cause).to render_html_variant( + "#{I18n.t('journals.caused_changes.system_update')} " \ + "#{I18n.t('journals.cause_descriptions.system_update.file_links_journal')}" + ) end - context "when rendering raw variant" do - let(:html) { false } - - it do - expect(subject).to eq "#{I18n.t('journals.caused_changes.system_update')} " \ - "#{I18n.t('journals.cause_descriptions.system_update.file_links_journal')}" - end + it do + expect(cause).to render_raw_variant( + "#{I18n.t('journals.caused_changes.system_update')} " \ + "#{I18n.t('journals.cause_descriptions.system_update.file_links_journal')}" + ) end end end From 4f674c622ffc8d34d6a778f4f418056cef59d6bf Mon Sep 17 00:00:00 2001 From: Christophe Bliard Date: Fri, 17 May 2024 16:55:58 +0200 Subject: [PATCH 019/176] Use double-quotes --- app/models/permitted_params.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/models/permitted_params.rb b/app/models/permitted_params.rb index 6ed1a45ae846..c768af525dd3 100644 --- a/app/models/permitted_params.rb +++ b/app/models/permitted_params.rb @@ -26,7 +26,7 @@ # See COPYRIGHT and LICENSE files for more details. #++ -require 'permitted_params/allowed_settings' +require "permitted_params/allowed_settings" class PermittedParams # This class intends to provide a method for all params hashes coming from the @@ -162,7 +162,7 @@ def query p = params.require(:query).permit(*self.class.permitted_attributes[:query]) p[:sort_criteria] = params .require(:query) - .permit(sort_criteria: { '0' => [], '1' => [], '2' => [] }) + .permit(sort_criteria: { "0" => [], "1" => [], "2" => [] }) p[:sort_criteria].delete :sort_criteria p end @@ -340,7 +340,7 @@ def message(project = nil) end def attachments - params.permit(attachments: %i[file description id])['attachments'] + params.permit(attachments: %i[file description id])["attachments"] end def enumerations @@ -407,7 +407,7 @@ def custom_field_values(key = nil, required: true) # Reject blank values from include_hidden select fields values.each { |_, v| v.compact_blank! if v.is_a?(Array) } - values.empty? ? {} : { 'custom_field_values' => values.permit! } + values.empty? ? {} : { "custom_field_values" => values.permit! } end def permitted_attributes(key, additions = {}) @@ -529,7 +529,7 @@ def self.permitted_attributes :subject, Proc.new do |args| # avoid costly allowed_in_project? if the param is not there at all - if args[:params]['work_package']&.has_key?('watcher_user_ids') && + if args[:params]["work_package"]&.has_key?("watcher_user_ids") && args[:current_user].allowed_in_project?(:add_work_package_watchers, args[:project]) { watcher_user_ids: [] } From 4b5292de3f30eeee241cc139af5bef22053b56d0 Mon Sep 17 00:00:00 2001 From: Christophe Bliard Date: Fri, 17 May 2024 17:00:12 +0200 Subject: [PATCH 020/176] [49409] Update UI to allow marking a status as excluded from totals The column headers of the statuses page have a shorter text to fit a reasonable page width. --- app/components/statuses/row_component.rb | 4 +++ app/components/statuses/table_component.rb | 7 ++-- app/controllers/statuses_controller.rb | 17 +++++++++- app/models/permitted_params.rb | 1 + app/views/statuses/_form.html.erb | 8 +++++ config/locales/en.yml | 9 +++++ spec/controllers/statuses_controller_spec.rb | 35 +++++++++++++++++++- 7 files changed, 76 insertions(+), 5 deletions(-) diff --git a/app/components/statuses/row_component.rb b/app/components/statuses/row_component.rb index 8c2f1d8d6b6c..0533192cbb81 100644 --- a/app/components/statuses/row_component.rb +++ b/app/components/statuses/row_component.rb @@ -50,6 +50,10 @@ def readonly? checkmark(status.is_readonly?) end + def excluded_from_totals? + checkmark(status.excluded_from_totals?) + end + def color helpers.icon_for_color status.color end diff --git a/app/components/statuses/table_component.rb b/app/components/statuses/table_component.rb index b0c5dbadf554..240cf1490e55 100644 --- a/app/components/statuses/table_component.rb +++ b/app/components/statuses/table_component.rb @@ -60,9 +60,10 @@ def headers [:name, { caption: Status.human_attribute_name(:name) }], [:color, { caption: Status.human_attribute_name(:color) }], [:done_ratio, { caption: WorkPackage.human_attribute_name(:done_ratio) }], - [:default?, { caption: Status.human_attribute_name(:is_default) }], - [:closed?, { caption: Status.human_attribute_name(:is_closed) }], - [:readonly?, { caption: Status.human_attribute_name(:is_readonly) }], + [:default?, { caption: I18n.t("statuses.index.headers.is_default") }], + [:closed?, { caption: I18n.t("statuses.index.headers.is_closed") }], + [:readonly?, { caption: I18n.t("statuses.index.headers.is_readonly") }], + [:excluded_from_totals?, { caption: I18n.t("statuses.index.headers.excluded_from_totals") }], [:sort, { caption: I18n.t(:label_sort) }] ] end diff --git a/app/controllers/statuses_controller.rb b/app/controllers/statuses_controller.rb index 53f549af30b2..691ee4bf2716 100644 --- a/app/controllers/statuses_controller.rb +++ b/app/controllers/statuses_controller.rb @@ -61,7 +61,7 @@ def create def update @status = Status.find(params[:id]) if @status.update(permitted_params.status) - apply_status_p_complete_change + recompute_progress_values flash[:notice] = I18n.t(:notice_successful_update) redirect_to action: "index" else @@ -97,6 +97,11 @@ def show_local_breadcrumb true end + def recompute_progress_values + apply_status_p_complete_change + apply_status_excluded_from_totals_change + end + def apply_status_p_complete_change return unless WorkPackage.use_status_for_done_ratio? return unless @status.default_done_ratio_previously_changed? @@ -107,4 +112,14 @@ def apply_status_p_complete_change status_id: @status.id, change: @status.default_done_ratio_previous_change) end + + def apply_status_excluded_from_totals_change + return unless @status.excluded_from_totals_previously_changed? + + WorkPackages::Progress::ApplyStatusesChangeJob + .perform_later(cause_type: "status_excluded_from_totals_changed", + status_name: @status.name, + status_id: @status.id, + change: @status.excluded_from_totals_previous_change) + end end diff --git a/app/models/permitted_params.rb b/app/models/permitted_params.rb index c768af525dd3..d7a6eda9347f 100644 --- a/app/models/permitted_params.rb +++ b/app/models/permitted_params.rb @@ -596,6 +596,7 @@ def self.permitted_attributes name color_id default_done_ratio + excluded_from_totals is_closed is_default is_readonly diff --git a/app/views/statuses/_form.html.erb b/app/views/statuses/_form.html.erb index 6122dec98b7b..d2e43dab8592 100644 --- a/app/views/statuses/_form.html.erb +++ b/app/views/statuses/_form.html.erb @@ -34,6 +34,7 @@ See COPYRIGHT and LICENSE files for more details.
<%= f.select :default_done_ratio, (0..100).step(10).map { |r| ["#{r} %", r] }, + { container_class: "-xslim" }, label: WorkPackage.human_attribute_name(:done_ratio) %>
<%= f.check_box "is_closed" %>
@@ -63,6 +64,13 @@ See COPYRIGHT and LICENSE files for more details. <% end %> +
+ <%= f.check_box "excluded_from_totals" %> +
+

<%= t("statuses.edit.status_excluded_from_totals_text") %>

+
+
+ <%= render partial: "/colors/color_autocomplete_field", locals: { form: f, diff --git a/config/locales/en.yml b/config/locales/en.yml index 169751efa9cc..c94024669163 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -478,12 +478,20 @@ Project attributes and sections are defined in the Note: Inherited values (e.g., from children or relations) will still apply. + status_excluded_from_totals_text: |- + Check this option to exclude work packages with this status from totals of Work, + Remaining work, and % Complete in a hierarchy. status_color_text: | Click to assign or change the color of this status. It is shown in the status button and can be used for highlighting work packages in the table. index: no_results_title_text: There are currently no work package statuses. no_results_content_text: Add a new status + headers: + is_default: "Default" + is_closed: "Closed" + is_readonly: "Read-only" + excluded_from_totals: "Excluded from totals" themes: light: "Light" @@ -676,6 +684,7 @@ Project attributes and sections are defined in the "status_excluded_from_totals_changed") + end + end + + context "when changing something else than default % complete or exclude from totals" do let(:status_params) { { name: "Another status name" } } it "does not start any jobs" do From e03d626897ceaa0b0bd054ace9075c122f048787 Mon Sep 17 00:00:00 2001 From: Christophe Bliard Date: Wed, 22 May 2024 14:45:39 +0200 Subject: [PATCH 021/176] [49409] Update cause messages for status changes - Update the messages according to latest specification - Update the journal cause to handle multiple changes in one cause --- app/controllers/statuses_controller.rb | 25 ++--- app/models/journal.rb | 6 +- ...changed.rb => caused_by_status_changed.rb} | 8 +- ..._by_status_excluded_from_totals_changed.rb | 39 -------- .../progress/apply_statuses_change_job.rb | 33 +++---- config/locales/en.yml | 12 +-- ...luded_from_totals_changed_journal_cause.rb | 48 ++++++++++ lib/open_project/journal_formatter/cause.rb | 81 ++++++++-------- spec/controllers/statuses_controller_spec.rb | 94 +++++++++++++++++-- spec/lib/journal_formatter/cause_spec.rb | 60 +++++++----- .../apply_statuses_change_job_spec.rb | 36 +++---- 11 files changed, 261 insertions(+), 181 deletions(-) rename app/models/journal/{caused_by_status_p_complete_changed.rb => caused_by_status_changed.rb} (84%) delete mode 100644 app/models/journal/caused_by_status_excluded_from_totals_changed.rb create mode 100644 db/migrate/20240522073759_fix_status_excluded_from_totals_changed_journal_cause.rb diff --git a/app/controllers/statuses_controller.rb b/app/controllers/statuses_controller.rb index 691ee4bf2716..c3b0e10784f1 100644 --- a/app/controllers/statuses_controller.rb +++ b/app/controllers/statuses_controller.rb @@ -98,28 +98,15 @@ def show_local_breadcrumb end def recompute_progress_values - apply_status_p_complete_change - apply_status_excluded_from_totals_change - end - - def apply_status_p_complete_change - return unless WorkPackage.use_status_for_done_ratio? - return unless @status.default_done_ratio_previously_changed? - - WorkPackages::Progress::ApplyStatusesChangeJob - .perform_later(cause_type: "status_p_complete_changed", - status_name: @status.name, - status_id: @status.id, - change: @status.default_done_ratio_previous_change) - end - - def apply_status_excluded_from_totals_change - return unless @status.excluded_from_totals_previously_changed? + attributes_triggering_recomputing = ["excluded_from_totals"] + attributes_triggering_recomputing << "default_done_ratio" if WorkPackage.use_status_for_done_ratio? + changes = @status.previous_changes.slice(*attributes_triggering_recomputing) + return if changes.empty? WorkPackages::Progress::ApplyStatusesChangeJob - .perform_later(cause_type: "status_excluded_from_totals_changed", + .perform_later(cause_type: "status_changed", status_name: @status.name, status_id: @status.id, - change: @status.excluded_from_totals_previous_change) + changes:) end end diff --git a/app/models/journal.rb b/app/models/journal.rb index d5e07c2e2751..1a9229a397a3 100644 --- a/app/models/journal.rb +++ b/app/models/journal.rb @@ -71,15 +71,13 @@ class Journal < ApplicationRecord changed_days status_name status_id - status_excluded_from_totals_change - status_p_complete_change + status_changes ], prefix: true VALID_CAUSE_TYPES = %w[ default_attribute_written progress_mode_changed_to_status_based - status_excluded_from_totals_changed - status_p_complete_changed + status_changed system_update work_package_children_changed_times work_package_parent_changed_times diff --git a/app/models/journal/caused_by_status_p_complete_changed.rb b/app/models/journal/caused_by_status_changed.rb similarity index 84% rename from app/models/journal/caused_by_status_p_complete_changed.rb rename to app/models/journal/caused_by_status_changed.rb index da648aca57d6..4e28458fbc75 100644 --- a/app/models/journal/caused_by_status_p_complete_changed.rb +++ b/app/models/journal/caused_by_status_changed.rb @@ -26,14 +26,14 @@ # See COPYRIGHT and LICENSE files for more details. #++ # -class Journal::CausedByStatusPCompleteChanged < CauseOfChange::Base - def initialize(status_name:, status_id:, status_p_complete_change:) +class Journal::CausedByStatusChanged < CauseOfChange::Base + def initialize(status_name:, status_id:, status_changes:) additional = { "status_name" => status_name, "status_id" => status_id, - "status_p_complete_change" => status_p_complete_change + "status_changes" => status_changes } - super("status_p_complete_changed", additional) + super("status_changed", additional) end end diff --git a/app/models/journal/caused_by_status_excluded_from_totals_changed.rb b/app/models/journal/caused_by_status_excluded_from_totals_changed.rb deleted file mode 100644 index e80b5b33bda7..000000000000 --- a/app/models/journal/caused_by_status_excluded_from_totals_changed.rb +++ /dev/null @@ -1,39 +0,0 @@ -#-- copyright -# OpenProject is an open source project management software. -# Copyright (C) 2012-2023 the OpenProject GmbH -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License version 3. -# -# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -# Copyright (C) 2006-2013 Jean-Philippe Lang -# Copyright (C) 2010-2013 the ChiliProject Team -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# 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 General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# See COPYRIGHT and LICENSE files for more details. -#++ - -class Journal::CausedByStatusExcludedFromTotalsChanged < CauseOfChange::Base - def initialize(status_name:, status_id:, status_excluded_from_totals_change:) - additional = { - "status_name" => status_name, - "status_id" => status_id, - "status_excluded_from_totals_change" => status_excluded_from_totals_change - } - - super("status_excluded_from_totals_changed", additional) - end -end diff --git a/app/workers/work_packages/progress/apply_statuses_change_job.rb b/app/workers/work_packages/progress/apply_statuses_change_job.rb index b5f52315c023..304a1ba2c79a 100644 --- a/app/workers/work_packages/progress/apply_statuses_change_job.rb +++ b/app/workers/work_packages/progress/apply_statuses_change_job.rb @@ -31,31 +31,31 @@ class WorkPackages::Progress::ApplyStatusesChangeJob < WorkPackages::Progress::Job VALID_CAUSE_TYPES = %w[ progress_mode_changed_to_status_based - status_excluded_from_totals_changed - status_p_complete_changed + status_changed ].freeze - attr_reader :cause_type, :status_name, :status_id, :change + attr_reader :cause_type, :status_name, :status_id, :changes # Updates % complete and remaining work of all work packages after a status % # complete value has been changed or the progress calculation mode was set to # status-based. # - # It creates a journal entry with the System user describing the change. + # It creates a journal entry with the System user describing the changes. # # @param status_name [String] The cause of the update to be put in the journal # entry. Must be one of `VALID_CAUSE_TYPES`. # @param status_name [String] The name of the status to apply. # @param status_id [Integer] The ID of the status to apply. Not used # currently, but here in case we need it in a later version. - # @param change [Object] The change object containing an array of [old, new] - # values of the change. + # @param changes [Object] The changes object containing an map of array of + # [old, new] values of the change, for instance + # `{"default_done_ratio" => [20, 40], "excluded_from_totals" => [false, true]}`. # @return [void] - def perform(cause_type:, status_name: nil, status_id: nil, change: nil) + def perform(cause_type:, status_name: nil, status_id: nil, changes: nil) @cause_type = cause_type @status_name = status_name @status_id = status_id - @change = change + @changes = changes with_temporary_progress_table do if WorkPackage.use_status_for_done_ratio? @@ -77,19 +77,12 @@ def journal_cause case cause_type when "progress_mode_changed_to_status_based" Journal::CausedByProgressModeChangedToStatusBased.new - when "status_excluded_from_totals_changed" + when "status_changed" assert_status_information_present! - Journal::CausedByStatusExcludedFromTotalsChanged.new( + Journal::CausedByStatusChanged.new( status_name:, status_id:, - status_excluded_from_totals_change: change - ) - when "status_p_complete_changed" - assert_status_information_present! - Journal::CausedByStatusPCompleteChanged.new( - status_name:, - status_id:, - status_p_complete_change: change + status_changes: changes ) else raise "Unable to handle cause type #{cause_type.inspect}" @@ -112,8 +105,8 @@ def assert_status_information_present! raise ArgumentError, "status_id must be provided" end - if change.nil? - raise ArgumentError, "change must be provided" + if changes.nil? + raise ArgumentError, "changes must be provided" end end end diff --git a/config/locales/en.yml b/config/locales/en.yml index c94024669163..dea895bac8a7 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1750,8 +1750,7 @@ Project attributes and sections are defined in the - - status '%{status_name}' was included in totals calculations - status_excluded_from_totals_set_to_true_message: >- - status '%{status_name}' was excluded from totals calculations - status_p_complete_changed: >- - % complete value for status '%{status_name}' changed from %{old_value}% to %{new_value}% + status_excluded_from_totals_set_to_false_message: now included in hierarchy totals + status_excluded_from_totals_set_to_true_message: now excluded from hierarchy totals + status_percent_complete_changed: "% complete changed from %{old_value}% to %{new_value}%" system_update: file_links_journal: > From now on, activity related to file links (files stored in external storages) will appear here in the diff --git a/db/migrate/20240522073759_fix_status_excluded_from_totals_changed_journal_cause.rb b/db/migrate/20240522073759_fix_status_excluded_from_totals_changed_journal_cause.rb new file mode 100644 index 000000000000..33f181c2f129 --- /dev/null +++ b/db/migrate/20240522073759_fix_status_excluded_from_totals_changed_journal_cause.rb @@ -0,0 +1,48 @@ +# Update journal entries from this: +# +# { +# "type" => "status_p_complete_changed", +# "status_name" => status.name, +# "status_id" => status.id, +# "status_p_complete_change" => [20, 40] +# } +# +# to this: +# +# { +# "type" => "status_changed", +# "status_name" => status.name, +# "status_id" => status.id, +# "status_changes" => { "default_done_ratio" => [20, 40] } +# } +# +# structure needed to handle multiple changes in one cause +class FixStatusExcludedFromTotalsChangedJournalCause < ActiveRecord::Migration[7.1] + def up + execute(<<~SQL.squish) + UPDATE journals + SET cause = json_object( + 'type': 'status_changed', + 'status_id': cause -> 'status_id', + 'status_name': cause -> 'status_name', + 'status_changes': json_object( + 'default_done_ratio': cause -> 'status_p_complete_change' + ) + ) + WHERE cause @> '{"type": "status_p_complete_changed"}'; + SQL + end + + def down + execute(<<~SQL.squish) + UPDATE journals + SET cause = json_object( + 'type': 'status_p_complete_changed', + 'status_id': cause -> 'status_id', + 'status_name': cause -> 'status_name', + 'status_p_complete_change': cause #> '{status_changes,default_done_ratio}' + ) + WHERE cause @> '{"type": "status_changed", "status_changes":{"default_done_ratio":[]}}'; + SQL + end +end diff --git a/lib/open_project/journal_formatter/cause.rb b/lib/open_project/journal_formatter/cause.rb index 69bc85837de5..ae0a8385f44a 100644 --- a/lib/open_project/journal_formatter/cause.rb +++ b/lib/open_project/journal_formatter/cause.rb @@ -32,50 +32,57 @@ class OpenProject::JournalFormatter::Cause < JournalFormatter::Base include OpenProject::StaticRouting::UrlHelpers include OpenProject::ObjectLinking + attr_reader :cause + def render(_key, values, options = { html: true }) - cause = values.last + @cause = values.last + @html = options[:html] - if options[:html] - "#{content_tag(:strong, cause_type_translation(cause['type']))} #{cause_description(cause, true)}" - else - "#{cause_type_translation(cause['type'])} #{cause_description(cause, false)}" - end + "#{caused_change} #{cause_description}" end private - def cause_type_translation(type) - mapped_type = mapped_cause_type(type) - I18n.t("journals.caused_changes.#{mapped_type}", default: mapped_type) + def html? + @html + end + + def caused_change + caused_change_text = I18n.t("journals.caused_changes.#{mapped_cause_type}", + default: mapped_cause_type, + status_name: cause["status_name"]) + if html? + content_tag(:strong, caused_change_text) + else + caused_change_text + end end - def mapped_cause_type(type) - case type + def mapped_cause_type + case cause["type"] when /changed_times/, "working_days_changed" "dates_changed" else - type + cause["type"] end end - def cause_description(cause, html) + def cause_description case cause["type"] when "system_update" - system_update_message(cause, html) + system_update_message when "working_days_changed" working_days_changed_message(cause["changed_days"]) - when "status_excluded_from_totals_changed" - status_excluded_from_totals_changed_message(cause, html) - when "status_p_complete_changed" - status_p_complete_changed_message(cause, html) + when "status_changed" + status_changed_message when "progress_mode_changed_to_status_based" progress_mode_changed_to_status_based_message else - related_work_package_changed_message(cause, html) + related_work_package_changed_message end end - def system_update_message(cause, html) + def system_update_message feature = cause["feature"] feature = "progress_calculation_adjusted" if feature == "progress_calculation_changed" @@ -90,7 +97,7 @@ def system_update_message(cause, html) {} end message = I18n.t("journals.cause_descriptions.system_update.#{feature}", **options) - html ? message : Sanitize.fragment(message) + html? ? message : Sanitize.fragment(message) end def working_days_changed_message(changed_dates) @@ -114,35 +121,35 @@ def working_date_change_message(date, working) date: I18n.l(Date.parse(date))) end - def status_excluded_from_totals_changed_message(cause, html) - cause.symbolize_keys => { status_name:, status_excluded_from_totals_change: change} - status_name = html_escape(status_name) if html - - if change == [false, true] - I18n.t("journals.cause_descriptions.status_excluded_from_totals_set_to_true_message", status_name:) - elsif change == [true, false] - I18n.t("journals.cause_descriptions.status_excluded_from_totals_set_to_false_message", status_name:) - end + def status_changed_message + cause["status_changes"] + .sort + .map { |change| status_change_partial_message(change) } + .to_sentence end - def status_p_complete_changed_message(cause, html) - cause.symbolize_keys => { status_name:, status_p_complete_change: [old_value, new_value]} - status_name = html_escape(status_name) if html - - I18n.t("journals.cause_descriptions.status_p_complete_changed", status_name:, old_value:, new_value:) + def status_change_partial_message(change) + case change + in ["default_done_ratio", [old_value, new_value]] + I18n.t("journals.cause_descriptions.status_percent_complete_changed", old_value:, new_value:) + in ["excluded_from_totals", [true, false]] + I18n.t("journals.cause_descriptions.status_excluded_from_totals_set_to_false_message") + in ["excluded_from_totals", [false, true]] + I18n.t("journals.cause_descriptions.status_excluded_from_totals_set_to_true_message") + end end def progress_mode_changed_to_status_based_message I18n.t("journals.cause_descriptions.progress_mode_changed_to_status_based") end - def related_work_package_changed_message(cause, html) + def related_work_package_changed_message related_work_package = WorkPackage.includes(:project).visible(User.current).find_by(id: cause["work_package_id"]) if related_work_package I18n.t( "journals.cause_descriptions.#{cause['type']}", - link: html ? link_to_work_package(related_work_package, all_link: true) : "##{related_work_package.id}" + link: html? ? link_to_work_package(related_work_package, all_link: true) : "##{related_work_package.id}" ) else diff --git a/spec/controllers/statuses_controller_spec.rb b/spec/controllers/statuses_controller_spec.rb index d3e446f269fc..a4058d23a443 100644 --- a/spec/controllers/statuses_controller_spec.rb +++ b/spec/controllers/statuses_controller_spec.rb @@ -146,6 +146,45 @@ expect(WorkPackages::Progress::ApplyStatusesChangeJob) .not_to have_been_enqueued end + + context "when also marking a status as excluded from totals calculations" do + before_all do + status.update_columns(name: "Rejected", + default_done_ratio: 70) + end + + shared_let(:status_new) { create(:status, name: "New", default_done_ratio: "0") } + shared_let_work_packages(<<~TABLE) + hierarchy | status | work | remaining work | % complete | ∑ work | ∑ remaining work | ∑ % complete + parent | New | | | | 20h | 15h | 25% + child | Rejected | 10h | 5h | 50% | | | + other child | New | 10h | 10h | 0% | | | + TABLE + + let(:status_params) do + { default_done_ratio: new_default_done_ratio, + excluded_from_totals: true } + end + + it "starts a job to update totals of work packages having excluded children" do + expect(status.reload).to have_attributes(excluded_from_totals: true) + expect(WorkPackages::Progress::ApplyStatusesChangeJob) + .to have_been_enqueued.with(cause_type: "status_changed", + status_name: status.name, + status_id: status.id, + changes: { "excluded_from_totals" => [false, true] }) + + perform_enqueued_jobs + + expect_work_packages([parent, child, other_child], <<~TABLE) + subject | status | work | remaining work | % complete | ∑ work | ∑ remaining work | ∑ % complete + parent | New | | | | 10h | 10h | 0% + child | Rejected | 10h | 5h | 50% | | | + other child | New | 10h | 10h | 0% | | | + TABLE + expect(parent.last_journal.details["cause"].last).to include("type" => "status_changed") + end + end end context "when in status-based mode", @@ -159,15 +198,15 @@ old_default_done_ratio = status.default_done_ratio expect(status.reload).to have_attributes(default_done_ratio: new_default_done_ratio) expect(WorkPackages::Progress::ApplyStatusesChangeJob) - .to have_been_enqueued.with(cause_type: "status_p_complete_changed", + .to have_been_enqueued.with(cause_type: "status_changed", status_name: status.name, status_id: status.id, - change: [old_default_done_ratio, new_default_done_ratio]) + changes: { "default_done_ratio" => [old_default_done_ratio, new_default_done_ratio] }) perform_enqueued_jobs expect(work_package.reload.read_attribute(:done_ratio)).to eq(new_default_done_ratio) - expect(work_package.last_journal.details["cause"].last).to include("type" => "status_p_complete_changed") + expect(work_package.last_journal.details["cause"].last).to include("type" => "status_changed") end end @@ -189,7 +228,7 @@ shared_let(:status_new) { create(:status, name: "New", default_done_ratio: "0") } shared_let_work_packages(<<~TABLE) hierarchy | status | work | remaining work | % complete | ∑ work | ∑ remaining work | ∑ % complete - parent | New | | | | 20h | 16h | 20% + parent | New | | | 0% | 20h | 16h | 20% child | Rejected | 10h | 3h | 70% | | | other child | New | 10h | 10h | 0% | | | TABLE @@ -199,17 +238,52 @@ it "starts a job to update totals of work packages having excluded children" do expect(status.reload).to have_attributes(excluded_from_totals: true) expect(WorkPackages::Progress::ApplyStatusesChangeJob) - .to have_been_enqueued.with(cause_type: "status_excluded_from_totals_changed", + .to have_been_enqueued.with(cause_type: "status_changed", status_name: status.name, status_id: status.id, - change: [false, true]) + changes: { "excluded_from_totals" => [false, true] }) perform_enqueued_jobs - expect(parent.reload.read_attribute(:derived_estimated_hours)).to eq(10) - expect(parent.reload.read_attribute(:derived_remaining_hours)).to eq(10) - expect(parent.reload.read_attribute(:derived_done_ratio)).to eq(0) - expect(parent.last_journal.details["cause"].last).to include("type" => "status_excluded_from_totals_changed") + expect_work_packages([parent, child, other_child], <<~TABLE) + subject | status | work | remaining work | % complete | ∑ work | ∑ remaining work | ∑ % complete + parent | New | | | 0% | 10h | 10h | 0% + child | Rejected | 10h | 3h | 70% | | | + other child | New | 10h | 10h | 0% | | | + TABLE + expect(parent.last_journal.details["cause"].last).to include("type" => "status_changed") + end + + context "when also changing the default % complete of the status" do + let(:new_default_done_ratio) { 40 } + let(:status_params) { { excluded_from_totals: true, default_done_ratio: new_default_done_ratio } } + + it "starts a job to update both total values and % complete of work packages" do + old_default_done_ratio = status.default_done_ratio + expect(status.reload).to have_attributes(default_done_ratio: new_default_done_ratio, + excluded_from_totals: true) + expect(WorkPackages::Progress::ApplyStatusesChangeJob) + .to have_been_enqueued.with(cause_type: "status_changed", + status_name: status.name, + status_id: status.id, + changes: { "default_done_ratio" => [old_default_done_ratio, new_default_done_ratio], + "excluded_from_totals" => [false, true] }) + + perform_enqueued_jobs + + expect_work_packages([parent, child, other_child], <<~TABLE) + subject | status | work | remaining work | % complete | ∑ work | ∑ remaining work | ∑ % complete + parent | New | | | 0% | 10h | 10h | 0% + child | Rejected | 10h | 6h | 40% | | | + other child | New | 10h | 10h | 0% | | | + TABLE + + [parent, child].each do |work_package| + expect(work_package.journals.count).to eq(2) + expect(work_package.last_journal.details["cause"].last).to include("type" => "status_changed") + end + expect(other_child.journals.count).to eq(1) # this one should not have changed + end end end diff --git a/spec/lib/journal_formatter/cause_spec.rb b/spec/lib/journal_formatter/cause_spec.rb index b8c6995e8080..1729d4e0b254 100644 --- a/spec/lib/journal_formatter/cause_spec.rb +++ b/spec/lib/journal_formatter/cause_spec.rb @@ -305,25 +305,20 @@ def render(cause, html:) shared_let(:status) { create(:status, name: "In progress", default_done_ratio: 40) } subject(:cause) do { - "type" => "status_p_complete_changed", + "type" => "status_changed", "status_name" => status.name, "status_id" => status.id, - "status_p_complete_change" => [20, 40] + "status_changes" => { "default_done_ratio" => [20, 40] } } end it do - expect(cause).to render_html_variant( - "#{I18n.t('journals.caused_changes.status_p_complete_changed')} " \ - "% complete value for status 'In progress' changed from 20% to 40%" - ) + expect(cause).to render_html_variant("Status 'In progress' " \ + "% complete changed from 20% to 40%") end it do - expect(cause).to render_raw_variant( - "#{I18n.t('journals.caused_changes.status_p_complete_changed')} " \ - "% complete value for status 'In progress' changed from 20% to 40%" - ) + expect(cause).to render_raw_variant("Status 'In progress' % complete changed from 20% to 40%") end it_behaves_like "XSS-proof rendering of status name" @@ -333,24 +328,22 @@ def render(cause, html:) shared_let(:status) { create(:status, name: "Rejected") } subject(:cause) do { - "type" => "status_excluded_from_totals_changed", + "type" => "status_changed", "status_name" => status.name, "status_id" => status.id, - "status_excluded_from_totals_change" => [false, true] + "status_changes" => { "excluded_from_totals" => [false, true] } } end it do expect(cause).to render_html_variant( - "Status Excluded from totals changed " \ - "status 'Rejected' was excluded from totals calculations" + "Status 'Rejected' now excluded from hierarchy totals" ) end it do expect(cause).to render_raw_variant( - "Status Excluded from totals changed " \ - "status 'Rejected' was excluded from totals calculations" + "Status 'Rejected' now excluded from hierarchy totals" ) end @@ -361,24 +354,22 @@ def render(cause, html:) shared_let(:status) { create(:status, name: "Rejected") } subject(:cause) do { - "type" => "status_excluded_from_totals_changed", + "type" => "status_changed", "status_name" => status.name, "status_id" => status.id, - "status_excluded_from_totals_change" => [true, false] + "status_changes" => { "excluded_from_totals" => [true, false] } } end it do expect(cause).to render_html_variant( - "Status Excluded from totals changed " \ - "status 'Rejected' was included in totals calculations" + "Status 'Rejected' now included in hierarchy totals" ) end it do expect(cause).to render_raw_variant( - "Status Excluded from totals changed " \ - "status 'Rejected' was included in totals calculations" + "Status 'Rejected' now included in hierarchy totals" ) end @@ -407,6 +398,31 @@ def render(cause, html:) end end + context "when both a change of status % complete and excluded from totals is the cause" do + shared_let(:status) { create(:status, name: "In progress", default_done_ratio: 40) } + subject(:cause) do + { + "type" => "status_changed", + "status_name" => status.name, + "status_id" => status.id, + "status_changes" => { "default_done_ratio" => [20, 40], + "excluded_from_totals" => [false, true] } + } + end + + it do + expect(cause).to render_html_variant("Status 'In progress' " \ + "% complete changed from 20% to 40% and now excluded from hierarchy totals") + end + + it do + expect(cause).to render_raw_variant("Status 'In progress' " \ + "% complete changed from 20% to 40% and now excluded from hierarchy totals") + end + + it_behaves_like "XSS-proof rendering of status name" + end + context "when cause is a system update: change of progress calculation mode from disabled to work-based" do subject(:cause) do { diff --git a/spec/workers/work_packages/progress/apply_statuses_change_job_spec.rb b/spec/workers/work_packages/progress/apply_statuses_change_job_spec.rb index bb7b4ec8266c..b6db280169d4 100644 --- a/spec/workers/work_packages/progress/apply_statuses_change_job_spec.rb +++ b/spec/workers/work_packages/progress/apply_statuses_change_job_spec.rb @@ -57,13 +57,13 @@ subject(:job) { described_class } def expect_performing_job_changes(from:, to:, - cause_type: "status_p_complete_changed", - status_name: "New", + cause_type: "status_changed", + status_name: "Some status name", status_id: 99, - change: [33, 66]) + changes: { "default_done_ratio" => [33, 66] }) table = create_table(from) - job.perform_now(cause_type:, status_name:, status_id:, change:) + job.perform_now(cause_type:, status_name:, status_id:, changes:) table.work_packages.map(&:reload) expect_work_packages(table.work_packages, to) @@ -107,10 +107,10 @@ def expect_performing_job_changes(from:, to:, before do job.perform_now( - cause_type: "status_excluded_from_totals_changed", + cause_type: "status_changed", status_name: status_excluded.name, status_id: status_excluded.id, - change: [false, true] + changes: { "excluded_from_totals" => [false, true] } ) table_work_packages.map(&:reload) end @@ -132,10 +132,10 @@ def expect_performing_job_changes(from:, to:, expect(work_package.journals.count).to eq(2), "expected #{work_package} to have a new journal" last_journal = work_package.last_journal expect(last_journal.user).to eq(User.system) - expect(last_journal.cause_type).to eq("status_excluded_from_totals_changed") + expect(last_journal.cause_type).to eq("status_changed") expect(last_journal.cause_status_name).to eq("Excluded") expect(last_journal.cause_status_id).to eq(status_excluded.id) - expect(last_journal.cause_status_excluded_from_totals_change).to eq([false, true]) + expect(last_journal.cause_status_changes).to eq({ "excluded_from_totals" => [false, true] }) end unchanged_work_packages = table_work_packages - changed_worked_packages @@ -227,10 +227,10 @@ def expect_performing_job_changes(from:, to:, before do job.perform_now( - cause_type: "status_excluded_from_totals_changed", + cause_type: "status_changed", status_name: status_excluded.name, status_id: status_excluded.id, - change: [false, true] + changes: { "excluded_from_totals" => [false, true] } ) table_work_packages.map(&:reload) end @@ -252,10 +252,10 @@ def expect_performing_job_changes(from:, to:, expect(work_package.journals.count).to eq(2), "expected #{work_package} to have a new journal" last_journal = work_package.last_journal expect(last_journal.user).to eq(User.system) - expect(last_journal.cause_type).to eq("status_excluded_from_totals_changed") + expect(last_journal.cause_type).to eq("status_changed") expect(last_journal.cause_status_name).to eq("Excluded") expect(last_journal.cause_status_id).to eq(status_excluded.id) - expect(last_journal.cause_status_excluded_from_totals_change).to eq([false, true]) + expect(last_journal.cause_status_changes).to eq({ "excluded_from_totals" => [false, true] }) end unchanged_work_packages = table_work_packages - changed_worked_packages @@ -281,19 +281,19 @@ def expect_performing_job_changes(from:, to:, child 1 | Doing (40%) | 10h | 6h | 40% | | | child 2 | Done (100%) | 10h | 0h | 100% | | | TABLE - cause_type: "status_p_complete_changed", + cause_type: "status_changed", status_name: status_40p_doing.name, status_id: status_40p_doing.id, - change: [20, 40] + changes: { "default_done_ratio" => [20, 40] } ) [parent, child1].each do |work_package| expect(work_package.journals.count).to eq 2 last_journal = work_package.last_journal expect(last_journal.user).to eq(User.system) - expect(last_journal.cause_type).to eq("status_p_complete_changed") + expect(last_journal.cause_type).to eq("status_changed") expect(last_journal.cause_status_name).to eq("Doing (40%)") expect(last_journal.cause_status_id).to eq(status_40p_doing.id) - expect(last_journal.cause_status_p_complete_change).to eq([20, 40]) + expect(last_journal.cause_status_changes).to eq({ "default_done_ratio" => [20, 40] }) end # unchanged => no new journals @@ -351,10 +351,10 @@ def expect_performing_job_changes(from:, to:, .and_return(nil) begin - job.perform_now(cause_type: "status_p_complete_changed", + job.perform_now(cause_type: "status_changed", status_name: "New", status_id: 99, - change: [33, 66]) + changes: { "default_done_ratio" => [33, 66] }) rescue StandardError end end From c2f338896c9e255b9422dcbb176c4076c73c3e38 Mon Sep 17 00:00:00 2001 From: Christophe Bliard Date: Thu, 23 May 2024 09:08:46 +0200 Subject: [PATCH 022/176] Make migration compatible with Postgres 13 --- ...luded_from_totals_changed_journal_cause.rb | 50 ++++++++++++++----- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/db/migrate/20240522073759_fix_status_excluded_from_totals_changed_journal_cause.rb b/db/migrate/20240522073759_fix_status_excluded_from_totals_changed_journal_cause.rb index 33f181c2f129..15f610b3ee47 100644 --- a/db/migrate/20240522073759_fix_status_excluded_from_totals_changed_journal_cause.rb +++ b/db/migrate/20240522073759_fix_status_excluded_from_totals_changed_journal_cause.rb @@ -19,29 +19,53 @@ # structure needed to handle multiple changes in one cause class FixStatusExcludedFromTotalsChangedJournalCause < ActiveRecord::Migration[7.1] def up + # With Postgres version 16+, it could be written as: + # json_object( + # 'type': 'status_changed', + # 'status_id': cause -> 'status_id', + # 'status_name': cause -> 'status_name', + # 'status_changes': json_object( + # 'default_done_ratio': cause -> 'status_p_complete_change' + # ) + # ) execute(<<~SQL.squish) UPDATE journals - SET cause = json_object( - 'type': 'status_changed', - 'status_id': cause -> 'status_id', - 'status_name': cause -> 'status_name', - 'status_changes': json_object( - 'default_done_ratio': cause -> 'status_p_complete_change' + SET cause = jsonb_set( + jsonb_set( + cause, + '{type}', + '"status_changed"' + ), + '{status_changes}', + jsonb_set( + '{"default_done_ratio": ""}'::jsonb, + '{default_done_ratio}', + cause -> 'status_p_complete_change' ) - ) + ) - 'status_p_complete_change' WHERE cause @> '{"type": "status_p_complete_changed"}'; SQL end def down + # With Postgres version 16+, it could be written as: + # json_object( + # 'type': 'status_p_complete_changed', + # 'status_id': cause -> 'status_id', + # 'status_name': cause -> 'status_name', + # 'status_p_complete_change': cause #> '{status_changes,default_done_ratio}' + # ) execute(<<~SQL.squish) UPDATE journals - SET cause = json_object( - 'type': 'status_p_complete_changed', - 'status_id': cause -> 'status_id', - 'status_name': cause -> 'status_name', - 'status_p_complete_change': cause #> '{status_changes,default_done_ratio}' - ) + SET cause = jsonb_set( + jsonb_set( + cause, + '{type}', + '"status_p_complete_changed"' + ), + '{status_p_complete_change}', + cause #> '{status_changes,default_done_ratio}' + ) - 'status_changes' WHERE cause @> '{"type": "status_changed", "status_changes":{"default_done_ratio":[]}}'; SQL end From 76f2989a3b109372f59750a08e8304128080dc78 Mon Sep 17 00:00:00 2001 From: Christophe Bliard Date: Thu, 23 May 2024 10:50:29 +0200 Subject: [PATCH 023/176] Display workflow run start time in github_pr_errors --- script/github_pr_errors | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/script/github_pr_errors b/script/github_pr_errors index 3bd6042f2009..6dbef958d69d 100755 --- a/script/github_pr_errors +++ b/script/github_pr_errors @@ -10,6 +10,7 @@ require "optparse" require "base64" require "pathname" require "pry" +require "time" require "yaml" require "httpx" @@ -274,6 +275,7 @@ class Report :head_branch, :head_sha, :commit_message, + :run_started_at, :merge_branch_sha end @@ -453,9 +455,11 @@ class Formatter report.head_branch = workflow_run["head_branch"] report.head_sha = workflow_run["head_sha"] report.commit_message = commit_message(workflow_run) + report.run_started_at = Time.parse(workflow_run["run_started_at"]).utc warn " Branch: #{report.head_branch.bold}" warn " Commit SHA: #{report.head_sha.bold}" warn " Commit message: #{report.commit_message.bold}" + warn " Run started at: #{report.run_started_at.localtime.to_s.bold}" display_pull_request_info(workflow_run) end From d728ea37db30a9b1daa36072beb39c9cbead1968 Mon Sep 17 00:00:00 2001 From: Christophe Bliard Date: Thu, 23 May 2024 10:51:08 +0200 Subject: [PATCH 024/176] Raise an error if there are more cells than headers in a row It's to prevent silly mistakes when writing and copy-pasting tables in specs. --- spec/support/table_helpers/table_parser.rb | 4 ++++ .../table_helpers/table_parser_spec.rb | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/spec/support/table_helpers/table_parser.rb b/spec/support/table_helpers/table_parser.rb index 4ac10ceee87f..c3faa62614be 100644 --- a/spec/support/table_helpers/table_parser.rb +++ b/spec/support/table_helpers/table_parser.rb @@ -33,6 +33,10 @@ class TableParser def parse(representation) headers, *rows = representation.split("\n").filter_map { |line| split_line_into_cells(line) } work_packages_data = rows.map.with_index do |cells, index| + if cells.size > headers.size + raise ArgumentError, "Too many cells in row #{index + 1}, have you forgotten some headers?" + end + { attributes: {}, index:, diff --git a/spec/support_spec/table_helpers/table_parser_spec.rb b/spec/support_spec/table_helpers/table_parser_spec.rb index 843d500cd13f..2e5358ec5748 100644 --- a/spec/support_spec/table_helpers/table_parser_spec.rb +++ b/spec/support_spec/table_helpers/table_parser_spec.rb @@ -73,6 +73,25 @@ .to raise_error(ArgumentError, 'Please use "remaining work" instead of "remaining hours"') end + it "raises an error if there are more cells than headers in a row" do + table = <<~TABLE + subject | work + wp | 4h | 6h + TABLE + expect { described_class.new.parse(table) } + .to raise_error(ArgumentError, "Too many cells in row 1, have you forgotten some headers?") + end + + it "is ok to have more headers than cells (value of missing cells will be nil)" do + table = <<~TABLE + subject | work | remaining work + wp | 4h + TABLE + parsed_data = described_class.new.parse(table) + expect(parsed_data.dig(0, :attributes, :estimated_hours)).to eq(4.0) + expect(parsed_data.dig(0, :attributes, :remaining_hours)).to be_nil + end + describe "subject column" do let(:table) do <<~TABLE From 15716cb04ca2e413a3cbf071945e94aeaa7c789c Mon Sep 17 00:00:00 2001 From: Christophe Bliard Date: Thu, 23 May 2024 14:04:01 +0200 Subject: [PATCH 025/176] Compute totals even if all children are excluded There was a bug in the way the excluded work packages were affecting the query which updates the totals, especially regarding looking at the `MAX(generations)` value. When considering work packages after filtering out excluded work packages, the parent is alone, and its `MAX(generations)` is 0, which is interpreted like it is a leaf work package and leading to totals being unset, which is not correct. Now the check for `MAX(generations) > 0` is done outside of the filtering to prevent this bug from happening. --- .../work_packages/progress/sql_commands.rb | 8 +- .../apply_statuses_change_job_spec.rb | 102 ++++++++++++------ 2 files changed, 73 insertions(+), 37 deletions(-) diff --git a/app/workers/work_packages/progress/sql_commands.rb b/app/workers/work_packages/progress/sql_commands.rb index 1430503de911..1b2b6990825b 100644 --- a/app/workers/work_packages/progress/sql_commands.rb +++ b/app/workers/work_packages/progress/sql_commands.rb @@ -96,7 +96,6 @@ def update_totals END FROM ( SELECT wp_tree.ancestor_id AS id, - MAX(generations) AS generations, SUM(estimated_hours) AS total_work, SUM(remaining_hours) AS total_remaining_work FROM work_package_hierarchies wp_tree @@ -106,7 +105,12 @@ def update_totals GROUP BY wp_tree.ancestor_id ) totals WHERE temp_wp_progress_values.id = totals.id - AND totals.generations > 0 + AND temp_wp_progress_values.id IN ( + SELECT ancestor_id AS id + FROM work_package_hierarchies + GROUP BY id + HAVING MAX(generations) > 0 + ) SQL end diff --git a/spec/workers/work_packages/progress/apply_statuses_change_job_spec.rb b/spec/workers/work_packages/progress/apply_statuses_change_job_spec.rb index b6db280169d4..97ad3d2cc0d2 100644 --- a/spec/workers/work_packages/progress/apply_statuses_change_job_spec.rb +++ b/spec/workers/work_packages/progress/apply_statuses_change_job_spec.rb @@ -95,52 +95,84 @@ def expect_performing_job_changes(from:, to:, end context "when a status is being excluded from progress calculation" do - # The work packages are created like if the status is not excluded yet - shared_let_work_packages(<<~TABLE) - hierarchy | status | work | remaining work | % complete | ∑ work | ∑ remaining work | ∑ % complete - grandparent | New | 1h | 0.6h | 40% | 24h | 11.3h | 53% - parent | Excluded | 4h | 1h | 75% | 23h | 10.7h | 53% - child 1 | Excluded | 9h | 7.2h | 20% | | | - child 2 | In progress | 5h | 2.5h | 50% | | | - child 3 | Closed | 5h | 0h | 100% | | | - TABLE + it "computes totals of the parent having work when all children are excluded" do + expect_performing_job_changes( + from: <<~TABLE, + hierarchy | status | work | remaining work | % complete | ∑ work | ∑ remaining work | ∑ % complete + parent | In progress | 10h | 3h | 70% | 20h | 5h | 75% + child | Excluded | 10h | 2h | 50% | | | + TABLE + to: <<~TABLE + subject | status | work | remaining work | % complete | ∑ work | ∑ remaining work | ∑ % complete + parent | In progress | 10h | 3h | 70% | 10h | 3h | 70% + child | Excluded | 10h | 2h | 50% | | | + TABLE + ) + end - before do - job.perform_now( - cause_type: "status_changed", - status_name: status_excluded.name, - status_id: status_excluded.id, - changes: { "excluded_from_totals" => [false, true] } + it "keeps the totals unset if work, remaining work, and % complete are all nil" do + expect_performing_job_changes( + from: <<~TABLE, + hierarchy | status | work | remaining work | % complete | ∑ work | ∑ remaining work | ∑ % complete + parent | In progress | | | | | | + child | Excluded | | | | | | + TABLE + to: <<~TABLE + subject | status | work | remaining work | % complete | ∑ work | ∑ remaining work | ∑ % complete + parent | In progress | | | | | | + child | Excluded | | | | | | + TABLE ) - table_work_packages.map(&:reload) end - it "recomputes totals without the values from work packages having the excluded status" do - expect_work_packages(table_work_packages, <<~TABLE) - subject | status | work | remaining work | % complete | ∑ work | ∑ remaining work | ∑ % complete - grandparent | New | 1h | 0.6h | 40% | 11h | 3.1h | 72% - parent | Excluded | 4h | 1h | 75% | 10H | 2.5h | 75% + describe "general case" do + # The work packages are created like if the status is not excluded yet + shared_let_work_packages(<<~TABLE) + hierarchy | status | work | remaining work | % complete | ∑ work | ∑ remaining work | ∑ % complete + grandparent | New | 1h | 0.6h | 40% | 24h | 11.3h | 53% + parent | Excluded | 4h | 1h | 75% | 23h | 10.7h | 53% child 1 | Excluded | 9h | 7.2h | 20% | | | child 2 | In progress | 5h | 2.5h | 50% | | | child 3 | Closed | 5h | 0h | 100% | | | TABLE - end - it "adds a relevant journal entry for the parent with recomputed total" do - changed_worked_packages = [grandparent, parent] - changed_worked_packages.each do |work_package| - expect(work_package.journals.count).to eq(2), "expected #{work_package} to have a new journal" - last_journal = work_package.last_journal - expect(last_journal.user).to eq(User.system) - expect(last_journal.cause_type).to eq("status_changed") - expect(last_journal.cause_status_name).to eq("Excluded") - expect(last_journal.cause_status_id).to eq(status_excluded.id) - expect(last_journal.cause_status_changes).to eq({ "excluded_from_totals" => [false, true] }) + before do + job.perform_now( + cause_type: "status_changed", + status_name: status_excluded.name, + status_id: status_excluded.id, + changes: { "excluded_from_totals" => [false, true] } + ) + table_work_packages.map(&:reload) end - unchanged_work_packages = table_work_packages - changed_worked_packages - unchanged_work_packages.each do |work_package| - expect(work_package.journals.count).to eq(1), "expected #{work_package} not to have new journals" + it "recomputes totals without the values from work packages having the excluded status" do + expect_work_packages(table_work_packages, <<~TABLE) + subject | status | work | remaining work | % complete | ∑ work | ∑ remaining work | ∑ % complete + grandparent | New | 1h | 0.6h | 40% | 11h | 3.1h | 72% + parent | Excluded | 4h | 1h | 75% | 10H | 2.5h | 75% + child 1 | Excluded | 9h | 7.2h | 20% | | | + child 2 | In progress | 5h | 2.5h | 50% | | | + child 3 | Closed | 5h | 0h | 100% | | | + TABLE + end + + it "adds a relevant journal entry for the parent with recomputed total" do + changed_worked_packages = [grandparent, parent] + changed_worked_packages.each do |work_package| + expect(work_package.journals.count).to eq(2), "expected #{work_package} to have a new journal" + last_journal = work_package.last_journal + expect(last_journal.user).to eq(User.system) + expect(last_journal.cause_type).to eq("status_changed") + expect(last_journal.cause_status_name).to eq("Excluded") + expect(last_journal.cause_status_id).to eq(status_excluded.id) + expect(last_journal.cause_status_changes).to eq({ "excluded_from_totals" => [false, true] }) + end + + unchanged_work_packages = table_work_packages - changed_worked_packages + unchanged_work_packages.each do |work_package| + expect(work_package.journals.count).to eq(1), "expected #{work_package} not to have new journals" + end end end end From 102b0cc252ae476d9ae26aec6893a54ab7db1591 Mon Sep 17 00:00:00 2001 From: Aaron Contreras Date: Tue, 14 May 2024 16:37:56 -0500 Subject: [PATCH 026/176] Make hours/day, hours/week, days/month configurable --- ...working_days_and_hours_params_contract.rb} | 35 ++++++++++++++++- ...king_days_and_hours_settings_controller.rb | 5 ++- app/services/duration_converter.rb | 10 +++-- ... working_days_and_hours_update_service.rb} | 5 ++- .../show.html.erb | 39 +++++++++++++++---- config/constants/settings/definition.rb | 18 +++++++++ config/locales/en.yml | 11 ++++++ ...ng_days_and_hours_params_contract_spec.rb} | 2 +- ...days_and_hours_settings_controller_spec.rb | 5 ++- ...ing_days_and_hours_update_service_spec.rb} | 16 ++++---- 10 files changed, 121 insertions(+), 25 deletions(-) rename app/contracts/settings/{working_days_params_contract.rb => working_days_and_hours_params_contract.rb} (68%) rename app/services/settings/{working_days_update_service.rb => working_days_and_hours_update_service.rb} (95%) rename spec/contracts/settings/{working_days_params_contract_spec.rb => working_days_and_hours_params_contract_spec.rb} (97%) rename spec/services/settings/{working_days_update_service_spec.rb => working_days_and_hours_update_service_spec.rb} (94%) diff --git a/app/contracts/settings/working_days_params_contract.rb b/app/contracts/settings/working_days_and_hours_params_contract.rb similarity index 68% rename from app/contracts/settings/working_days_params_contract.rb rename to app/contracts/settings/working_days_and_hours_params_contract.rb index 42bacb779bab..70adb482c7db 100644 --- a/app/contracts/settings/working_days_params_contract.rb +++ b/app/contracts/settings/working_days_and_hours_params_contract.rb @@ -27,10 +27,13 @@ #++ module Settings - class WorkingDaysParamsContract < ::ParamsContract + class WorkingDaysAndHoursParamsContract < ::ParamsContract include RequiresAdminGuard validate :working_days_are_present + validate :hours_per_day_are_present + validate :hours_per_week_are_present + validate :days_per_month_are_present validate :unique_job protected @@ -41,6 +44,24 @@ def working_days_are_present end end + def hours_per_day_are_present + if hours_per_day.blank? + errors.add :base, :hours_per_day_are_missing + end + end + + def hours_per_week_are_present + if hours_per_week.blank? + errors.add :base, :hours_per_week_are_missing + end + end + + def days_per_month_are_present + if days_per_month.blank? + errors.add :base, :days_per_month_are_missing + end + end + def unique_job WorkPackages::ApplyWorkingDaysChangeJob.new.check_concurrency do errors.add :base, :previous_working_day_changes_unprocessed @@ -50,5 +71,17 @@ def unique_job def working_days params[:working_days] end + + def hours_per_day + params[:hours_per_day] + end + + def hours_per_week + params[:hours_per_week] + end + + def days_per_month + params[:days_per_month] + end end end diff --git a/app/controllers/admin/settings/working_days_and_hours_settings_controller.rb b/app/controllers/admin/settings/working_days_and_hours_settings_controller.rb index 15366b7adb52..f6b40d0f8226 100644 --- a/app/controllers/admin/settings/working_days_and_hours_settings_controller.rb +++ b/app/controllers/admin/settings/working_days_and_hours_settings_controller.rb @@ -46,11 +46,14 @@ def settings_params settings = super settings[:working_days] = working_days_params(settings) settings[:non_working_days] = non_working_days_params + settings[:hours_per_day] = params[:settings][:hours_per_day] + settings[:hours_per_week] = params[:settings][:hours_per_week] + settings[:days_per_month] = params[:settings][:days_per_month] settings end def update_service - ::Settings::WorkingDaysUpdateService + ::Settings::WorkingDaysAndHoursUpdateService end private diff --git a/app/services/duration_converter.rb b/app/services/duration_converter.rb index 757c49281781..885ec15805ad 100644 --- a/app/services/duration_converter.rb +++ b/app/services/duration_converter.rb @@ -38,7 +38,7 @@ class << self def parse(duration_string) # Keep 0 values and convert the extracted duration to hours # by dividing by 3600. - ChronicDuration.parse(duration_string, keep_zero: true, default_unit: "hours") / 3600.to_f + ChronicDuration.parse(duration_string, keep_zero: true, default_unit: "hours", **duration_length_options) / 3600.to_f end def output(duration_in_hours) @@ -52,10 +52,10 @@ def output(duration_in_hours) # keeping zeroes, we'd format this as "0 secs". # # We want to override this behavior. - if ChronicDuration.output(duration_in_seconds, default_unit: "hours").nil? + if ChronicDuration.output(duration_in_seconds, default_unit: "hours", **duration_length_options).nil? "0h" else - ChronicDuration.output(duration_in_seconds, default_unit: "hours", format: :short) + ChronicDuration.output(duration_in_seconds, default_unit: "hours", format: :short, **duration_length_options) end end @@ -64,5 +64,9 @@ def output(duration_in_hours) def convert_duration_to_seconds(duration_in_hours) (BigDecimal(duration_in_hours.to_s) * 3600).to_f end + + def duration_length_options + { hours_per_day: Setting.hours_per_day, days_per_month: Setting.days_per_month } + end end end diff --git a/app/services/settings/working_days_update_service.rb b/app/services/settings/working_days_and_hours_update_service.rb similarity index 95% rename from app/services/settings/working_days_update_service.rb rename to app/services/settings/working_days_and_hours_update_service.rb index 56575aed1e83..50f80557a3aa 100644 --- a/app/services/settings/working_days_update_service.rb +++ b/app/services/settings/working_days_and_hours_update_service.rb @@ -26,7 +26,7 @@ # See COPYRIGHT and LICENSE files for more details. #++ -class Settings::WorkingDaysUpdateService < Settings::UpdateService +class Settings::WorkingDaysAndHoursUpdateService < Settings::UpdateService def call(params) params = params.to_h.deep_symbolize_keys self.non_working_days_params = params.delete(:non_working_days) || [] @@ -36,7 +36,8 @@ def call(params) end def validate_params(params) - contract = Settings::WorkingDaysParamsContract.new(model, user, params:) + binding.pry + contract = Settings::WorkingDaysAndHoursParamsContract.new(model, user, params:) ServiceResult.new success: contract.valid?, errors: contract.errors, result: model diff --git a/app/views/admin/settings/working_days_and_hours_settings/show.html.erb b/app/views/admin/settings/working_days_and_hours_settings/show.html.erb index 44314edcb325..8c77b003cf47 100644 --- a/app/views/admin/settings/working_days_and_hours_settings/show.html.erb +++ b/app/views/admin/settings/working_days_and_hours_settings/show.html.erb @@ -29,20 +29,43 @@ See COPYRIGHT and LICENSE files for more details. <%= toolbar title: t(:label_working_days_and_hours) %> -
-
-

- <%= t("working_days.warning").html_safe %> -

-
-
- <%= styled_form_tag( admin_settings_working_days_and_hours_path, method: :patch, class: 'op-working-days-admin-settings' ) do %> +
+
+
+ <%= setting_text_field :hours_per_day, + type: :number %> +
<%= t("setting_hours_per_day_explanation") %>
+
+ +
+ <%= setting_text_field :hours_per_week, + type: :number %> +
<%= t("setting_hours_per_week_explanation") %>
+
+ +
+ <%= setting_text_field :days_per_month, + type: :number %> +
<%= t("setting_days_per_month_explanation") %>
+
+ +
+
+ +
+
+

+ <%= t("working_days.warning").html_safe %> +

+
+
+
<%= t('settings.working_days.section_work_week') %> diff --git a/config/constants/settings/definition.rb b/config/constants/settings/definition.rb index 479ed4fa1e4d..1ae869b2f66c 100644 --- a/config/constants/settings/definition.rb +++ b/config/constants/settings/definition.rb @@ -303,6 +303,12 @@ class Definition "%B %d, %Y" ].freeze }, + days_per_month: { + description: "This will define what is considered a “week” when displaying duration in a more natural way " \ + "(for example, if a month is 20 days, 60 days would be 3 months.", + default: 20, + format: :integer + }, default_auto_hide_popups: { description: "Whether to automatically hide success notifications by default", default: true @@ -518,6 +524,18 @@ class Definition host_name: { default: "localhost:3000" }, + hours_per_day: { + description: "This will define what is considered a “day” when displaying duration in a more natural way " \ + "(for example, if a day is 8 hours, 32 hours would be 4 days).", + default: 8, + format: :integer + }, + hours_per_week: { + description: "This will define what is considered a “week” when displaying duration in a more natural way " \ + "(for example, if a week is 40 hours, 1260 hours would be 7.5 weeks).", + default: 40, + format: :integer + }, # Health check configuration health_checks_authentication_password: { description: "Add an authentication challenge for the /health_check endpoint", diff --git a/config/locales/en.yml b/config/locales/en.yml index d9906f57c96d..7be9328bdde9 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1018,6 +1018,9 @@ Project attributes and sections are defined in the + This will define what is considered a “day” when displaying duration in a more natural way (for example, if a day is 8 hours, 32 hours would be 4 days). + setting_hours_per_week: "Hours per week" + setting_hours_per_week_explanation: > + This will define what is considered a “week” when displaying duration in a more natural way (for example, if a week is 40 hours, 1260 hours would be 7.5 weeks). setting_invitation_expiration_days: "Activation email expires after" setting_work_package_done_ratio: "Progress calculation" setting_work_package_done_ratio_field: "Work-based" diff --git a/spec/contracts/settings/working_days_params_contract_spec.rb b/spec/contracts/settings/working_days_and_hours_params_contract_spec.rb similarity index 97% rename from spec/contracts/settings/working_days_params_contract_spec.rb rename to spec/contracts/settings/working_days_and_hours_params_contract_spec.rb index ddd60516a286..4272ed1c6bdd 100644 --- a/spec/contracts/settings/working_days_params_contract_spec.rb +++ b/spec/contracts/settings/working_days_and_hours_params_contract_spec.rb @@ -29,7 +29,7 @@ require "spec_helper" require "contracts/shared/model_contract_shared_context" -RSpec.describe Settings::WorkingDaysParamsContract do +RSpec.describe Settings::WorkingDaysAndHoursParamsContract do include_context "ModelContract shared context" shared_let(:current_user) { create(:admin) } let(:setting) { Setting } diff --git a/spec/controllers/admin/settings/working_days_and_hours_settings_controller_spec.rb b/spec/controllers/admin/settings/working_days_and_hours_settings_controller_spec.rb index 9e465ef9903f..baca0292526d 100644 --- a/spec/controllers/admin/settings/working_days_and_hours_settings_controller_spec.rb +++ b/spec/controllers/admin/settings/working_days_and_hours_settings_controller_spec.rb @@ -38,8 +38,11 @@ describe "update" do let(:working_days) { [*"1".."7"] } let(:non_working_days_attributes) { {} } + let(:hours_per_day) { 4 } + let(:hours_per_week) { 16 } + let(:days_per_month) { 25 } let(:params) do - { settings: { working_days:, non_working_days_attributes: } } + { settings: { working_days:, non_working_days_attributes:, hours_per_day:, hours_per_week:, days_per_month: } } end subject { patch "update", params: } diff --git a/spec/services/settings/working_days_update_service_spec.rb b/spec/services/settings/working_days_and_hours_update_service_spec.rb similarity index 94% rename from spec/services/settings/working_days_update_service_spec.rb rename to spec/services/settings/working_days_and_hours_update_service_spec.rb index 597466215d65..cd7b8072c94e 100644 --- a/spec/services/settings/working_days_update_service_spec.rb +++ b/spec/services/settings/working_days_and_hours_update_service_spec.rb @@ -27,7 +27,7 @@ require "spec_helper" require_relative "shared/shared_call_examples" -RSpec.describe Settings::WorkingDaysUpdateService do +RSpec.describe Settings::WorkingDaysAndHoursUpdateService do let(:instance) do described_class.new(user:) end @@ -39,7 +39,7 @@ end let(:contract_success) { true } let(:params_contract) do - instance_double(Settings::WorkingDaysParamsContract, + instance_double(Settings::WorkingDaysAndHoursParamsContract, valid?: params_contract_success, errors: instance_double(ActiveModel::Error)) end @@ -55,20 +55,20 @@ # stub a setting definition allow(Setting) .to receive(:[]) - .and_call_original + .and_call_original allow(Setting) .to receive(:[]).with(setting_name) - .and_return(previous_setting_value) + .and_return(previous_setting_value) allow(Setting) .to receive(:[]=) # stub contract allow(Settings::UpdateContract) .to receive(:new) - .and_return(contract) - allow(Settings::WorkingDaysParamsContract) + .and_return(contract) + allow(Settings::WorkingDaysAndHoursParamsContract) .to receive(:new) - .and_return(params_contract) + .and_return(params_contract) end describe "#call" do @@ -87,7 +87,7 @@ expect(WorkPackages::ApplyWorkingDaysChangeJob) .to have_received(:perform_later) - .with(user_id: user.id, previous_working_days:, previous_non_working_days:) + .with(user_id: user.id, previous_working_days:, previous_non_working_days:) end end From 6e26e66e1229125a9942fc153841c0b369a3dc74 Mon Sep 17 00:00:00 2001 From: Aaron Contreras Date: Tue, 21 May 2024 12:45:51 -0500 Subject: [PATCH 027/176] Provide duration configuration to frontend --- .../src/app/core/config/configuration.service.ts | 12 ++++++++++++ .../src/app/core/datetime/timezone.service.ts | 15 ++++++++++++--- .../v3/configuration/configuration_representer.rb | 9 +++++++++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/frontend/src/app/core/config/configuration.service.ts b/frontend/src/app/core/config/configuration.service.ts index d34618a87039..52d7bd2b2725 100644 --- a/frontend/src/app/core/config/configuration.service.ts +++ b/frontend/src/app/core/config/configuration.service.ts @@ -95,6 +95,18 @@ export class ConfigurationService { return this.systemPreference('dateFormat'); } + public hoursPerDay():number { + return this.systemPreference('hoursPerDay'); + } + + public hoursPerWeek():number { + return this.systemPreference('hoursPerWeek'); + } + + public daysPerMonth():number { + return this.systemPreference('daysPerMonth'); + } + public timeFormatPresent():boolean { return !!this.systemPreference('timeFormat'); } diff --git a/frontend/src/app/core/datetime/timezone.service.ts b/frontend/src/app/core/datetime/timezone.service.ts index 2d5a073479e6..fe8042b6e1ef 100644 --- a/frontend/src/app/core/datetime/timezone.service.ts +++ b/frontend/src/app/core/datetime/timezone.service.ts @@ -131,16 +131,25 @@ export class TimezoneService { public formattedDuration(durationString:string, unit:'hour'|'days' = 'hour'):string { switch (unit) { case 'hour': - return this.I18n.t('js.units.hour', { count: this.toHours(durationString) }); + return this.I18n.t('js.units.hour', { + count: this.toHours(durationString), + }); case 'days': - return this.I18n.t('js.units.day', { count: this.toDays(durationString) }); + return this.I18n.t('js.units.day', { + count: this.toDays(durationString), + }); default: // Case fallthrough for eslint return ''; } } - public formattedChronicDuration(durationString:string, opts = { format: 'short' }):string { + public formattedChronicDuration(durationString:string, opts = { + format: 'short', + hoursPerDay: this.configurationService.hoursPerDay(), + hoursPerWeek: this.configurationService.hoursPerWeek(), + daysPerMonth: this.configurationService.daysPerMonth(), + }):string { return outputChronicDuration(this.toHours(durationString) * 3600, opts) || '0h'; } diff --git a/lib/api/v3/configuration/configuration_representer.rb b/lib/api/v3/configuration/configuration_representer.rb index e5e51be1c568..f4a9d703745b 100644 --- a/lib/api/v3/configuration/configuration_representer.rb +++ b/lib/api/v3/configuration/configuration_representer.rb @@ -76,6 +76,15 @@ class ConfigurationRepresenter < ::API::Decorators::Single }, render_nil: true + property :hours_per_day, + render_nil: true + + property :hours_per_week, + render_nil: true + + property :days_per_month, + render_nil: true + property :host_name, getter: ->(*) { Setting.host_name From b600e762446bbfc4116171548841e62c3dc8cb75 Mon Sep 17 00:00:00 2001 From: Aaron Contreras Date: Tue, 21 May 2024 14:10:00 -0500 Subject: [PATCH 028/176] Sync days_per_week and days_per_month on client side --- .../working_days_and_hours_params_contract.rb | 12 ++-- ...king_days_and_hours_settings_controller.rb | 2 +- .../working_days_and_hours_update_service.rb | 1 - .../show.html.erb | 18 ++++-- config/constants/settings/definition.rb | 6 +- config/locales/en.yml | 13 +++-- .../working-days-and-hours.controller.ts | 58 +++++++++++++++++++ .../configuration_representer.rb | 2 +- ...days_and_hours_settings_controller_spec.rb | 6 +- 9 files changed, 91 insertions(+), 27 deletions(-) create mode 100644 frontend/src/stimulus/controllers/dynamic/admin/working-days-and-hours.controller.ts diff --git a/app/contracts/settings/working_days_and_hours_params_contract.rb b/app/contracts/settings/working_days_and_hours_params_contract.rb index 70adb482c7db..7ce38caaeaa8 100644 --- a/app/contracts/settings/working_days_and_hours_params_contract.rb +++ b/app/contracts/settings/working_days_and_hours_params_contract.rb @@ -32,7 +32,7 @@ class WorkingDaysAndHoursParamsContract < ::ParamsContract validate :working_days_are_present validate :hours_per_day_are_present - validate :hours_per_week_are_present + validate :days_per_week_are_present validate :days_per_month_are_present validate :unique_job @@ -50,9 +50,9 @@ def hours_per_day_are_present end end - def hours_per_week_are_present - if hours_per_week.blank? - errors.add :base, :hours_per_week_are_missing + def days_per_week_are_present + if days_per_week.blank? + errors.add :base, :days_per_week_are_missing end end @@ -76,8 +76,8 @@ def hours_per_day params[:hours_per_day] end - def hours_per_week - params[:hours_per_week] + def days_per_week + params[:days_per_week] end def days_per_month diff --git a/app/controllers/admin/settings/working_days_and_hours_settings_controller.rb b/app/controllers/admin/settings/working_days_and_hours_settings_controller.rb index f6b40d0f8226..712395a1b141 100644 --- a/app/controllers/admin/settings/working_days_and_hours_settings_controller.rb +++ b/app/controllers/admin/settings/working_days_and_hours_settings_controller.rb @@ -47,7 +47,7 @@ def settings_params settings[:working_days] = working_days_params(settings) settings[:non_working_days] = non_working_days_params settings[:hours_per_day] = params[:settings][:hours_per_day] - settings[:hours_per_week] = params[:settings][:hours_per_week] + settings[:days_per_week] = params[:settings][:days_per_week] settings[:days_per_month] = params[:settings][:days_per_month] settings end diff --git a/app/services/settings/working_days_and_hours_update_service.rb b/app/services/settings/working_days_and_hours_update_service.rb index 50f80557a3aa..d3fe86a527bf 100644 --- a/app/services/settings/working_days_and_hours_update_service.rb +++ b/app/services/settings/working_days_and_hours_update_service.rb @@ -36,7 +36,6 @@ def call(params) end def validate_params(params) - binding.pry contract = Settings::WorkingDaysAndHoursParamsContract.new(model, user, params:) ServiceResult.new success: contract.valid?, errors: contract.errors, diff --git a/app/views/admin/settings/working_days_and_hours_settings/show.html.erb b/app/views/admin/settings/working_days_and_hours_settings/show.html.erb index 8c77b003cf47..e0813489c5ec 100644 --- a/app/views/admin/settings/working_days_and_hours_settings/show.html.erb +++ b/app/views/admin/settings/working_days_and_hours_settings/show.html.erb @@ -35,7 +35,9 @@ See COPYRIGHT and LICENSE files for more details. class: 'op-working-days-admin-settings' ) do %> -
+
<%= setting_text_field :hours_per_day, @@ -44,14 +46,18 @@ See COPYRIGHT and LICENSE files for more details.
- <%= setting_text_field :hours_per_week, - type: :number %> -
<%= t("setting_hours_per_week_explanation") %>
+ <%= setting_text_field :days_per_week, + type: :number, + data: { admin__working_days_and_hours_target: 'daysPerWeekInput', + action: 'blur->admin--working-days-and-hours#recalculateDaysPerMonth' } %> +
<%= t("setting_days_per_week_explanation") %>
<%= setting_text_field :days_per_month, - type: :number %> + type: :number, + data: { admin__working_days_and_hours_target: 'daysPerMonthInput', + action: 'blur->admin--working-days-and-hours#recalculateDaysPerWeek' } %>
<%= t("setting_days_per_month_explanation") %>
@@ -65,7 +71,7 @@ See COPYRIGHT and LICENSE files for more details.

- +
<%= t('settings.working_days.section_work_week') %> diff --git a/config/constants/settings/definition.rb b/config/constants/settings/definition.rb index e3f384d84caa..caf0b5405617 100644 --- a/config/constants/settings/definition.rb +++ b/config/constants/settings/definition.rb @@ -533,10 +533,10 @@ class Definition default: 8, format: :integer }, - hours_per_week: { + days_per_week: { description: "This will define what is considered a “week” when displaying duration in a more natural way " \ - "(for example, if a week is 40 hours, 1260 hours would be 7.5 weeks).", - default: 40, + "(for example, if a week is 5 days, 15 days 3 weeks).", + default: 5, format: :integer }, # Health check configuration diff --git a/config/locales/en.yml b/config/locales/en.yml index ece40dc3420a..f2e5360153ff 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1018,7 +1018,7 @@ Project attributes and sections are defined in the + This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Default language" setting_default_projects_modules: "Default enabled modules for new projects" setting_default_projects_public: "New projects are public by default" @@ -3096,10 +3097,10 @@ Project attributes and sections are defined in the - This will define what is considered a “day” when displaying duration in a more natural way (for example, if a day is 8 hours, 32 hours would be 4 days). - setting_hours_per_week: "Hours per week" - setting_hours_per_week_explanation: > - This will define what is considered a “week” when displaying duration in a more natural way (for example, if a week is 40 hours, 1260 hours would be 7.5 weeks). + This will define what is considered a "day" when displaying duration in a more natural way (for example, if a day is 8 hours, 32 hours would be 4 days). + setting_days_per_week: "Days per week" + setting_days_per_week_explanation: > + This will define what is considered a "week" when displaying duration in a more natural way (for example, if a week is 5 days, 15 days 3 weeks). setting_invitation_expiration_days: "Activation email expires after" setting_work_package_done_ratio: "Progress calculation" setting_work_package_done_ratio_field: "Work-based" diff --git a/frontend/src/stimulus/controllers/dynamic/admin/working-days-and-hours.controller.ts b/frontend/src/stimulus/controllers/dynamic/admin/working-days-and-hours.controller.ts new file mode 100644 index 000000000000..69298a5fe7a3 --- /dev/null +++ b/frontend/src/stimulus/controllers/dynamic/admin/working-days-and-hours.controller.ts @@ -0,0 +1,58 @@ +/* + * -- copyright + * OpenProject is an open source project management software. + * Copyright (C) 2023 the OpenProject GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 3. + * + * OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: + * Copyright (C) 2006-2013 Jean-Philippe Lang + * Copyright (C) 2010-2013 the ChiliProject Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * See COPYRIGHT and LICENSE files for more details. + * ++ + */ + +import { Controller } from '@hotwired/stimulus'; + +/* + * Helps keep daysPerWeek and daysPerMonth in-line with each other + */ +export default class WorkingDaysAndHoursController extends Controller { + static targets = [ + 'daysPerWeekInput', + 'daysPerMonthInput', + ]; + + declare readonly daysPerWeekInputTarget:HTMLInputElement; + declare readonly daysPerMonthInputTarget:HTMLInputElement; + + connect() {} + + recalculateDaysPerWeek() { + const daysPerMonth = parseFloat(this.daysPerMonthInputTarget.value); + const daysPerWeek = daysPerMonth / 4; + this.daysPerWeekInputTarget.value = daysPerWeek.toString(); + } + + recalculateDaysPerMonth() { + const daysPerWeek = parseFloat(this.daysPerWeekInputTarget.value); + const daysPerMonth = daysPerWeek * 4; + this.daysPerMonthInputTarget.value = daysPerMonth.toString(); + } +} diff --git a/lib/api/v3/configuration/configuration_representer.rb b/lib/api/v3/configuration/configuration_representer.rb index f4a9d703745b..b10f31f8c555 100644 --- a/lib/api/v3/configuration/configuration_representer.rb +++ b/lib/api/v3/configuration/configuration_representer.rb @@ -79,7 +79,7 @@ class ConfigurationRepresenter < ::API::Decorators::Single property :hours_per_day, render_nil: true - property :hours_per_week, + property :days_per_week, render_nil: true property :days_per_month, diff --git a/spec/controllers/admin/settings/working_days_and_hours_settings_controller_spec.rb b/spec/controllers/admin/settings/working_days_and_hours_settings_controller_spec.rb index baca0292526d..38e753137e99 100644 --- a/spec/controllers/admin/settings/working_days_and_hours_settings_controller_spec.rb +++ b/spec/controllers/admin/settings/working_days_and_hours_settings_controller_spec.rb @@ -39,10 +39,10 @@ let(:working_days) { [*"1".."7"] } let(:non_working_days_attributes) { {} } let(:hours_per_day) { 4 } - let(:hours_per_week) { 16 } - let(:days_per_month) { 25 } + let(:days_per_week) { 5 } + let(:days_per_month) { 20 } let(:params) do - { settings: { working_days:, non_working_days_attributes:, hours_per_day:, hours_per_week:, days_per_month: } } + { settings: { working_days:, non_working_days_attributes:, hours_per_day:, days_per_week:, days_per_month: } } end subject { patch "update", params: } From be3c0c83a1c0cd2838cc9a4643336c2024ea9d8b Mon Sep 17 00:00:00 2001 From: Aaron Contreras Date: Tue, 21 May 2024 15:44:08 -0500 Subject: [PATCH 029/176] Ensure backend validation for days_per_week/days_per_month consistency --- .../working_days_and_hours_params_contract.rb | 9 +++++++++ app/services/duration_converter.rb | 4 +++- config/locales/en.yml | 1 + .../src/app/core/datetime/timezone.service.ts | 5 ++++- ...ing_days_and_hours_params_contract_spec.rb | 19 ++++++++++++++----- 5 files changed, 31 insertions(+), 7 deletions(-) diff --git a/app/contracts/settings/working_days_and_hours_params_contract.rb b/app/contracts/settings/working_days_and_hours_params_contract.rb index 7ce38caaeaa8..2a73109218ae 100644 --- a/app/contracts/settings/working_days_and_hours_params_contract.rb +++ b/app/contracts/settings/working_days_and_hours_params_contract.rb @@ -34,6 +34,7 @@ class WorkingDaysAndHoursParamsContract < ::ParamsContract validate :hours_per_day_are_present validate :days_per_week_are_present validate :days_per_month_are_present + validate :days_per_week_and_days_per_month_are_consistent validate :unique_job protected @@ -62,6 +63,14 @@ def days_per_month_are_present end end + def days_per_week_and_days_per_month_are_consistent + if days_per_week && + days_per_month && + days_per_week.to_i != days_per_month.to_i / ChronicDuration::FULL_WEEKS_PER_MONTH + errors.add :base, :days_per_week_and_days_per_month_are_inconsistent + end + end + def unique_job WorkPackages::ApplyWorkingDaysChangeJob.new.check_concurrency do errors.add :base, :previous_working_day_changes_unprocessed diff --git a/app/services/duration_converter.rb b/app/services/duration_converter.rb index 885ec15805ad..921a4784c44d 100644 --- a/app/services/duration_converter.rb +++ b/app/services/duration_converter.rb @@ -66,7 +66,9 @@ def convert_duration_to_seconds(duration_in_hours) end def duration_length_options - { hours_per_day: Setting.hours_per_day, days_per_month: Setting.days_per_month } + { hours_per_day: Setting.hours_per_day, + days_per_month: Setting.days_per_month, + weeks: true } end end end diff --git a/config/locales/en.yml b/config/locales/en.yml index f2e5360153ff..2c9ad9191e6b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1020,6 +1020,7 @@ Project attributes and sections are defined in the Date: Tue, 21 May 2024 20:02:25 -0500 Subject: [PATCH 030/176] Adapt specs to new format --- .../costs/spec/features/time_entries_spec.rb | 2 +- .../activities/work_package_activity_spec.rb | 6 ++-- .../display_fields/work_display_spec.rb | 14 ++++---- .../work_packages/edit_work_package_spec.rb | 2 +- .../features/work_packages/index_sums_spec.rb | 34 +++++++++---------- .../work_packages/progress_modal_spec.rb | 6 ++-- .../work_packages/remaining_time_spec.rb | 6 ++-- 7 files changed, 35 insertions(+), 35 deletions(-) diff --git a/modules/costs/spec/features/time_entries_spec.rb b/modules/costs/spec/features/time_entries_spec.rb index eb7c5c03a421..cb0a76abe215 100644 --- a/modules/costs/spec/features/time_entries_spec.rb +++ b/modules/costs/spec/features/time_entries_spec.rb @@ -73,7 +73,7 @@ parent_row = wp_table.row(parent) wp_row = wp_table.row(work_package) - expect(parent_row).to have_css(".inline-edit--container.spentTime", text: "12h 30m") + expect(parent_row).to have_css(".inline-edit--container.spentTime", text: "1d 4h 30m") expect(wp_row).to have_css(".inline-edit--container.spentTime", text: "2h 30m") end diff --git a/spec/features/activities/work_package_activity_spec.rb b/spec/features/activities/work_package_activity_spec.rb index fd72f6f943b8..3eab179c7920 100644 --- a/spec/features/activities/work_package_activity_spec.rb +++ b/spec/features/activities/work_package_activity_spec.rb @@ -61,10 +61,10 @@ it "displays changed attributes in the activity tab", :aggregate_failures do within("activity-entry", text: admin.name) do expect(page).to have_list_item(text: "% Complete set to 50%") - expect(page).to have_list_item(text: "Work set to 10h") + expect(page).to have_list_item(text: "Work set to 1d 2h") expect(page).to have_list_item(text: "Remaining work set to 5h") - expect(page).to have_list_item(text: "Total work set to 20h") - expect(page).to have_list_item(text: "Total remaining work set to 8h") + expect(page).to have_list_item(text: "Total work set to 2d 4h") + expect(page).to have_list_item(text: "Total remaining work set to 1d") expect(page).to have_list_item(text: "Total % complete set to 60%") end end diff --git a/spec/features/work_packages/display_fields/work_display_spec.rb b/spec/features/work_packages/display_fields/work_display_spec.rb index 7bbd7a756e40..ddfee0c921b0 100644 --- a/spec/features/work_packages/display_fields/work_display_spec.rb +++ b/spec/features/work_packages/display_fields/work_display_spec.rb @@ -172,11 +172,11 @@ wp_table.visit_query query # parent - expect(page).to have_content("5h·Σ 20h") - expect(page).to have_link("Σ 20h") + expect(page).to have_content("5h·Σ 2d 4h") + expect(page).to have_link("Σ 2d 4h") # child 2 - expect(page).to have_content("3h·Σ 15h") - expect(page).to have_link("Σ 15h") + expect(page).to have_content("3h·Σ 1d 7h") + expect(page).to have_link("Σ 1d 7h") end context "when clicking the link of a top parent" do @@ -185,7 +185,7 @@ end it "shows a work package table with a parent filter to list the direct children" do - click_on("Σ 20h") + click_on("Σ 2d 4h") wp_table.expect_work_package_count(4) wp_table.expect_work_package_listed(parent, child1, child2, child3) @@ -202,8 +202,8 @@ end it "shows also all ancestors in the work package table" do - expect(page).to have_content("Work\n3h·Σ 15h") - click_on("Σ 15h") + expect(page).to have_content("Work\n3h·Σ 1d 7h") + click_on("Σ 1d 7h") wp_table.expect_work_package_count(3) wp_table.expect_work_package_listed(parent, child2, grand_child21) diff --git a/spec/features/work_packages/edit_work_package_spec.rb b/spec/features/work_packages/edit_work_package_spec.rb index e7308a5f04ba..07d5d8bf2e47 100644 --- a/spec/features/work_packages/edit_work_package_spec.rb +++ b/spec/features/work_packages/edit_work_package_spec.rb @@ -143,7 +143,7 @@ def visit! responsible: manager.name, assignee: manager.name, combinedDate: "03/04/2013 - 03/20/2013", - estimatedTime: "10h", + estimatedTime: "1d 2h", remainingTime: "7h", percentageDone: "30%", subject: "a new subject", diff --git a/spec/features/work_packages/index_sums_spec.rb b/spec/features/work_packages/index_sums_spec.rb index f94ea54f76cf..896ea730cb85 100644 --- a/spec/features/work_packages/index_sums_spec.rb +++ b/spec/features/work_packages/index_sums_spec.rb @@ -146,8 +146,8 @@ # Expect the total sums row aggregate_failures do within(:row, "Total sum") do |row| - expect(row).to have_css(".estimatedTime", text: "1d 1h") - expect(row).to have_css(".remainingTime", text: "12h 30m") + expect(row).to have_css(".estimatedTime", text: "3d 1h") + expect(row).to have_css(".remainingTime", text: "1d 4h 30m") expect(row).to have_css(".#{int_cf.attribute_name(:camel_case)}", text: "12") expect(row).to have_css(".#{float_cf.attribute_name(:camel_case)}", text: "13.2") expect(row).to have_css(".laborCosts", text: "15.00 EUR") @@ -164,8 +164,8 @@ aggregate_failures do within(:row, "Total sum") do |row| - expect(row).to have_css(".estimatedTime", text: "1d 11h") - expect(row).to have_css(".remainingTime", text: "19h 30m") + expect(row).to have_css(".estimatedTime", text: "4d 3h") + expect(row).to have_css(".remainingTime", text: "2d 3h 30m") expect(row).to have_css(".#{int_cf.attribute_name(:camel_case)}", text: "12") expect(row).to have_css(".#{float_cf.attribute_name(:camel_case)}", text: "13.2") expect(row).to have_css(".laborCosts", text: "15.00 EUR") @@ -184,8 +184,8 @@ first_sum_row, second_sum_row = *find_all(:row, "Sum") # First status row aggregate_failures do - expect(first_sum_row).to have_css(".estimatedTime", text: "20h") - expect(first_sum_row).to have_css(".remainingTime", text: "12h") + expect(first_sum_row).to have_css(".estimatedTime", text: "2d 4h") + expect(first_sum_row).to have_css(".remainingTime", text: "1d 4h") expect(first_sum_row).to have_css(".#{int_cf.attribute_name(:camel_case)}", text: "5") expect(first_sum_row).to have_css(".#{float_cf.attribute_name(:camel_case)}", text: "5.5") expect(first_sum_row).to have_css(".laborCosts", text: "15.00 EUR") @@ -195,7 +195,7 @@ # Second status row aggregate_failures do - expect(second_sum_row).to have_css(".estimatedTime", text: "15h") + expect(second_sum_row).to have_css(".estimatedTime", text: "1d 7h") expect(second_sum_row).to have_css(".remainingTime", text: "7h 30m") expect(second_sum_row).to have_css(".#{int_cf.attribute_name(:camel_case)}", text: "7") expect(second_sum_row).to have_css(".#{float_cf.attribute_name(:camel_case)}", text: "7.7") @@ -207,8 +207,8 @@ # Total sums row is unchanged aggregate_failures do within(:row, "Total sum") do |row| - expect(row).to have_css(".estimatedTime", text: "1d 11h") - expect(row).to have_css(".remainingTime", text: "19h 30m") + expect(row).to have_css(".estimatedTime", text: "4d 3h") + expect(row).to have_css(".remainingTime", text: "2d 3h 30m") expect(row).to have_css(".#{int_cf.attribute_name(:camel_case)}", text: "12") expect(row).to have_css(".#{float_cf.attribute_name(:camel_case)}", text: "13.2") expect(row).to have_css(".laborCosts", text: "15.00 EUR") @@ -282,8 +282,8 @@ # Expect the total sums row without filtering aggregate_failures do within(:row, "Total sum") do |row| - expect(row).to have_css(".estimatedTime", text: "2d 2h") - expect(row).to have_css(".remainingTime", text: "1d 1h") + expect(row).to have_css(".estimatedTime", text: "1w 1d 2h") + expect(row).to have_css(".remainingTime", text: "3d 1h") expect(row).to have_css(".#{int_cf.attribute_name(:camel_case)}", text: "24") expect(row).to have_css(".#{float_cf.attribute_name(:camel_case)}", text: "26.4") expect(row).to have_css(".laborCosts", text: "40.00 EUR") @@ -303,8 +303,8 @@ # Expect the total sums row to have changed aggregate_failures do within(:row, "Total sum") do |row| - expect(row).to have_css(".estimatedTime", text: "1d 6h") - expect(row).to have_css(".remainingTime", text: "15h") + expect(row).to have_css(".estimatedTime", text: "3d 6h") + expect(row).to have_css(".remainingTime", text: "1d 7h") expect(row).to have_css(".#{int_cf.attribute_name(:camel_case)}", text: "14") expect(row).to have_css(".#{float_cf.attribute_name(:camel_case)}", text: "15.4") expect(row).to have_css(".laborCosts", text: "", exact_text: true) @@ -328,7 +328,7 @@ first_sum_row, second_sum_row = *find_all(:row, "Sum") # First status row aggregate_failures do - expect(first_sum_row).to have_css(".estimatedTime", text: "10h") + expect(first_sum_row).to have_css(".estimatedTime", text: "1d 2h") expect(first_sum_row).to have_css(".remainingTime", text: "5h") expect(first_sum_row).to have_css(".#{int_cf.attribute_name(:camel_case)}", text: "5") expect(first_sum_row).to have_css(".#{float_cf.attribute_name(:camel_case)}", text: "5.5") @@ -339,7 +339,7 @@ # Second status row aggregate_failures do - expect(second_sum_row).to have_css(".estimatedTime", text: "15h") + expect(second_sum_row).to have_css(".estimatedTime", text: "1d 7h") expect(second_sum_row).to have_css(".remainingTime", text: "7h 30m") expect(second_sum_row).to have_css(".#{int_cf.attribute_name(:camel_case)}", text: "7") expect(second_sum_row).to have_css(".#{float_cf.attribute_name(:camel_case)}", text: "7.7") @@ -351,8 +351,8 @@ # Total sum aggregate_failures do within(:row, "Total sum") do |row| - expect(row).to have_css(".estimatedTime", text: "1d 1h") - expect(row).to have_css(".remainingTime", text: "12h 30m") + expect(row).to have_css(".estimatedTime", text: "3d 1h") + expect(row).to have_css(".remainingTime", text: "1d 4h 30m") expect(row).to have_css(".#{int_cf.attribute_name(:camel_case)}", text: "12") expect(row).to have_css(".#{float_cf.attribute_name(:camel_case)}", text: "13.2") expect(row).to have_css(".laborCosts", text: "15.00 EUR") diff --git a/spec/features/work_packages/progress_modal_spec.rb b/spec/features/work_packages/progress_modal_spec.rb index 3ce425906147..3e4b7b9f7fa0 100644 --- a/spec/features/work_packages/progress_modal_spec.rb +++ b/spec/features/work_packages/progress_modal_spec.rb @@ -350,7 +350,7 @@ def update_work_package_with(work_package, attributes) work_edit_field.activate! - work_edit_field.expect_modal_field_value("10h") + work_edit_field.expect_modal_field_value("1d 2h") remaining_work_edit_field.expect_modal_field_value("2h 7m 12s") percent_complete_edit_field.expect_modal_field_value("78", readonly: true) end @@ -521,7 +521,7 @@ def update_work_package_with(work_package, attributes) specify "Case 2: when work is set to 12h, " \ "remaining work is automatically set to 6h " \ "and subsequently work is set to 14h, " \ - "remaining work updates to 8h" do + "remaining work updates to 1d" do work_package_table.visit_query(progress_query) work_package_table.expect_work_package_listed(work_package) @@ -537,7 +537,7 @@ def update_work_package_with(work_package, attributes) work_edit_field.set_value("14") page.driver.wait_for_network_idle # Wait for live-update to finish - remaining_work_edit_field.expect_modal_field_value("8h") + remaining_work_edit_field.expect_modal_field_value("1d") end specify "Case 3: when work is set to 2h, " \ diff --git a/spec/features/work_packages/remaining_time_spec.rb b/spec/features/work_packages/remaining_time_spec.rb index 7283d7142db5..599d999fec3f 100644 --- a/spec/features/work_packages/remaining_time_spec.rb +++ b/spec/features/work_packages/remaining_time_spec.rb @@ -50,7 +50,7 @@ # need to update work first to enable the remaining work field wp_page.update_attributes estimatedTime: "200" # rubocop:disable Rails/ActiveRecordAliases wp_page.update_attributes remainingTime: "125" # rubocop:disable Rails/ActiveRecordAliases - wp_page.expect_attributes remainingTime: "5d 5h" + wp_page.expect_attributes remainingTime: "3w 5h" work_package.reload expect(work_package.remaining_hours).to eq 125.0 @@ -70,8 +70,8 @@ # need to update work first to enable the remaining work field wp_table_page.update_work_package_attributes work_package, estimatedTime: "200" wp_table_page.update_work_package_attributes work_package, remainingTime: "125" - wp_table_page.expect_work_package_with_attributes work_package, remainingTime: "5d 5h" - wp_table_page.expect_sums_row_with_attributes remainingTime: "5d 5h" + wp_table_page.expect_work_package_with_attributes work_package, remainingTime: "3w 5h" + wp_table_page.expect_sums_row_with_attributes remainingTime: "3w 5h" work_package.reload expect(work_package.remaining_hours).to eq 125.0 From 7651bba4d0e486e3c10e8a1ae68ff337ee1b41c7 Mon Sep 17 00:00:00 2001 From: Aaron Contreras Date: Tue, 21 May 2024 20:52:42 -0500 Subject: [PATCH 031/176] Lint ABC branch condition size --- ...orking_days_and_hours_settings_controller.rb | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/app/controllers/admin/settings/working_days_and_hours_settings_controller.rb b/app/controllers/admin/settings/working_days_and_hours_settings_controller.rb index 712395a1b141..df067f5f9740 100644 --- a/app/controllers/admin/settings/working_days_and_hours_settings_controller.rb +++ b/app/controllers/admin/settings/working_days_and_hours_settings_controller.rb @@ -43,13 +43,11 @@ def failure_callback(call) protected def settings_params - settings = super - settings[:working_days] = working_days_params(settings) - settings[:non_working_days] = non_working_days_params - settings[:hours_per_day] = params[:settings][:hours_per_day] - settings[:days_per_week] = params[:settings][:days_per_week] - settings[:days_per_month] = params[:settings][:days_per_month] - settings + super.tap do |settings| + settings[:working_days] = working_days_params(settings) + settings[:non_working_days] = non_working_days_params + settings.merge(duration_configuration_params) + end end def update_service @@ -67,6 +65,11 @@ def non_working_days_params non_working_days.to_h.values end + def duration_configuration_params + params.require(:settings) + .permit(:hours_per_day, :days_per_week, :days_per_month) + end + def modified_non_working_days_for(result) return if result.nil? From 157bf473b94e9050d7b33da046105b2ce478eaad Mon Sep 17 00:00:00 2001 From: Aaron Contreras Date: Fri, 24 May 2024 11:10:38 -0500 Subject: [PATCH 032/176] Rely on duration params being provided by parent class --- .../settings/working_days_and_hours_settings_controller.rb | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/controllers/admin/settings/working_days_and_hours_settings_controller.rb b/app/controllers/admin/settings/working_days_and_hours_settings_controller.rb index df067f5f9740..b0bd50d11abd 100644 --- a/app/controllers/admin/settings/working_days_and_hours_settings_controller.rb +++ b/app/controllers/admin/settings/working_days_and_hours_settings_controller.rb @@ -46,7 +46,6 @@ def settings_params super.tap do |settings| settings[:working_days] = working_days_params(settings) settings[:non_working_days] = non_working_days_params - settings.merge(duration_configuration_params) end end @@ -65,11 +64,6 @@ def non_working_days_params non_working_days.to_h.values end - def duration_configuration_params - params.require(:settings) - .permit(:hours_per_day, :days_per_week, :days_per_month) - end - def modified_non_working_days_for(result) return if result.nil? From 15d4145f9e8fa3440aa2b068fd802d750343c408 Mon Sep 17 00:00:00 2001 From: Aaron Contreras Date: Fri, 24 May 2024 11:32:32 -0500 Subject: [PATCH 033/176] Ensure durations are positive numbers --- .../working_days_and_hours_params_contract.rb | 16 +++++++++++ config/locales/en.yml | 1 + ...ing_days_and_hours_params_contract_spec.rb | 28 +++++++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/app/contracts/settings/working_days_and_hours_params_contract.rb b/app/contracts/settings/working_days_and_hours_params_contract.rb index 2a73109218ae..4a347f4c9884 100644 --- a/app/contracts/settings/working_days_and_hours_params_contract.rb +++ b/app/contracts/settings/working_days_and_hours_params_contract.rb @@ -34,6 +34,7 @@ class WorkingDaysAndHoursParamsContract < ::ParamsContract validate :hours_per_day_are_present validate :days_per_week_are_present validate :days_per_month_are_present + validate :durations_are_positive_values validate :days_per_week_and_days_per_month_are_consistent validate :unique_job @@ -63,6 +64,21 @@ def days_per_month_are_present end end + def durations_are_positive_values + if hours_per_day && + days_per_week && + days_per_month && + any_duration_is_negative_or_zero? + errors.add :base, :durations_are_not_positive_numbers + end + end + + def any_duration_is_negative_or_zero? + !hours_per_day.to_i.positive? || + !days_per_week.to_i.positive? || + !days_per_month.to_i.positive? + end + def days_per_week_and_days_per_month_are_consistent if days_per_week && days_per_month && diff --git a/config/locales/en.yml b/config/locales/en.yml index 2c9ad9191e6b..48e989a9ffbe 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1020,6 +1020,7 @@ Project attributes and sections are defined in the Date: Fri, 24 May 2024 11:35:13 -0500 Subject: [PATCH 034/176] Limit the width of duration input fields --- .../settings/working_days_and_hours_settings/show.html.erb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/views/admin/settings/working_days_and_hours_settings/show.html.erb b/app/views/admin/settings/working_days_and_hours_settings/show.html.erb index e0813489c5ec..aab35422d284 100644 --- a/app/views/admin/settings/working_days_and_hours_settings/show.html.erb +++ b/app/views/admin/settings/working_days_and_hours_settings/show.html.erb @@ -41,13 +41,15 @@ See COPYRIGHT and LICENSE files for more details.
<%= setting_text_field :hours_per_day, - type: :number %> + type: :number, + container_class: "-wide" %>
<%= t("setting_hours_per_day_explanation") %>
<%= setting_text_field :days_per_week, type: :number, + container_class: "-wide", data: { admin__working_days_and_hours_target: 'daysPerWeekInput', action: 'blur->admin--working-days-and-hours#recalculateDaysPerMonth' } %>
<%= t("setting_days_per_week_explanation") %>
@@ -56,6 +58,7 @@ See COPYRIGHT and LICENSE files for more details.
<%= setting_text_field :days_per_month, type: :number, + container_class: "-wide", data: { admin__working_days_and_hours_target: 'daysPerMonthInput', action: 'blur->admin--working-days-and-hours#recalculateDaysPerWeek' } %>
<%= t("setting_days_per_month_explanation") %>
From adfa1bd7f6863d2f953f25f95cbe9597b514e04d Mon Sep 17 00:00:00 2001 From: Aaron Contreras Date: Fri, 24 May 2024 11:50:54 -0500 Subject: [PATCH 035/176] Move toast warning to appropriate section --- .../show.html.erb | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/app/views/admin/settings/working_days_and_hours_settings/show.html.erb b/app/views/admin/settings/working_days_and_hours_settings/show.html.erb index aab35422d284..5d0b93127a6f 100644 --- a/app/views/admin/settings/working_days_and_hours_settings/show.html.erb +++ b/app/views/admin/settings/working_days_and_hours_settings/show.html.erb @@ -67,18 +67,9 @@ See COPYRIGHT and LICENSE files for more details.
-
-
-

- <%= t("working_days.warning").html_safe %> -

-
-
-
<%= t('settings.working_days.section_work_week') %> -

<%= t("working_days.info").html_safe %>

@@ -90,6 +81,13 @@ See COPYRIGHT and LICENSE files for more details. direction: :horizontal %> +
+
+

+ <%= t("working_days.warning").html_safe %> +

+
+
From 1111687a605d36777b574f084191d8cb623deec0 Mon Sep 17 00:00:00 2001 From: Christophe Bliard Date: Mon, 27 May 2024 11:43:24 +0200 Subject: [PATCH 036/176] Move toast warning to even more appropriate location Also: - reword the warning message slightly to remove the "click apply to apply" part. - remove some html_safe calls that are not needed anymore (especially since 2f82d73fb15). --- .../show.html.erb | 21 +++++++++---------- config/locales/en.yml | 7 ++++--- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/app/views/admin/settings/working_days_and_hours_settings/show.html.erb b/app/views/admin/settings/working_days_and_hours_settings/show.html.erb index 5d0b93127a6f..29bf4690feb8 100644 --- a/app/views/admin/settings/working_days_and_hours_settings/show.html.erb +++ b/app/views/admin/settings/working_days_and_hours_settings/show.html.erb @@ -70,24 +70,23 @@ See COPYRIGHT and LICENSE files for more details.
<%= t('settings.working_days.section_work_week') %> +
+
+

+ <%= t("working_days.warning") %> +

+
+

- <%= t("working_days.info").html_safe %> +

+ <%= t("working_days.info") %>

<%= setting_multiselect :working_days, - I18n.t('date.day_names').rotate.zip(WeekDay::DAY_RANGE), direction: :horizontal %>
- -
-
-

- <%= t("working_days.warning").html_safe %> -

-
-
@@ -96,7 +95,7 @@ See COPYRIGHT and LICENSE files for more details. <%= t('settings.working_days.section_holidays_and_closures') %>

- <%= t("working_days.instance_wide_info").html_safe %> + <%= t("working_days.instance_wide_info") %>

<%= angular_component_tag 'op-non-working-days-list', data: { modified_non_working_days: @modified_non_working_days } %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 48e989a9ffbe..eab053f2392d 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -3631,13 +3631,14 @@ Project attributes and sections are defined in the
- Days that are not selected are skipped when scheduling work packages (and not included in the day count). These can be overriden at a work-package level. + Days that are not selected are skipped when scheduling work packages (and not included in the day count). + These can be overridden at a work-package level. instance_wide_info: > Dates added to the list below are considered non-working and skipped when scheduling work packages. change_button: "Change working days" warning: > - Changing which days of the week are considered working days or non-working days can affect the start and finish days of all work packages in all projects in this instance.
- Please note that changes are only applied after you click on the apply changes button. + Changing which days of the week are considered working days or non-working days + can affect the start and finish days of all work packages in all projects in this instance. journal_note: changed: _**Working days** changed (%{changes})._ days: From 1e3221d10eede0610f983483cd8ccfc2938960c8 Mon Sep 17 00:00:00 2001 From: Eric Schubert Date: Mon, 27 May 2024 13:10:53 +0200 Subject: [PATCH 037/176] [#55033] added distance to github tab header - https://community.openproject.org/work_packages/55033 - used same distance, that button in relations tab has --- .../frontend/module/tab-header/styles/tab-header.sass | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/github_integration/frontend/module/tab-header/styles/tab-header.sass b/modules/github_integration/frontend/module/tab-header/styles/tab-header.sass index 0f80e7171fe4..1f118e3a5089 100644 --- a/modules/github_integration/frontend/module/tab-header/styles/tab-header.sass +++ b/modules/github_integration/frontend/module/tab-header/styles/tab-header.sass @@ -31,6 +31,7 @@ flex-wrap: wrap-reverse justify-content: flex-end + padding-bottom: 4px border-bottom: 1px solid #ddd margin: 0 0 0.8rem 0 From 567a6ccd40b7c9b51204dfc68022002d5006af2d Mon Sep 17 00:00:00 2001 From: Marcello Rocha Date: Tue, 28 May 2024 12:08:12 +0200 Subject: [PATCH 038/176] remove the link around the table --- .../_health_status_notification.html.erb | 130 +++++++++--------- .../storages/health_status_mailer_job.rb | 2 +- 2 files changed, 65 insertions(+), 67 deletions(-) diff --git a/modules/storages/app/views/storages/storages_mailer/_health_status_notification.html.erb b/modules/storages/app/views/storages/storages_mailer/_health_status_notification.html.erb index f91d94bb9f13..5f8366dfed66 100644 --- a/modules/storages/app/views/storages/storages_mailer/_health_status_notification.html.erb +++ b/modules/storages/app/views/storages/storages_mailer/_health_status_notification.html.erb @@ -27,78 +27,76 @@ See COPYRIGHT and LICENSE files for more details. ++#%> -
- <%= render layout: 'mailer/border_table' do %> - - - > - - <%= placeholder_cell('12px', vertical: true) %> - - <%= placeholder_cell('12px', vertical: true) %> - - - - <%= placeholder_cell('8px', vertical: false) %> - - - - <%= placeholder_cell('12px', vertical: true) %> - +<%= render layout: 'mailer/border_table' do %> + + - - <% end %> - + <% end %> +
- > - - - - <%= placeholder_cell('8px', vertical: true) %> - - - -
- <% if state == :unhealthy %> - <%= render Mailer::LabelComponent.new(scheme: :danger, text: 'Error') %> - <% else %> - <%= render Mailer::LabelComponent.new(scheme: :success, text: 'Healthy') %> - <% end %> - - <%= I18n.t("storages.provider_types.#{storage.short_provider_type}.name") %> - <%= storage.host %> -
-
<%= storage.name %>
+ > + + <%= placeholder_cell('12px', vertical: true) %> + + <%= placeholder_cell('12px', vertical: true) %> + + + + <%= placeholder_cell('8px', vertical: false) %> + + + + <%= placeholder_cell('12px', vertical: true) %> + + <%= placeholder_cell('12px', vertical: true) %> + + + + <%= placeholder_cell('8px', vertical: false) %> + + + + <%= placeholder_cell('12px', vertical: true) %> + + <%= placeholder_cell('12px', vertical: true) %> + + + <% if storage.provider_type == ::Storages::Storage::PROVIDER_TYPE_NEXTCLOUD && state == :unhealthy %> + <%= placeholder_cell('12px', vertical: true) %> - - - <%= placeholder_cell('8px', vertical: false) %> - - - - <%= placeholder_cell('12px', vertical: true) %> + <%= placeholder_cell('12px', vertical: true) %> - - <% if storage.provider_type == ::Storages::Storage::PROVIDER_TYPE_NEXTCLOUD && state == :unhealthy %> - - <%= placeholder_cell('12px', vertical: true) %> - - - - <%= placeholder_cell('12px', vertical: true) %> - - <% end %> -
+ > + + + + <%= placeholder_cell('8px', vertical: true) %> + + + +
+ <% if state == :unhealthy %> + <%= render Mailer::LabelComponent.new(scheme: :danger, text: 'Error') %> + <% else %> + <%= render Mailer::LabelComponent.new(scheme: :success, text: 'Healthy') %> + <% end %> + + <%= I18n.t("storages.provider_types.#{storage.short_provider_type}.name") %> - <%= storage.uri %> +
+
<%= storage.name %>
+ <% if state == :unhealthy %> + <%= reason %> <%= I18n.t('mail.storages.health.unhealthy.since') %> <%= format_time(storage.health_changed_at) %> + <% else %> + <%= reason %> <%= I18n.t('mail.storages.health.healthy.solved_at') %> <%= format_time(storage.health_changed_at) %> + <% end %> +
- <% if state == :unhealthy %> - <%= reason %> <%= I18n.t('mail.storages.health.unhealthy.since') %> <%= format_time(storage.health_changed_at) %> - <% else %> - <%= reason %> <%= I18n.t('mail.storages.health.healthy.solved_at') %> <%= format_time(storage.health_changed_at) %> - <% end %> + <%= I18n.t('mail.storages.health.unhealthy.troubleshooting.text') %> + <%= I18n.t('mail.storages.health.unhealthy.troubleshooting.link_text') %>.
- <%= I18n.t('mail.storages.health.unhealthy.troubleshooting.text') %> - <%= I18n.t('mail.storages.health.unhealthy.troubleshooting.link_text') %>. -
-
+ + +<% end %> > diff --git a/modules/storages/app/workers/storages/health_status_mailer_job.rb b/modules/storages/app/workers/storages/health_status_mailer_job.rb index d765e8746104..01b3ba5df0ae 100644 --- a/modules/storages/app/workers/storages/health_status_mailer_job.rb +++ b/modules/storages/app/workers/storages/health_status_mailer_job.rb @@ -50,7 +50,7 @@ def perform(storage:) return if storage.health_healthy? admin_users.each do |admin| - ::Storages::StoragesMailer.notify_unhealthy(admin, storage).deliver_later + StoragesMailer.notify_unhealthy(admin, storage).deliver_later end HealthStatusMailerJob.schedule(storage:) From 15005eea6bcfb7141468aaff684318c8838ad416 Mon Sep 17 00:00:00 2001 From: Christophe Bliard Date: Tue, 28 May 2024 17:07:19 +0200 Subject: [PATCH 039/176] [49409] Add icon to progress fields if status is excluded from totals --- .../features/hal/resources/status-resource.ts | 2 + .../hal/resources/work-package-resource.ts | 3 +- .../compound-progress-display-field.module.ts | 6 ++ .../excluded-icon-helper.service.ts | 64 +++++++++++++++++++ .../field-types/work-display-field.module.ts | 7 ++ .../inplace_editing/_display_fields.sass | 7 +- lib/api/v3/statuses/status_representer.rb | 1 + .../v3/statuses/status_representer_spec.rb | 15 +++-- 8 files changed, 98 insertions(+), 7 deletions(-) create mode 100644 frontend/src/app/shared/components/fields/display/field-types/excluded-icon-helper.service.ts diff --git a/frontend/src/app/features/hal/resources/status-resource.ts b/frontend/src/app/features/hal/resources/status-resource.ts index 504aaf093d2a..d2a5694de3c7 100644 --- a/frontend/src/app/features/hal/resources/status-resource.ts +++ b/frontend/src/app/features/hal/resources/status-resource.ts @@ -36,6 +36,8 @@ export class StatusResource extends HalResource { isReadonly:boolean; + excludedFromTotals:boolean; + public get state():InputState { return this.states.statuses.get(this.href as string) as any; } diff --git a/frontend/src/app/features/hal/resources/work-package-resource.ts b/frontend/src/app/features/hal/resources/work-package-resource.ts index 0be3adcfeb47..89fce7c137fd 100644 --- a/frontend/src/app/features/hal/resources/work-package-resource.ts +++ b/frontend/src/app/features/hal/resources/work-package-resource.ts @@ -44,6 +44,7 @@ import { HalResource } from 'core-app/features/hal/resources/hal-resource'; import { CollectionResource } from 'core-app/features/hal/resources/collection-resource'; import { TypeResource } from 'core-app/features/hal/resources/type-resource'; import { RelationResource } from 'core-app/features/hal/resources/relation-resource'; +import { StatusResource } from 'core-app/features/hal/resources/status-resource'; import { FormResource } from 'core-app/features/hal/resources/form-resource'; import { Attachable } from 'core-app/features/hal/resources/mixins/attachable-mixin'; import { ICKEditorContext } from 'core-app/shared/components/editor/components/ckeditor/ckeditor.types'; @@ -67,7 +68,7 @@ export interface WorkPackageResourceEmbedded { relations:CollectionResource; responsible:HalResource|any; revisions:CollectionResource|any; - status:HalResource|any; + status:StatusResource|any; timeEntries:HalResource[]|any[]; type:TypeResource; version:HalResource|any; diff --git a/frontend/src/app/shared/components/fields/display/field-types/compound-progress-display-field.module.ts b/frontend/src/app/shared/components/fields/display/field-types/compound-progress-display-field.module.ts index 4a7d283fcb2b..57a29f7ac857 100644 --- a/frontend/src/app/shared/components/fields/display/field-types/compound-progress-display-field.module.ts +++ b/frontend/src/app/shared/components/fields/display/field-types/compound-progress-display-field.module.ts @@ -36,12 +36,16 @@ import { import { HierarchyQueryLinkHelperService, } from 'core-app/shared/components/fields/display/field-types/hierarchy-query-link-helper.service'; +import { ExcludedIconHelperService } from 'core-app/shared/components/fields/display/field-types/excluded-icon-helper.service'; +import { WorkPackageResource } from 'core-app/features/hal/resources/work-package-resource'; export class CompoundProgressDisplayField extends DisplayField { @InjectField() PathHelper:PathHelperService; @InjectField() apiV3Service:ApiV3Service; + @InjectField() excludedIconHelperService:ExcludedIconHelperService; + @InjectField() hierarchyQueryLinkHelper:HierarchyQueryLinkHelperService; private derivedText = this.I18n.t('js.label_value_derived_from_children'); @@ -65,6 +69,8 @@ export class CompoundProgressDisplayField extends DisplayField { span.title = this.valueString; span.classList.add('-actual-value'); + this.excludedIconHelperService.addIconIfExcludedFromTotals(span, this.resource as WorkPackageResource); + element.appendChild(span); } diff --git a/frontend/src/app/shared/components/fields/display/field-types/excluded-icon-helper.service.ts b/frontend/src/app/shared/components/fields/display/field-types/excluded-icon-helper.service.ts new file mode 100644 index 000000000000..a22029340237 --- /dev/null +++ b/frontend/src/app/shared/components/fields/display/field-types/excluded-icon-helper.service.ts @@ -0,0 +1,64 @@ +// -- copyright +// OpenProject is an open source project management software. +// Copyright (C) 2012-2024 the OpenProject GmbH +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License version 3. +// +// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +// Copyright (C) 2006-2013 Jean-Philippe Lang +// Copyright (C) 2010-2013 the ChiliProject Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// See COPYRIGHT and LICENSE files for more details. +//++ + +import { Injectable } from '@angular/core'; +import { ApiV3Service } from 'core-app/core/apiv3/api-v3.service'; +import { WorkPackageResource } from 'core-app/features/hal/resources/work-package-resource'; +import { StatusResource } from 'core-app/features/hal/resources/status-resource'; + +@Injectable({ providedIn: 'root' }) + +export class ExcludedIconHelperService { + constructor( + private apiV3Service:ApiV3Service, + ) {} + + public addIconIfExcludedFromTotals(element:HTMLElement, resource:WorkPackageResource):void { + if (resource?.status) { + this.apiV3Service.statuses.id(resource.status as StatusResource).get().subscribe( + (status:StatusResource) => { + if (status.excludedFromTotals) { + this.addExcludedInfoIcon(element); + } + }, + ); + } + } + + public addExcludedInfoIcon(element:HTMLElement):void { + // This should work, but does not work when adding it through javascript + // + const icon = document.createElement('i'); + icon.classList.add('icon-info1', 'excluded-from-totals'); + element.appendChild(icon); + } +} diff --git a/frontend/src/app/shared/components/fields/display/field-types/work-display-field.module.ts b/frontend/src/app/shared/components/fields/display/field-types/work-display-field.module.ts index bb7414126d03..b9965281529c 100644 --- a/frontend/src/app/shared/components/fields/display/field-types/work-display-field.module.ts +++ b/frontend/src/app/shared/components/fields/display/field-types/work-display-field.module.ts @@ -32,7 +32,9 @@ import { TimezoneService } from 'core-app/core/datetime/timezone.service'; import { ApiV3Service } from 'core-app/core/apiv3/api-v3.service'; import { PathHelperService } from 'core-app/core/path-helper/path-helper.service'; import { uiStateLinkClass } from 'core-app/features/work-packages/components/wp-fast-table/builders/ui-state-link-builder'; +import { ExcludedIconHelperService } from 'core-app/shared/components/fields/display/field-types/excluded-icon-helper.service'; import { HierarchyQueryLinkHelperService } from 'core-app/shared/components/fields/display/field-types/hierarchy-query-link-helper.service'; +import { WorkPackageResource } from 'core-app/features/hal/resources/work-package-resource'; export class WorkDisplayField extends DisplayField { @InjectField() timezoneService:TimezoneService; @@ -41,6 +43,8 @@ export class WorkDisplayField extends DisplayField { @InjectField() apiV3Service:ApiV3Service; + @InjectField() excludedIconHelperService:ExcludedIconHelperService; + @InjectField() hierarchyQueryLinkHelper:HierarchyQueryLinkHelperService; private derivedText = this.I18n.t('js.label_value_derived_from_children'); @@ -98,6 +102,9 @@ export class WorkDisplayField extends DisplayField { } span.classList.add('-actual-value'); + if (this.value) { + this.excludedIconHelperService.addIconIfExcludedFromTotals(span, this.resource as WorkPackageResource); + } element.appendChild(span); } diff --git a/frontend/src/global_styles/content/work_packages/inplace_editing/_display_fields.sass b/frontend/src/global_styles/content/work_packages/inplace_editing/_display_fields.sass index 7bb82b874315..03a2802913fb 100644 --- a/frontend/src/global_styles/content/work_packages/inplace_editing/_display_fields.sass +++ b/frontend/src/global_styles/content/work_packages/inplace_editing/_display_fields.sass @@ -51,7 +51,6 @@ display-field padding-right: 0.25rem text-align: center - // READ value of edit fields .inline-edit--display-field display: inline-block @@ -101,6 +100,12 @@ display-field .-actual-value @include wp-table--actual-time-values + .excluded-from-totals + padding-left: 0.25rem + color: var(--fgColor-muted) + &:hover + color: var(--fgColor-default) + .-separator display: inline-block width: 1rem diff --git a/lib/api/v3/statuses/status_representer.rb b/lib/api/v3/statuses/status_representer.rb index 7012a529324b..1c5b041882a8 100644 --- a/lib/api/v3/statuses/status_representer.rb +++ b/lib/api/v3/statuses/status_representer.rb @@ -42,6 +42,7 @@ class StatusRepresenter < ::API::Decorators::Single render_nil: true property :is_default, render_nil: true property :is_readonly, render_nil: true + property :excluded_from_totals, render_nil: true property :default_done_ratio, render_nil: true property :position, render_nil: true diff --git a/spec/lib/api/v3/statuses/status_representer_spec.rb b/spec/lib/api/v3/statuses/status_representer_spec.rb index 799a822cc116..e704992c0710 100644 --- a/spec/lib/api/v3/statuses/status_representer_spec.rb +++ b/spec/lib/api/v3/statuses/status_representer_spec.rb @@ -30,9 +30,9 @@ RSpec.describe API::V3::Statuses::StatusRepresenter do let(:status) { build_stubbed(:status) } - let(:representer) { described_class.new(status, current_user: double("current_user")) } + let(:representer) { described_class.new(status, current_user: instance_double(User)) } - context "generation" do + describe "generation" do subject(:generated) { representer.to_json } it { is_expected.to include_json("Status".to_json).at_path("_type") } @@ -43,6 +43,7 @@ it { is_expected.to have_json_path("isClosed") } it { is_expected.to have_json_path("isDefault") } it { is_expected.to have_json_path("isReadonly") } + it { is_expected.to have_json_path("excludedFromTotals") } it { is_expected.to have_json_path("position") } it { is_expected.to have_json_path("defaultDoneRatio") } @@ -52,6 +53,7 @@ it { is_expected.to be_json_eql(status.is_closed.to_json).at_path("isClosed") } it { is_expected.to be_json_eql(status.is_default.to_json).at_path("isDefault") } it { is_expected.to be_json_eql(status.is_readonly.to_json).at_path("isReadonly") } + it { is_expected.to be_json_eql(status.excluded_from_totals.to_json).at_path("excludedFromTotals") } it { is_expected.to be_json_eql(status.position.to_json).at_path("position") } it { @@ -74,12 +76,15 @@ describe "caching" do it "is based on the representer's cache_key" do - expect(OpenProject::Cache) + allow(OpenProject::Cache) .to receive(:fetch) - .with(representer.json_cache_key) .and_call_original representer.to_json + + expect(OpenProject::Cache) + .to have_received(:fetch) + .with(representer.json_cache_key) end describe "#json_cache_key" do @@ -98,7 +103,7 @@ end it "changes when the status is updated" do - status.updated_at = Time.now + 20.seconds + status.updated_at = 20.seconds.from_now expect(representer.json_cache_key) .not_to eql former_cache_key From 43b6460aa5a75963101636c5435f89541b9ac1db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20Br=C3=A4unlein?= Date: Tue, 28 May 2024 16:34:18 +0200 Subject: [PATCH 040/176] [#55267] Replace webfonts-generator https://community.openproject.org/work_packages/55267 --- frontend/package.json | 2 +- frontend/src/app/spot/icon-font/generate.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index d0b6522834aa..80ef1701ab61 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -105,7 +105,7 @@ "@uirouter/angular": "^13.0.0", "@uirouter/core": "^6.1.0", "@uirouter/rx": "^1.0.0", - "@vusion/webfonts-generator": "^0.8.0", + "webfonts-generator-casaper": "^0.5.2", "@w11k/ngx-componentdestroyed": "^5.0.2", "@xeokit/xeokit-bim-viewer": "2.5.1-beta-28", "autoprefixer": "^10.4.19", diff --git a/frontend/src/app/spot/icon-font/generate.js b/frontend/src/app/spot/icon-font/generate.js index 4096638042bd..1be342317092 100644 --- a/frontend/src/app/spot/icon-font/generate.js +++ b/frontend/src/app/spot/icon-font/generate.js @@ -1,6 +1,6 @@ #!/usr/bin/env node -const webfontsGenerator = require('@vusion/webfonts-generator'); +const webfontsGenerator = require('webfonts-generator-casaper'); const path = require('path'); const glob = require("glob") From f7bd2309ddbef82bf3c973607e8c49f755604e9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20Br=C3=A4unlein?= Date: Tue, 28 May 2024 18:16:33 +0200 Subject: [PATCH 041/176] [#55267] Add missing icons https://community.openproject.org/work_packages/55267 --- .../spot/icon-font/src/arrow-thin-left.svg | 3 + .../app/spot/icon-font/src/baseline-add.svg | 4 + .../spot/icon-font/src/baseline-delete.svg | 4 + .../src/app/spot/icon-font/src/blocked.svg | 3 + .../spot/icon-font/src/bookmark-filled.svg | 3 + .../src/app/spot/icon-font/src/bookmark.svg | 3 + .../src/app/spot/icon-font/src/comments.svg | 3 + .../spot/icon-font/src/configure-knobs.svg | 4 + .../app/spot/icon-font/src/copy-documents.svg | 4 + .../spot/icon-font/src/enterprise-badge.svg | 4 + .../app/spot/icon-font/src/export-pdf-1.svg | 7 + .../icon-font/src/file-storage-connection.svg | 6 + .../app/spot/icon-font/src/github_logo.svg | 3 + .../app/spot/icon-font/src/gitlab_logo.svg | 7 + frontend/src/app/spot/icon-font/src/hide.svg | 4 + .../spot/icon-font/src/iconfont-scaler.svg | 3 + .../src/app/spot/icon-font/src/like-hand.svg | 3 + .../spot/icon-font/src/mention-comment.svg | 4 + .../app/spot/icon-font/src/not-watching.svg | 3 + .../src/app/spot/icon-font/src/remove-1.svg | 3 + .../spot/icon-font/src/return-to-previous.svg | 3 + .../spot/icon-font/src/settings-display.svg | 3 + .../src/app/spot/icon-font/src/snooze.svg | 3 + .../src/app/spot/icon-font/src/star-empty.svg | 3 + .../app/spot/icon-font/src/star-filled.svg | 3 + frontend/src/app/spot/icon-font/src/stop.svg | 3 + .../src/app/spot/icon-font/src/sum-error.svg | 4 + .../src/app/spot/icon-font/src/sum-sign.svg | 3 + .../app/spot/icon-font/src/today-arrows.svg | 5 + .../src/two-factor-authentification.svg | 5 + .../spot/icon-font/src/up-down-stepper.svg | 3 + .../app/spot/icon-font/src/user-missing.svg | 4 + .../src/app/spot/styles/sass/common/icon.sass | 1312 ++++---- .../openproject-icon-font.html | 2808 ++++++++++------- .../openproject-icon-font.svg | 2291 ++++++++++---- .../openproject-icon-font.ttf | Bin 55440 -> 90040 bytes .../openproject-icon-font.woff | Bin 32532 -> 47080 bytes .../openproject-icon-font.woff2 | Bin 26424 -> 39208 bytes .../openproject-spot-icon-font.svg | 2303 ++++++++++---- .../openproject-spot-icon-font.ttf | Bin 64600 -> 110156 bytes .../openproject-spot-icon-font.woff | Bin 38108 -> 45060 bytes .../openproject-spot-icon-font.woff2 | Bin 31508 -> 37488 bytes .../fonts/_openproject_icon_definitions.sass | 1421 +++++---- 43 files changed, 6546 insertions(+), 3709 deletions(-) create mode 100644 frontend/src/app/spot/icon-font/src/arrow-thin-left.svg create mode 100644 frontend/src/app/spot/icon-font/src/baseline-add.svg create mode 100644 frontend/src/app/spot/icon-font/src/baseline-delete.svg create mode 100644 frontend/src/app/spot/icon-font/src/blocked.svg create mode 100644 frontend/src/app/spot/icon-font/src/bookmark-filled.svg create mode 100644 frontend/src/app/spot/icon-font/src/bookmark.svg create mode 100644 frontend/src/app/spot/icon-font/src/comments.svg create mode 100644 frontend/src/app/spot/icon-font/src/configure-knobs.svg create mode 100644 frontend/src/app/spot/icon-font/src/copy-documents.svg create mode 100644 frontend/src/app/spot/icon-font/src/enterprise-badge.svg create mode 100644 frontend/src/app/spot/icon-font/src/export-pdf-1.svg create mode 100644 frontend/src/app/spot/icon-font/src/file-storage-connection.svg create mode 100644 frontend/src/app/spot/icon-font/src/github_logo.svg create mode 100644 frontend/src/app/spot/icon-font/src/gitlab_logo.svg create mode 100644 frontend/src/app/spot/icon-font/src/hide.svg create mode 100644 frontend/src/app/spot/icon-font/src/iconfont-scaler.svg create mode 100644 frontend/src/app/spot/icon-font/src/like-hand.svg create mode 100644 frontend/src/app/spot/icon-font/src/mention-comment.svg create mode 100644 frontend/src/app/spot/icon-font/src/not-watching.svg create mode 100644 frontend/src/app/spot/icon-font/src/remove-1.svg create mode 100644 frontend/src/app/spot/icon-font/src/return-to-previous.svg create mode 100644 frontend/src/app/spot/icon-font/src/settings-display.svg create mode 100644 frontend/src/app/spot/icon-font/src/snooze.svg create mode 100644 frontend/src/app/spot/icon-font/src/star-empty.svg create mode 100644 frontend/src/app/spot/icon-font/src/star-filled.svg create mode 100644 frontend/src/app/spot/icon-font/src/stop.svg create mode 100644 frontend/src/app/spot/icon-font/src/sum-error.svg create mode 100644 frontend/src/app/spot/icon-font/src/sum-sign.svg create mode 100644 frontend/src/app/spot/icon-font/src/today-arrows.svg create mode 100644 frontend/src/app/spot/icon-font/src/two-factor-authentification.svg create mode 100644 frontend/src/app/spot/icon-font/src/up-down-stepper.svg create mode 100644 frontend/src/app/spot/icon-font/src/user-missing.svg diff --git a/frontend/src/app/spot/icon-font/src/arrow-thin-left.svg b/frontend/src/app/spot/icon-font/src/arrow-thin-left.svg new file mode 100644 index 000000000000..a54ec09c91d1 --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/arrow-thin-left.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/app/spot/icon-font/src/baseline-add.svg b/frontend/src/app/spot/icon-font/src/baseline-add.svg new file mode 100644 index 000000000000..87bf2c6f34ed --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/baseline-add.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/src/app/spot/icon-font/src/baseline-delete.svg b/frontend/src/app/spot/icon-font/src/baseline-delete.svg new file mode 100644 index 000000000000..1044dea6ab27 --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/baseline-delete.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/src/app/spot/icon-font/src/blocked.svg b/frontend/src/app/spot/icon-font/src/blocked.svg new file mode 100644 index 000000000000..2cf2759243ef --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/blocked.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/app/spot/icon-font/src/bookmark-filled.svg b/frontend/src/app/spot/icon-font/src/bookmark-filled.svg new file mode 100644 index 000000000000..676e0b096dab --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/bookmark-filled.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/app/spot/icon-font/src/bookmark.svg b/frontend/src/app/spot/icon-font/src/bookmark.svg new file mode 100644 index 000000000000..f604a8487e5b --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/bookmark.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/app/spot/icon-font/src/comments.svg b/frontend/src/app/spot/icon-font/src/comments.svg new file mode 100644 index 000000000000..2e79c91e4606 --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/comments.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/app/spot/icon-font/src/configure-knobs.svg b/frontend/src/app/spot/icon-font/src/configure-knobs.svg new file mode 100644 index 000000000000..79345d86065c --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/configure-knobs.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/src/app/spot/icon-font/src/copy-documents.svg b/frontend/src/app/spot/icon-font/src/copy-documents.svg new file mode 100644 index 000000000000..daeb72e53212 --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/copy-documents.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/src/app/spot/icon-font/src/enterprise-badge.svg b/frontend/src/app/spot/icon-font/src/enterprise-badge.svg new file mode 100644 index 000000000000..fcf714ed09fb --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/enterprise-badge.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/src/app/spot/icon-font/src/export-pdf-1.svg b/frontend/src/app/spot/icon-font/src/export-pdf-1.svg new file mode 100644 index 000000000000..ef70df401092 --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/export-pdf-1.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/frontend/src/app/spot/icon-font/src/file-storage-connection.svg b/frontend/src/app/spot/icon-font/src/file-storage-connection.svg new file mode 100644 index 000000000000..c59cce4baf8b --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/file-storage-connection.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/frontend/src/app/spot/icon-font/src/github_logo.svg b/frontend/src/app/spot/icon-font/src/github_logo.svg new file mode 100644 index 000000000000..ecdf31e23185 --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/github_logo.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/app/spot/icon-font/src/gitlab_logo.svg b/frontend/src/app/spot/icon-font/src/gitlab_logo.svg new file mode 100644 index 000000000000..47ac9da36af5 --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/gitlab_logo.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/frontend/src/app/spot/icon-font/src/hide.svg b/frontend/src/app/spot/icon-font/src/hide.svg new file mode 100644 index 000000000000..c8e1911af160 --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/hide.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/src/app/spot/icon-font/src/iconfont-scaler.svg b/frontend/src/app/spot/icon-font/src/iconfont-scaler.svg new file mode 100644 index 000000000000..beb049be4d18 --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/iconfont-scaler.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/app/spot/icon-font/src/like-hand.svg b/frontend/src/app/spot/icon-font/src/like-hand.svg new file mode 100644 index 000000000000..d487a1907c92 --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/like-hand.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/app/spot/icon-font/src/mention-comment.svg b/frontend/src/app/spot/icon-font/src/mention-comment.svg new file mode 100644 index 000000000000..5de0c6e0729c --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/mention-comment.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/src/app/spot/icon-font/src/not-watching.svg b/frontend/src/app/spot/icon-font/src/not-watching.svg new file mode 100644 index 000000000000..22382d95890b --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/not-watching.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/app/spot/icon-font/src/remove-1.svg b/frontend/src/app/spot/icon-font/src/remove-1.svg new file mode 100644 index 000000000000..646e900b30ea --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/remove-1.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/app/spot/icon-font/src/return-to-previous.svg b/frontend/src/app/spot/icon-font/src/return-to-previous.svg new file mode 100644 index 000000000000..2ba6833cc606 --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/return-to-previous.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/app/spot/icon-font/src/settings-display.svg b/frontend/src/app/spot/icon-font/src/settings-display.svg new file mode 100644 index 000000000000..ecdbb6350228 --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/settings-display.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/app/spot/icon-font/src/snooze.svg b/frontend/src/app/spot/icon-font/src/snooze.svg new file mode 100644 index 000000000000..9ea5a430f70e --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/snooze.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/app/spot/icon-font/src/star-empty.svg b/frontend/src/app/spot/icon-font/src/star-empty.svg new file mode 100644 index 000000000000..ef3e8fd6bd34 --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/star-empty.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/app/spot/icon-font/src/star-filled.svg b/frontend/src/app/spot/icon-font/src/star-filled.svg new file mode 100644 index 000000000000..b1e6dd3afc91 --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/star-filled.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/app/spot/icon-font/src/stop.svg b/frontend/src/app/spot/icon-font/src/stop.svg new file mode 100644 index 000000000000..d03a815be5f0 --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/stop.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/app/spot/icon-font/src/sum-error.svg b/frontend/src/app/spot/icon-font/src/sum-error.svg new file mode 100644 index 000000000000..a3ae94aecb4e --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/sum-error.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/src/app/spot/icon-font/src/sum-sign.svg b/frontend/src/app/spot/icon-font/src/sum-sign.svg new file mode 100644 index 000000000000..581b94bc9da4 --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/sum-sign.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/app/spot/icon-font/src/today-arrows.svg b/frontend/src/app/spot/icon-font/src/today-arrows.svg new file mode 100644 index 000000000000..3fd50088bd00 --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/today-arrows.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/src/app/spot/icon-font/src/two-factor-authentification.svg b/frontend/src/app/spot/icon-font/src/two-factor-authentification.svg new file mode 100644 index 000000000000..ea4ec94e09ba --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/two-factor-authentification.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/src/app/spot/icon-font/src/up-down-stepper.svg b/frontend/src/app/spot/icon-font/src/up-down-stepper.svg new file mode 100644 index 000000000000..8403457f99fc --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/up-down-stepper.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/app/spot/icon-font/src/user-missing.svg b/frontend/src/app/spot/icon-font/src/user-missing.svg new file mode 100644 index 000000000000..8f595d6e4f64 --- /dev/null +++ b/frontend/src/app/spot/icon-font/src/user-missing.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/src/app/spot/styles/sass/common/icon.sass b/frontend/src/app/spot/styles/sass/common/icon.sass index 7a6f9bbd1b6f..c8e3bc5af048 100644 --- a/frontend/src/app/spot/styles/sass/common/icon.sass +++ b/frontend/src/app/spot/styles/sass/common/icon.sass @@ -28,1151 +28,1151 @@ -moz-osx-font-smoothing: grayscale -@mixin spot-icon-accessibility +@mixin spot-icon-zoom-out content: "\f101" -.spot-icon_accessibility:before +.spot-icon_zoom-out:before content: "\f101" -@mixin spot-icon-accountable +@mixin spot-icon-zoom-in content: "\f102" -.spot-icon_accountable:before +.spot-icon_zoom-in:before content: "\f102" -@mixin spot-icon-activity-history +@mixin spot-icon-zoom-auto content: "\f103" -.spot-icon_activity-history:before +.spot-icon_zoom-auto:before content: "\f103" -@mixin spot-icon-add-attachment +@mixin spot-icon-zen-mode content: "\f104" -.spot-icon_add-attachment:before +.spot-icon_zen-mode:before content: "\f104" -@mixin spot-icon-add-link +@mixin spot-icon-yes content: "\f105" -.spot-icon_add-link:before +.spot-icon_yes:before content: "\f105" -@mixin spot-icon-add +@mixin spot-icon-workflow content: "\f106" -.spot-icon_add:before +.spot-icon_workflow:before content: "\f106" -@mixin spot-icon-align-center +@mixin spot-icon-work-packages content: "\f107" -.spot-icon_align-center:before +.spot-icon_work-packages:before content: "\f107" -@mixin spot-icon-align-justify +@mixin spot-icon-wiki2 content: "\f108" -.spot-icon_align-justify:before +.spot-icon_wiki2:before content: "\f108" -@mixin spot-icon-align-left +@mixin spot-icon-wiki content: "\f109" -.spot-icon_align-left:before +.spot-icon_wiki:before content: "\f109" -@mixin spot-icon-align-right +@mixin spot-icon-wiki-edit content: "\f10a" -.spot-icon_align-right:before +.spot-icon_wiki-edit:before content: "\f10a" -@mixin spot-icon-arrow-down1 +@mixin spot-icon-watching content: "\f10b" -.spot-icon_arrow-down1:before +.spot-icon_watching:before content: "\f10b" -@mixin spot-icon-arrow-down2 +@mixin spot-icon-watched content: "\f10c" -.spot-icon_arrow-down2:before +.spot-icon_watched:before content: "\f10c" -@mixin spot-icon-arrow-in +@mixin spot-icon-warning content: "\f10d" -.spot-icon_arrow-in:before +.spot-icon_warning:before content: "\f10d" -@mixin spot-icon-arrow-left-right +@mixin spot-icon-view-timeline content: "\f10e" -.spot-icon_arrow-left-right:before +.spot-icon_view-timeline:before content: "\f10e" -@mixin spot-icon-arrow-left1 +@mixin spot-icon-view-split2 content: "\f10f" -.spot-icon_arrow-left1:before +.spot-icon_view-split2:before content: "\f10f" -@mixin spot-icon-arrow-left2 +@mixin spot-icon-view-split content: "\f110" -.spot-icon_arrow-left2:before +.spot-icon_view-split:before content: "\f110" -@mixin spot-icon-arrow-left3 +@mixin spot-icon-view-split-viewer-table content: "\f111" -.spot-icon_arrow-left3:before +.spot-icon_view-split-viewer-table:before content: "\f111" -@mixin spot-icon-arrow-left4 +@mixin spot-icon-view-model content: "\f112" -.spot-icon_arrow-left4:before +.spot-icon_view-model:before content: "\f112" -@mixin spot-icon-arrow-out +@mixin spot-icon-view-list content: "\f113" -.spot-icon_arrow-out:before +.spot-icon_view-list:before content: "\f113" -@mixin spot-icon-arrow-right2 +@mixin spot-icon-view-fullscreen content: "\f114" -.spot-icon_arrow-right2:before +.spot-icon_view-fullscreen:before content: "\f114" -@mixin spot-icon-arrow-right3 +@mixin spot-icon-view-card content: "\f115" -.spot-icon_arrow-right3:before +.spot-icon_view-card:before content: "\f115" -@mixin spot-icon-arrow-right4 +@mixin spot-icon-user content: "\f116" -.spot-icon_arrow-right4:before +.spot-icon_user:before content: "\f116" -@mixin spot-icon-arrow-right5 +@mixin spot-icon-user-plus content: "\f117" -.spot-icon_arrow-right5:before +.spot-icon_user-plus:before content: "\f117" -@mixin spot-icon-arrow-right6 +@mixin spot-icon-user-missing content: "\f118" -.spot-icon_arrow-right6:before +.spot-icon_user-missing:before content: "\f118" -@mixin spot-icon-arrow-right7 +@mixin spot-icon-user-minus content: "\f119" -.spot-icon_arrow-right7:before +.spot-icon_user-minus:before content: "\f119" -@mixin spot-icon-arrow-thin-left +@mixin spot-icon-upload content: "\f11a" -.spot-icon_arrow-thin-left:before +.spot-icon_upload:before content: "\f11a" -@mixin spot-icon-arrow-thin +@mixin spot-icon-upload-arrow content: "\f11b" -.spot-icon_arrow-thin:before +.spot-icon_upload-arrow:before content: "\f11b" -@mixin spot-icon-arrow-up1 +@mixin spot-icon-up-down-stepper content: "\f11c" -.spot-icon_arrow-up1:before +.spot-icon_up-down-stepper:before content: "\f11c" -@mixin spot-icon-arrow-up2 +@mixin spot-icon-unwatched content: "\f11d" -.spot-icon_arrow-up2:before +.spot-icon_unwatched:before content: "\f11d" -@mixin spot-icon-assigned-to-me +@mixin spot-icon-unordered-list content: "\f11e" -.spot-icon_assigned-to-me:before +.spot-icon_unordered-list:before content: "\f11e" -@mixin spot-icon-assigned +@mixin spot-icon-unlocked content: "\f11f" -.spot-icon_assigned:before +.spot-icon_unlocked:before content: "\f11f" -@mixin spot-icon-attachment +@mixin spot-icon-unit content: "\f120" -.spot-icon_attachment:before +.spot-icon_unit:before content: "\f120" -@mixin spot-icon-attention +@mixin spot-icon-undo content: "\f121" -.spot-icon_attention:before +.spot-icon_undo:before content: "\f121" -@mixin spot-icon-back-up +@mixin spot-icon-underline content: "\f122" -.spot-icon_back-up:before +.spot-icon_underline:before content: "\f122" -@mixin spot-icon-backlogs +@mixin spot-icon-types content: "\f123" -.spot-icon_backlogs:before +.spot-icon_types:before content: "\f123" -@mixin spot-icon-baseline-add +@mixin spot-icon-two-factor-authentification content: "\f124" -.spot-icon_baseline-add:before +.spot-icon_two-factor-authentification:before content: "\f124" -@mixin spot-icon-baseline-delete +@mixin spot-icon-two-factor-authentication content: "\f125" -.spot-icon_baseline-delete:before +.spot-icon_two-factor-authentication:before content: "\f125" -@mixin spot-icon-baseline +@mixin spot-icon-training-consulting content: "\f126" -.spot-icon_baseline:before +.spot-icon_training-consulting:before content: "\f126" -@mixin spot-icon-bcf +@mixin spot-icon-today-arrows content: "\f127" -.spot-icon_bcf:before +.spot-icon_today-arrows:before content: "\f127" -@mixin spot-icon-bell +@mixin spot-icon-to-fullscreen content: "\f128" -.spot-icon_bell:before +.spot-icon_to-fullscreen:before content: "\f128" -@mixin spot-icon-billing-information +@mixin spot-icon-time content: "\f129" -.spot-icon_billing-information:before +.spot-icon_time:before content: "\f129" -@mixin spot-icon-blocked +@mixin spot-icon-time-tracking-stop content: "\f12a" -.spot-icon_blocked:before +.spot-icon_time-tracking-stop:before content: "\f12a" -@mixin spot-icon-boards +@mixin spot-icon-time-tracking-start content: "\f12b" -.spot-icon_boards:before +.spot-icon_time-tracking-start:before content: "\f12b" -@mixin spot-icon-bold +@mixin spot-icon-time-tracking-running content: "\f12c" -.spot-icon_bold:before +.spot-icon_time-tracking-running:before content: "\f12c" -@mixin spot-icon-bookmark-filled +@mixin spot-icon-ticket content: "\f12d" -.spot-icon_bookmark-filled:before +.spot-icon_ticket:before content: "\f12d" -@mixin spot-icon-bookmark +@mixin spot-icon-ticket-note content: "\f12e" -.spot-icon_bookmark:before +.spot-icon_ticket-note:before content: "\f12e" -@mixin spot-icon-budget +@mixin spot-icon-ticket-minus content: "\f12f" -.spot-icon_budget:before +.spot-icon_ticket-minus:before content: "\f12f" -@mixin spot-icon-bug +@mixin spot-icon-ticket-edit content: "\f130" -.spot-icon_bug:before +.spot-icon_ticket-edit:before content: "\f130" -@mixin spot-icon-calendar +@mixin spot-icon-ticket-down content: "\f131" -.spot-icon_calendar:before +.spot-icon_ticket-down:before content: "\f131" -@mixin spot-icon-calendar2 +@mixin spot-icon-ticket-checked content: "\f132" -.spot-icon_calendar2:before +.spot-icon_ticket-checked:before content: "\f132" -@mixin spot-icon-camera +@mixin spot-icon-text content: "\f133" -.spot-icon_camera:before +.spot-icon_text:before content: "\f133" -@mixin spot-icon-cancel-circle +@mixin spot-icon-team-planner content: "\f134" -.spot-icon_cancel-circle:before +.spot-icon_team-planner:before content: "\f134" -@mixin spot-icon-cancel +@mixin spot-icon-sum-sign content: "\f135" -.spot-icon_cancel:before +.spot-icon_sum-sign:before content: "\f135" -@mixin spot-icon-cart +@mixin spot-icon-sum-error content: "\f136" -.spot-icon_cart:before +.spot-icon_sum-error:before content: "\f136" -@mixin spot-icon-changeset-down +@mixin spot-icon-strike-through content: "\f137" -.spot-icon_changeset-down:before +.spot-icon_strike-through:before content: "\f137" -@mixin spot-icon-changeset-up +@mixin spot-icon-stop content: "\f138" -.spot-icon_changeset-up:before +.spot-icon_stop:before content: "\f138" -@mixin spot-icon-changeset +@mixin spot-icon-status content: "\f139" -.spot-icon_changeset:before +.spot-icon_status:before content: "\f139" -@mixin spot-icon-chart1 +@mixin spot-icon-status-reporting content: "\f13a" -.spot-icon_chart1:before +.spot-icon_status-reporting:before content: "\f13a" -@mixin spot-icon-chart2 +@mixin spot-icon-star content: "\f13b" -.spot-icon_chart2:before +.spot-icon_star:before content: "\f13b" -@mixin spot-icon-chart3 +@mixin spot-icon-star-filled content: "\f13c" -.spot-icon_chart3:before +.spot-icon_star-filled:before content: "\f13c" -@mixin spot-icon-checkmark-circle +@mixin spot-icon-star-empty content: "\f13d" -.spot-icon_checkmark-circle:before +.spot-icon_star-empty:before content: "\f13d" -@mixin spot-icon-checkmark +@mixin spot-icon-square content: "\f13e" -.spot-icon_checkmark:before +.spot-icon_square:before content: "\f13e" -@mixin spot-icon-clipboard +@mixin spot-icon-sort-up content: "\f13f" -.spot-icon_clipboard:before +.spot-icon_sort-up:before content: "\f13f" -@mixin spot-icon-close +@mixin spot-icon-sort-down content: "\f140" -.spot-icon_close:before +.spot-icon_sort-down:before content: "\f140" -@mixin spot-icon-code-tag +@mixin spot-icon-sort-descending content: "\f141" -.spot-icon_code-tag:before +.spot-icon_sort-descending:before content: "\f141" -@mixin spot-icon-color-text +@mixin spot-icon-sort-by content: "\f142" -.spot-icon_color-text:before +.spot-icon_sort-by:before content: "\f142" -@mixin spot-icon-color-underline +@mixin spot-icon-sort-ascending content: "\f143" -.spot-icon_color-underline:before +.spot-icon_sort-ascending:before content: "\f143" -@mixin spot-icon-column-left +@mixin spot-icon-snooze content: "\f144" -.spot-icon_column-left:before +.spot-icon_snooze:before content: "\f144" -@mixin spot-icon-column-right +@mixin spot-icon-slack content: "\f145" -.spot-icon_column-right:before +.spot-icon_slack:before content: "\f145" -@mixin spot-icon-columns +@mixin spot-icon-show-more content: "\f146" -.spot-icon_columns:before +.spot-icon_show-more:before content: "\f146" -@mixin spot-icon-comments +@mixin spot-icon-show-more-horizontal content: "\f147" -.spot-icon_comments:before +.spot-icon_show-more-horizontal:before content: "\f147" -@mixin spot-icon-compare2 +@mixin spot-icon-show-all-projects content: "\f148" -.spot-icon_compare2:before +.spot-icon_show-all-projects:before content: "\f148" -@mixin spot-icon-concept +@mixin spot-icon-shortcuts content: "\f149" -.spot-icon_concept:before +.spot-icon_shortcuts:before content: "\f149" -@mixin spot-icon-configure-knobs +@mixin spot-icon-share content: "\f14a" -.spot-icon_configure-knobs:before +.spot-icon_share:before content: "\f14a" -@mixin spot-icon-console-light +@mixin spot-icon-settings4 content: "\f14b" -.spot-icon_console-light:before +.spot-icon_settings4:before content: "\f14b" -@mixin spot-icon-console +@mixin spot-icon-settings3 content: "\f14c" -.spot-icon_console:before +.spot-icon_settings3:before content: "\f14c" -@mixin spot-icon-contacts +@mixin spot-icon-settings2 content: "\f14d" -.spot-icon_contacts:before +.spot-icon_settings2:before content: "\f14d" -@mixin spot-icon-copy-documents +@mixin spot-icon-settings content: "\f14e" -.spot-icon_copy-documents:before +.spot-icon_settings:before content: "\f14e" -@mixin spot-icon-copy +@mixin spot-icon-settings-display content: "\f14f" -.spot-icon_copy:before +.spot-icon_settings-display:before content: "\f14f" -@mixin spot-icon-cost-reports +@mixin spot-icon-server-key content: "\f150" -.spot-icon_cost-reports:before +.spot-icon_server-key:before content: "\f150" -@mixin spot-icon-cost-types +@mixin spot-icon-send-mail content: "\f151" -.spot-icon_cost-types:before +.spot-icon_send-mail:before content: "\f151" -@mixin spot-icon-cursor +@mixin spot-icon-select-all content: "\f152" -.spot-icon_cursor:before +.spot-icon_select-all:before content: "\f152" -@mixin spot-icon-custom-development +@mixin spot-icon-search content: "\f153" -.spot-icon_custom-development:before +.spot-icon_search:before content: "\f153" -@mixin spot-icon-custom-fields +@mixin spot-icon-save content: "\f154" -.spot-icon_custom-fields:before +.spot-icon_save:before content: "\f154" -@mixin spot-icon-cut +@mixin spot-icon-rubber content: "\f155" -.spot-icon_cut:before +.spot-icon_rubber:before content: "\f155" -@mixin spot-icon-date-alerts +@mixin spot-icon-rss content: "\f156" -.spot-icon_date-alerts:before +.spot-icon_rss:before content: "\f156" -@mixin spot-icon-delete-folder +@mixin spot-icon-roadmap content: "\f157" -.spot-icon_delete-folder:before +.spot-icon_roadmap:before content: "\f157" -@mixin spot-icon-delete +@mixin spot-icon-return-to-previous content: "\f158" -.spot-icon_delete:before +.spot-icon_return-to-previous:before content: "\f158" -@mixin spot-icon-delta-triangle +@mixin spot-icon-resizer-vertical-lines content: "\f159" -.spot-icon_delta-triangle:before +.spot-icon_resizer-vertical-lines:before content: "\f159" -@mixin spot-icon-dependency +@mixin spot-icon-resizer-bottom-right content: "\f15a" -.spot-icon_dependency:before +.spot-icon_resizer-bottom-right:before content: "\f15a" -@mixin spot-icon-design +@mixin spot-icon-reported-by-me content: "\f15b" -.spot-icon_design:before +.spot-icon_reported-by-me:before content: "\f15b" -@mixin spot-icon-double-arrow-left +@mixin spot-icon-rename content: "\f15c" -.spot-icon_double-arrow-left:before +.spot-icon_rename:before content: "\f15c" -@mixin spot-icon-double-arrow-right +@mixin spot-icon-remove content: "\f15d" -.spot-icon_double-arrow-right:before +.spot-icon_remove:before content: "\f15d" -@mixin spot-icon-download-arrow +@mixin spot-icon-remove-link content: "\f15e" -.spot-icon_download-arrow:before +.spot-icon_remove-link:before content: "\f15e" -@mixin spot-icon-download +@mixin spot-icon-remove-1 content: "\f15f" -.spot-icon_download:before +.spot-icon_remove-1:before content: "\f15f" -@mixin spot-icon-drag-handle +@mixin spot-icon-reminder content: "\f160" -.spot-icon_drag-handle:before +.spot-icon_reminder:before content: "\f160" -@mixin spot-icon-dropdown-open +@mixin spot-icon-reload content: "\f161" -.spot-icon_dropdown-open:before +.spot-icon_reload:before content: "\f161" -@mixin spot-icon-dropdown +@mixin spot-icon-relations content: "\f162" -.spot-icon_dropdown:before +.spot-icon_relations:before content: "\f162" -@mixin spot-icon-duplicate +@mixin spot-icon-relation-precedes content: "\f163" -.spot-icon_duplicate:before +.spot-icon_relation-precedes:before content: "\f163" -@mixin spot-icon-edit +@mixin spot-icon-relation-new-child content: "\f164" -.spot-icon_edit:before +.spot-icon_relation-new-child:before content: "\f164" -@mixin spot-icon-email-alert +@mixin spot-icon-relation-follows content: "\f165" -.spot-icon_email-alert:before +.spot-icon_relation-follows:before content: "\f165" -@mixin spot-icon-enterprise-addons +@mixin spot-icon-redo content: "\f166" -.spot-icon_enterprise-addons:before +.spot-icon_redo:before content: "\f166" -@mixin spot-icon-enterprise-badge +@mixin spot-icon-quote2 content: "\f167" -.spot-icon_enterprise-badge:before +.spot-icon_quote2:before content: "\f167" -@mixin spot-icon-enterprise +@mixin spot-icon-quote content: "\f168" -.spot-icon_enterprise:before +.spot-icon_quote:before content: "\f168" -@mixin spot-icon-enumerations +@mixin spot-icon-pulldown content: "\f169" -.spot-icon_enumerations:before +.spot-icon_pulldown:before content: "\f169" -@mixin spot-icon-error +@mixin spot-icon-pulldown-up content: "\f16a" -.spot-icon_error:before +.spot-icon_pulldown-up:before content: "\f16a" -@mixin spot-icon-export-atom +@mixin spot-icon-publish content: "\f16b" -.spot-icon_export-atom:before +.spot-icon_publish:before content: "\f16b" -@mixin spot-icon-export-bcf +@mixin spot-icon-projects content: "\f16c" -.spot-icon_export-bcf:before +.spot-icon_projects:before content: "\f16c" -@mixin spot-icon-export-csv +@mixin spot-icon-project-types content: "\f16d" -.spot-icon_export-csv:before +.spot-icon_project-types:before content: "\f16d" -@mixin spot-icon-export-pdf-1 +@mixin spot-icon-priority content: "\f16e" -.spot-icon_export-pdf-1:before +.spot-icon_priority:before content: "\f16e" -@mixin spot-icon-export-pdf-descr +@mixin spot-icon-print content: "\f16f" -.spot-icon_export-pdf-descr:before +.spot-icon_print:before content: "\f16f" -@mixin spot-icon-export-pdf-with-descriptions +@mixin spot-icon-preview content: "\f170" -.spot-icon_export-pdf-with-descriptions:before +.spot-icon_preview:before content: "\f170" -@mixin spot-icon-export-pdf +@mixin spot-icon-presentation content: "\f171" -.spot-icon_export-pdf:before +.spot-icon_presentation:before content: "\f171" -@mixin spot-icon-export-xls-descr +@mixin spot-icon-pre content: "\f172" -.spot-icon_export-xls-descr:before +.spot-icon_pre:before content: "\f172" -@mixin spot-icon-export-xls-with-descriptions +@mixin spot-icon-plus content: "\f173" -.spot-icon_export-xls-with-descriptions:before +.spot-icon_plus:before content: "\f173" -@mixin spot-icon-export-xls-with-relations +@mixin spot-icon-plugins content: "\f174" -.spot-icon_export-xls-with-relations:before +.spot-icon_plugins:before content: "\f174" -@mixin spot-icon-export-xls +@mixin spot-icon-play content: "\f175" -.spot-icon_export-xls:before +.spot-icon_play:before content: "\f175" -@mixin spot-icon-export +@mixin spot-icon-pin content: "\f176" -.spot-icon_export:before +.spot-icon_pin:before content: "\f176" -@mixin spot-icon-external-link +@mixin spot-icon-phone content: "\f177" -.spot-icon_external-link:before +.spot-icon_phone:before content: "\f177" -@mixin spot-icon-faq +@mixin spot-icon-payment-history content: "\f178" -.spot-icon_faq:before +.spot-icon_payment-history:before content: "\f178" -@mixin spot-icon-file-doc +@mixin spot-icon-paragraph content: "\f179" -.spot-icon_file-doc:before +.spot-icon_paragraph:before content: "\f179" -@mixin spot-icon-file-form +@mixin spot-icon-paragraph-right content: "\f17a" -.spot-icon_file-form:before +.spot-icon_paragraph-right:before content: "\f17a" -@mixin spot-icon-file-presentation +@mixin spot-icon-paragraph-left content: "\f17b" -.spot-icon_file-presentation:before +.spot-icon_paragraph-left:before content: "\f17b" -@mixin spot-icon-file-sheet +@mixin spot-icon-outline content: "\f17c" -.spot-icon_file-sheet:before +.spot-icon_outline:before content: "\f17c" -@mixin spot-icon-file-storage-connection +@mixin spot-icon-ordered-list content: "\f17d" -.spot-icon_file-storage-connection:before +.spot-icon_ordered-list:before content: "\f17d" -@mixin spot-icon-file-text +@mixin spot-icon-openproject content: "\f17e" -.spot-icon_file-text:before +.spot-icon_openproject:before content: "\f17e" -@mixin spot-icon-filter +@mixin spot-icon-openid content: "\f17f" -.spot-icon_filter:before +.spot-icon_openid:before content: "\f17f" -@mixin spot-icon-flag +@mixin spot-icon-notes content: "\f180" -.spot-icon_flag:before +.spot-icon_notes:before content: "\f180" -@mixin spot-icon-folder-add +@mixin spot-icon-not-watching content: "\f181" -.spot-icon_folder-add:before +.spot-icon_not-watching:before content: "\f181" -@mixin spot-icon-folder-locked +@mixin spot-icon-not-supported content: "\f182" -.spot-icon_folder-locked:before +.spot-icon_not-supported:before content: "\f182" -@mixin spot-icon-folder-open +@mixin spot-icon-no-zen-mode content: "\f183" -.spot-icon_folder-open:before +.spot-icon_no-zen-mode:before content: "\f183" -@mixin spot-icon-folder-remove +@mixin spot-icon-no-hierarchy content: "\f184" -.spot-icon_folder-remove:before +.spot-icon_no-hierarchy:before content: "\f184" -@mixin spot-icon-folder +@mixin spot-icon-nextcloud content: "\f185" -.spot-icon_folder:before +.spot-icon_nextcloud:before content: "\f185" -@mixin spot-icon-forums +@mixin spot-icon-nextcloud-circle content: "\f186" -.spot-icon_forums:before +.spot-icon_nextcloud-circle:before content: "\f186" -@mixin spot-icon-from-fullscreen +@mixin spot-icon-news content: "\f187" -.spot-icon_from-fullscreen:before +.spot-icon_news:before content: "\f187" -@mixin spot-icon-getting-started +@mixin spot-icon-new-planning-element content: "\f188" -.spot-icon_getting-started:before +.spot-icon_new-planning-element:before content: "\f188" -@mixin spot-icon-github_logo +@mixin spot-icon-music content: "\f189" -.spot-icon_github_logo:before +.spot-icon_music:before content: "\f189" -@mixin spot-icon-gitlab_logo +@mixin spot-icon-movie content: "\f18a" -.spot-icon_gitlab_logo:before +.spot-icon_movie:before content: "\f18a" -@mixin spot-icon-glossar +@mixin spot-icon-move content: "\f18b" -.spot-icon_glossar:before +.spot-icon_move:before content: "\f18b" -@mixin spot-icon-google-plus +@mixin spot-icon-more content: "\f18c" -.spot-icon_google-plus:before +.spot-icon_more:before content: "\f18c" -@mixin spot-icon-group-by +@mixin spot-icon-modules content: "\f18d" -.spot-icon_group-by:before +.spot-icon_modules:before content: "\f18d" -@mixin spot-icon-group +@mixin spot-icon-mobile content: "\f18e" -.spot-icon_group:before +.spot-icon_mobile:before content: "\f18e" -@mixin spot-icon-hamburger +@mixin spot-icon-minus2 content: "\f18f" -.spot-icon_hamburger:before +.spot-icon_minus2:before content: "\f18f" -@mixin spot-icon-headline1 +@mixin spot-icon-minus1 content: "\f190" -.spot-icon_headline1:before +.spot-icon_minus1:before content: "\f190" -@mixin spot-icon-headline2 +@mixin spot-icon-milestone content: "\f191" -.spot-icon_headline2:before +.spot-icon_milestone:before content: "\f191" -@mixin spot-icon-headline3 +@mixin spot-icon-microphone content: "\f192" -.spot-icon_headline3:before +.spot-icon_microphone:before content: "\f192" -@mixin spot-icon-headset +@mixin spot-icon-merge-branch content: "\f193" -.spot-icon_headset:before +.spot-icon_merge-branch:before content: "\f193" -@mixin spot-icon-help +@mixin spot-icon-menu content: "\f194" -.spot-icon_help:before +.spot-icon_menu:before content: "\f194" -@mixin spot-icon-help1 +@mixin spot-icon-mention content: "\f195" -.spot-icon_help1:before +.spot-icon_mention:before content: "\f195" -@mixin spot-icon-help2 +@mixin spot-icon-mention-comment content: "\f196" -.spot-icon_help2:before +.spot-icon_mention-comment:before content: "\f196" -@mixin spot-icon-hide +@mixin spot-icon-meetings content: "\f197" -.spot-icon_hide:before +.spot-icon_meetings:before content: "\f197" -@mixin spot-icon-hierarchy +@mixin spot-icon-mark-read content: "\f198" -.spot-icon_hierarchy:before +.spot-icon_mark-read:before content: "\f198" -@mixin spot-icon-home +@mixin spot-icon-mark-all-read content: "\f199" -.spot-icon_home:before +.spot-icon_mark-all-read:before content: "\f199" -@mixin spot-icon-hosting +@mixin spot-icon-maintenance-support content: "\f19a" -.spot-icon_hosting:before +.spot-icon_maintenance-support:before content: "\f19a" -@mixin spot-icon-iconfont-scaler +@mixin spot-icon-mail2 content: "\f19b" -.spot-icon_iconfont-scaler:before +.spot-icon_mail2:before content: "\f19b" -@mixin spot-icon-ifc +@mixin spot-icon-mail1 content: "\f19c" -.spot-icon_ifc:before +.spot-icon_mail1:before content: "\f19c" -@mixin spot-icon-image1 +@mixin spot-icon-logout content: "\f19d" -.spot-icon_image1:before +.spot-icon_logout:before content: "\f19d" -@mixin spot-icon-image2 +@mixin spot-icon-locked content: "\f19e" -.spot-icon_image2:before +.spot-icon_locked:before content: "\f19e" -@mixin spot-icon-import +@mixin spot-icon-location content: "\f19f" -.spot-icon_import:before +.spot-icon_location:before content: "\f19f" -@mixin spot-icon-inbox +@mixin spot-icon-loading2 content: "\f1a0" -.spot-icon_inbox:before +.spot-icon_loading2:before content: "\f1a0" -@mixin spot-icon-info1 +@mixin spot-icon-loading1 content: "\f1a1" -.spot-icon_info1:before +.spot-icon_loading1:before content: "\f1a1" -@mixin spot-icon-info2 +@mixin spot-icon-link content: "\f1a2" -.spot-icon_info2:before +.spot-icon_link:before content: "\f1a2" -@mixin spot-icon-input-disabled +@mixin spot-icon-like-hand content: "\f1a3" -.spot-icon_input-disabled:before +.spot-icon_like-hand:before content: "\f1a3" -@mixin spot-icon-installation-services +@mixin spot-icon-key content: "\f1a4" -.spot-icon_installation-services:before +.spot-icon_key:before content: "\f1a4" @@ -1183,1150 +1183,1150 @@ content: "\f1a5" -@mixin spot-icon-key +@mixin spot-icon-installation-services content: "\f1a6" -.spot-icon_key:before +.spot-icon_installation-services:before content: "\f1a6" -@mixin spot-icon-like-hand +@mixin spot-icon-input-disabled content: "\f1a7" -.spot-icon_like-hand:before +.spot-icon_input-disabled:before content: "\f1a7" -@mixin spot-icon-link +@mixin spot-icon-info2 content: "\f1a8" -.spot-icon_link:before +.spot-icon_info2:before content: "\f1a8" -@mixin spot-icon-loading1 +@mixin spot-icon-info1 content: "\f1a9" -.spot-icon_loading1:before +.spot-icon_info1:before content: "\f1a9" -@mixin spot-icon-loading2 +@mixin spot-icon-inbox content: "\f1aa" -.spot-icon_loading2:before +.spot-icon_inbox:before content: "\f1aa" -@mixin spot-icon-location +@mixin spot-icon-import content: "\f1ab" -.spot-icon_location:before +.spot-icon_import:before content: "\f1ab" -@mixin spot-icon-locked +@mixin spot-icon-image2 content: "\f1ac" -.spot-icon_locked:before +.spot-icon_image2:before content: "\f1ac" -@mixin spot-icon-logout +@mixin spot-icon-image1 content: "\f1ad" -.spot-icon_logout:before +.spot-icon_image1:before content: "\f1ad" -@mixin spot-icon-mail1 +@mixin spot-icon-ifc content: "\f1ae" -.spot-icon_mail1:before +.spot-icon_ifc:before content: "\f1ae" -@mixin spot-icon-mail2 +@mixin spot-icon-iconfont-scaler content: "\f1af" -.spot-icon_mail2:before +.spot-icon_iconfont-scaler:before content: "\f1af" -@mixin spot-icon-maintenance-support +@mixin spot-icon-hosting content: "\f1b0" -.spot-icon_maintenance-support:before +.spot-icon_hosting:before content: "\f1b0" -@mixin spot-icon-mark-all-read +@mixin spot-icon-home content: "\f1b1" -.spot-icon_mark-all-read:before +.spot-icon_home:before content: "\f1b1" -@mixin spot-icon-mark-read +@mixin spot-icon-hierarchy content: "\f1b2" -.spot-icon_mark-read:before +.spot-icon_hierarchy:before content: "\f1b2" -@mixin spot-icon-meetings +@mixin spot-icon-hide content: "\f1b3" -.spot-icon_meetings:before +.spot-icon_hide:before content: "\f1b3" -@mixin spot-icon-mention-comment +@mixin spot-icon-help2 content: "\f1b4" -.spot-icon_mention-comment:before +.spot-icon_help2:before content: "\f1b4" -@mixin spot-icon-mention +@mixin spot-icon-help1 content: "\f1b5" -.spot-icon_mention:before +.spot-icon_help1:before content: "\f1b5" -@mixin spot-icon-menu +@mixin spot-icon-help content: "\f1b6" -.spot-icon_menu:before +.spot-icon_help:before content: "\f1b6" -@mixin spot-icon-merge-branch +@mixin spot-icon-headset content: "\f1b7" -.spot-icon_merge-branch:before +.spot-icon_headset:before content: "\f1b7" -@mixin spot-icon-microphone +@mixin spot-icon-headline3 content: "\f1b8" -.spot-icon_microphone:before +.spot-icon_headline3:before content: "\f1b8" -@mixin spot-icon-milestone +@mixin spot-icon-headline2 content: "\f1b9" -.spot-icon_milestone:before +.spot-icon_headline2:before content: "\f1b9" -@mixin spot-icon-minus1 +@mixin spot-icon-headline1 content: "\f1ba" -.spot-icon_minus1:before +.spot-icon_headline1:before content: "\f1ba" -@mixin spot-icon-minus2 +@mixin spot-icon-hamburger content: "\f1bb" -.spot-icon_minus2:before +.spot-icon_hamburger:before content: "\f1bb" -@mixin spot-icon-mobile +@mixin spot-icon-group content: "\f1bc" -.spot-icon_mobile:before +.spot-icon_group:before content: "\f1bc" -@mixin spot-icon-modules +@mixin spot-icon-group-by content: "\f1bd" -.spot-icon_modules:before +.spot-icon_group-by:before content: "\f1bd" -@mixin spot-icon-more +@mixin spot-icon-google-plus content: "\f1be" -.spot-icon_more:before +.spot-icon_google-plus:before content: "\f1be" -@mixin spot-icon-move +@mixin spot-icon-glossar content: "\f1bf" -.spot-icon_move:before +.spot-icon_glossar:before content: "\f1bf" -@mixin spot-icon-movie +@mixin spot-icon-gitlab_logo content: "\f1c0" -.spot-icon_movie:before +.spot-icon_gitlab_logo:before content: "\f1c0" -@mixin spot-icon-music +@mixin spot-icon-github_logo content: "\f1c1" -.spot-icon_music:before +.spot-icon_github_logo:before content: "\f1c1" -@mixin spot-icon-new-planning-element +@mixin spot-icon-getting-started content: "\f1c2" -.spot-icon_new-planning-element:before +.spot-icon_getting-started:before content: "\f1c2" -@mixin spot-icon-news +@mixin spot-icon-from-fullscreen content: "\f1c3" -.spot-icon_news:before +.spot-icon_from-fullscreen:before content: "\f1c3" -@mixin spot-icon-nextcloud-circle +@mixin spot-icon-forums content: "\f1c4" -.spot-icon_nextcloud-circle:before +.spot-icon_forums:before content: "\f1c4" -@mixin spot-icon-nextcloud +@mixin spot-icon-folder content: "\f1c5" -.spot-icon_nextcloud:before +.spot-icon_folder:before content: "\f1c5" -@mixin spot-icon-no-hierarchy +@mixin spot-icon-folder-remove content: "\f1c6" -.spot-icon_no-hierarchy:before +.spot-icon_folder-remove:before content: "\f1c6" -@mixin spot-icon-no-zen-mode +@mixin spot-icon-folder-open content: "\f1c7" -.spot-icon_no-zen-mode:before +.spot-icon_folder-open:before content: "\f1c7" -@mixin spot-icon-not-supported +@mixin spot-icon-folder-locked content: "\f1c8" -.spot-icon_not-supported:before +.spot-icon_folder-locked:before content: "\f1c8" -@mixin spot-icon-not-watching +@mixin spot-icon-folder-add content: "\f1c9" -.spot-icon_not-watching:before +.spot-icon_folder-add:before content: "\f1c9" -@mixin spot-icon-notes +@mixin spot-icon-flag content: "\f1ca" -.spot-icon_notes:before +.spot-icon_flag:before content: "\f1ca" -@mixin spot-icon-openid +@mixin spot-icon-filter content: "\f1cb" -.spot-icon_openid:before +.spot-icon_filter:before content: "\f1cb" -@mixin spot-icon-openproject +@mixin spot-icon-file-text content: "\f1cc" -.spot-icon_openproject:before +.spot-icon_file-text:before content: "\f1cc" -@mixin spot-icon-ordered-list +@mixin spot-icon-file-storage-connection content: "\f1cd" -.spot-icon_ordered-list:before +.spot-icon_file-storage-connection:before content: "\f1cd" -@mixin spot-icon-outline +@mixin spot-icon-file-sheet content: "\f1ce" -.spot-icon_outline:before +.spot-icon_file-sheet:before content: "\f1ce" -@mixin spot-icon-paragraph-left +@mixin spot-icon-file-presentation content: "\f1cf" -.spot-icon_paragraph-left:before +.spot-icon_file-presentation:before content: "\f1cf" -@mixin spot-icon-paragraph-right +@mixin spot-icon-file-form content: "\f1d0" -.spot-icon_paragraph-right:before +.spot-icon_file-form:before content: "\f1d0" -@mixin spot-icon-paragraph +@mixin spot-icon-file-doc content: "\f1d1" -.spot-icon_paragraph:before +.spot-icon_file-doc:before content: "\f1d1" -@mixin spot-icon-payment-history +@mixin spot-icon-faq content: "\f1d2" -.spot-icon_payment-history:before +.spot-icon_faq:before content: "\f1d2" -@mixin spot-icon-phone +@mixin spot-icon-external-link content: "\f1d3" -.spot-icon_phone:before +.spot-icon_external-link:before content: "\f1d3" -@mixin spot-icon-pin +@mixin spot-icon-export content: "\f1d4" -.spot-icon_pin:before +.spot-icon_export:before content: "\f1d4" -@mixin spot-icon-play +@mixin spot-icon-export-xls content: "\f1d5" -.spot-icon_play:before +.spot-icon_export-xls:before content: "\f1d5" -@mixin spot-icon-plugins +@mixin spot-icon-export-xls-with-relations content: "\f1d6" -.spot-icon_plugins:before +.spot-icon_export-xls-with-relations:before content: "\f1d6" -@mixin spot-icon-plus +@mixin spot-icon-export-xls-with-descriptions content: "\f1d7" -.spot-icon_plus:before +.spot-icon_export-xls-with-descriptions:before content: "\f1d7" -@mixin spot-icon-pre +@mixin spot-icon-export-xls-descr content: "\f1d8" -.spot-icon_pre:before +.spot-icon_export-xls-descr:before content: "\f1d8" -@mixin spot-icon-presentation +@mixin spot-icon-export-pdf content: "\f1d9" -.spot-icon_presentation:before +.spot-icon_export-pdf:before content: "\f1d9" -@mixin spot-icon-preview +@mixin spot-icon-export-pdf-with-descriptions content: "\f1da" -.spot-icon_preview:before +.spot-icon_export-pdf-with-descriptions:before content: "\f1da" -@mixin spot-icon-print +@mixin spot-icon-export-pdf-descr content: "\f1db" -.spot-icon_print:before +.spot-icon_export-pdf-descr:before content: "\f1db" -@mixin spot-icon-priority +@mixin spot-icon-export-pdf-1 content: "\f1dc" -.spot-icon_priority:before +.spot-icon_export-pdf-1:before content: "\f1dc" -@mixin spot-icon-project-types +@mixin spot-icon-export-csv content: "\f1dd" -.spot-icon_project-types:before +.spot-icon_export-csv:before content: "\f1dd" -@mixin spot-icon-projects +@mixin spot-icon-export-bcf content: "\f1de" -.spot-icon_projects:before +.spot-icon_export-bcf:before content: "\f1de" -@mixin spot-icon-publish +@mixin spot-icon-export-atom content: "\f1df" -.spot-icon_publish:before +.spot-icon_export-atom:before content: "\f1df" -@mixin spot-icon-pulldown-up +@mixin spot-icon-error content: "\f1e0" -.spot-icon_pulldown-up:before +.spot-icon_error:before content: "\f1e0" -@mixin spot-icon-pulldown +@mixin spot-icon-enumerations content: "\f1e1" -.spot-icon_pulldown:before +.spot-icon_enumerations:before content: "\f1e1" -@mixin spot-icon-quote +@mixin spot-icon-enterprise content: "\f1e2" -.spot-icon_quote:before +.spot-icon_enterprise:before content: "\f1e2" -@mixin spot-icon-quote2 +@mixin spot-icon-enterprise-badge content: "\f1e3" -.spot-icon_quote2:before +.spot-icon_enterprise-badge:before content: "\f1e3" -@mixin spot-icon-redo +@mixin spot-icon-enterprise-addons content: "\f1e4" -.spot-icon_redo:before +.spot-icon_enterprise-addons:before content: "\f1e4" -@mixin spot-icon-relation-follows +@mixin spot-icon-email-alert content: "\f1e5" -.spot-icon_relation-follows:before +.spot-icon_email-alert:before content: "\f1e5" -@mixin spot-icon-relation-new-child +@mixin spot-icon-edit content: "\f1e6" -.spot-icon_relation-new-child:before +.spot-icon_edit:before content: "\f1e6" -@mixin spot-icon-relation-precedes +@mixin spot-icon-duplicate content: "\f1e7" -.spot-icon_relation-precedes:before +.spot-icon_duplicate:before content: "\f1e7" -@mixin spot-icon-relations +@mixin spot-icon-dropdown content: "\f1e8" -.spot-icon_relations:before +.spot-icon_dropdown:before content: "\f1e8" -@mixin spot-icon-reload +@mixin spot-icon-dropdown-open content: "\f1e9" -.spot-icon_reload:before +.spot-icon_dropdown-open:before content: "\f1e9" -@mixin spot-icon-reminder +@mixin spot-icon-drag-handle content: "\f1ea" -.spot-icon_reminder:before +.spot-icon_drag-handle:before content: "\f1ea" -@mixin spot-icon-remove-1 +@mixin spot-icon-download content: "\f1eb" -.spot-icon_remove-1:before +.spot-icon_download:before content: "\f1eb" -@mixin spot-icon-remove-link +@mixin spot-icon-download-arrow content: "\f1ec" -.spot-icon_remove-link:before +.spot-icon_download-arrow:before content: "\f1ec" -@mixin spot-icon-remove +@mixin spot-icon-double-arrow-right content: "\f1ed" -.spot-icon_remove:before +.spot-icon_double-arrow-right:before content: "\f1ed" -@mixin spot-icon-rename +@mixin spot-icon-double-arrow-left content: "\f1ee" -.spot-icon_rename:before +.spot-icon_double-arrow-left:before content: "\f1ee" -@mixin spot-icon-reported-by-me +@mixin spot-icon-design content: "\f1ef" -.spot-icon_reported-by-me:before +.spot-icon_design:before content: "\f1ef" -@mixin spot-icon-resizer-bottom-right +@mixin spot-icon-dependency content: "\f1f0" -.spot-icon_resizer-bottom-right:before +.spot-icon_dependency:before content: "\f1f0" -@mixin spot-icon-resizer-vertical-lines +@mixin spot-icon-delta-triangle content: "\f1f1" -.spot-icon_resizer-vertical-lines:before +.spot-icon_delta-triangle:before content: "\f1f1" -@mixin spot-icon-return-to-previous +@mixin spot-icon-delete content: "\f1f2" -.spot-icon_return-to-previous:before +.spot-icon_delete:before content: "\f1f2" -@mixin spot-icon-roadmap +@mixin spot-icon-delete-folder content: "\f1f3" -.spot-icon_roadmap:before +.spot-icon_delete-folder:before content: "\f1f3" -@mixin spot-icon-rss +@mixin spot-icon-date-alerts content: "\f1f4" -.spot-icon_rss:before +.spot-icon_date-alerts:before content: "\f1f4" -@mixin spot-icon-rubber +@mixin spot-icon-cut content: "\f1f5" -.spot-icon_rubber:before +.spot-icon_cut:before content: "\f1f5" -@mixin spot-icon-save +@mixin spot-icon-custom-fields content: "\f1f6" -.spot-icon_save:before +.spot-icon_custom-fields:before content: "\f1f6" -@mixin spot-icon-search +@mixin spot-icon-custom-development content: "\f1f7" -.spot-icon_search:before +.spot-icon_custom-development:before content: "\f1f7" -@mixin spot-icon-select-all +@mixin spot-icon-cursor content: "\f1f8" -.spot-icon_select-all:before +.spot-icon_cursor:before content: "\f1f8" -@mixin spot-icon-send-mail +@mixin spot-icon-cost-types content: "\f1f9" -.spot-icon_send-mail:before +.spot-icon_cost-types:before content: "\f1f9" -@mixin spot-icon-server-key +@mixin spot-icon-cost-reports content: "\f1fa" -.spot-icon_server-key:before +.spot-icon_cost-reports:before content: "\f1fa" -@mixin spot-icon-settings-display +@mixin spot-icon-copy content: "\f1fb" -.spot-icon_settings-display:before +.spot-icon_copy:before content: "\f1fb" -@mixin spot-icon-settings +@mixin spot-icon-copy-documents content: "\f1fc" -.spot-icon_settings:before +.spot-icon_copy-documents:before content: "\f1fc" -@mixin spot-icon-settings2 +@mixin spot-icon-contacts content: "\f1fd" -.spot-icon_settings2:before +.spot-icon_contacts:before content: "\f1fd" -@mixin spot-icon-settings3 +@mixin spot-icon-console content: "\f1fe" -.spot-icon_settings3:before +.spot-icon_console:before content: "\f1fe" -@mixin spot-icon-settings4 +@mixin spot-icon-console-light content: "\f1ff" -.spot-icon_settings4:before +.spot-icon_console-light:before content: "\f1ff" -@mixin spot-icon-share +@mixin spot-icon-configure-knobs content: "\f200" -.spot-icon_share:before +.spot-icon_configure-knobs:before content: "\f200" -@mixin spot-icon-shortcuts +@mixin spot-icon-concept content: "\f201" -.spot-icon_shortcuts:before +.spot-icon_concept:before content: "\f201" -@mixin spot-icon-show-all-projects +@mixin spot-icon-compare2 content: "\f202" -.spot-icon_show-all-projects:before +.spot-icon_compare2:before content: "\f202" -@mixin spot-icon-show-more-horizontal +@mixin spot-icon-comments content: "\f203" -.spot-icon_show-more-horizontal:before +.spot-icon_comments:before content: "\f203" -@mixin spot-icon-show-more +@mixin spot-icon-columns content: "\f204" -.spot-icon_show-more:before +.spot-icon_columns:before content: "\f204" -@mixin spot-icon-slack +@mixin spot-icon-column-right content: "\f205" -.spot-icon_slack:before +.spot-icon_column-right:before content: "\f205" -@mixin spot-icon-snooze +@mixin spot-icon-column-left content: "\f206" -.spot-icon_snooze:before +.spot-icon_column-left:before content: "\f206" -@mixin spot-icon-sort-ascending +@mixin spot-icon-color-underline content: "\f207" -.spot-icon_sort-ascending:before +.spot-icon_color-underline:before content: "\f207" -@mixin spot-icon-sort-by +@mixin spot-icon-color-text content: "\f208" -.spot-icon_sort-by:before +.spot-icon_color-text:before content: "\f208" -@mixin spot-icon-sort-descending +@mixin spot-icon-code-tag content: "\f209" -.spot-icon_sort-descending:before +.spot-icon_code-tag:before content: "\f209" -@mixin spot-icon-sort-down +@mixin spot-icon-close content: "\f20a" -.spot-icon_sort-down:before +.spot-icon_close:before content: "\f20a" -@mixin spot-icon-sort-up +@mixin spot-icon-clipboard content: "\f20b" -.spot-icon_sort-up:before +.spot-icon_clipboard:before content: "\f20b" -@mixin spot-icon-square +@mixin spot-icon-checkmark content: "\f20c" -.spot-icon_square:before +.spot-icon_checkmark:before content: "\f20c" -@mixin spot-icon-star-empty +@mixin spot-icon-checkmark-circle content: "\f20d" -.spot-icon_star-empty:before +.spot-icon_checkmark-circle:before content: "\f20d" -@mixin spot-icon-star-filled +@mixin spot-icon-chart3 content: "\f20e" -.spot-icon_star-filled:before +.spot-icon_chart3:before content: "\f20e" -@mixin spot-icon-star +@mixin spot-icon-chart2 content: "\f20f" -.spot-icon_star:before +.spot-icon_chart2:before content: "\f20f" -@mixin spot-icon-status-reporting +@mixin spot-icon-chart1 content: "\f210" -.spot-icon_status-reporting:before +.spot-icon_chart1:before content: "\f210" -@mixin spot-icon-status +@mixin spot-icon-changeset content: "\f211" -.spot-icon_status:before +.spot-icon_changeset:before content: "\f211" -@mixin spot-icon-stop +@mixin spot-icon-changeset-up content: "\f212" -.spot-icon_stop:before +.spot-icon_changeset-up:before content: "\f212" -@mixin spot-icon-strike-through +@mixin spot-icon-changeset-down content: "\f213" -.spot-icon_strike-through:before +.spot-icon_changeset-down:before content: "\f213" -@mixin spot-icon-sum-error +@mixin spot-icon-cart content: "\f214" -.spot-icon_sum-error:before +.spot-icon_cart:before content: "\f214" -@mixin spot-icon-sum-sign +@mixin spot-icon-cancel content: "\f215" -.spot-icon_sum-sign:before +.spot-icon_cancel:before content: "\f215" -@mixin spot-icon-team-planner +@mixin spot-icon-cancel-circle content: "\f216" -.spot-icon_team-planner:before +.spot-icon_cancel-circle:before content: "\f216" -@mixin spot-icon-text +@mixin spot-icon-camera content: "\f217" -.spot-icon_text:before +.spot-icon_camera:before content: "\f217" -@mixin spot-icon-ticket-checked +@mixin spot-icon-calendar2 content: "\f218" -.spot-icon_ticket-checked:before +.spot-icon_calendar2:before content: "\f218" -@mixin spot-icon-ticket-down +@mixin spot-icon-calendar content: "\f219" -.spot-icon_ticket-down:before +.spot-icon_calendar:before content: "\f219" -@mixin spot-icon-ticket-edit +@mixin spot-icon-bug content: "\f21a" -.spot-icon_ticket-edit:before +.spot-icon_bug:before content: "\f21a" -@mixin spot-icon-ticket-minus +@mixin spot-icon-budget content: "\f21b" -.spot-icon_ticket-minus:before +.spot-icon_budget:before content: "\f21b" -@mixin spot-icon-ticket-note +@mixin spot-icon-bookmark content: "\f21c" -.spot-icon_ticket-note:before +.spot-icon_bookmark:before content: "\f21c" -@mixin spot-icon-ticket +@mixin spot-icon-bookmark-filled content: "\f21d" -.spot-icon_ticket:before +.spot-icon_bookmark-filled:before content: "\f21d" -@mixin spot-icon-time-tracking-running +@mixin spot-icon-bold content: "\f21e" -.spot-icon_time-tracking-running:before +.spot-icon_bold:before content: "\f21e" -@mixin spot-icon-time-tracking-start +@mixin spot-icon-boards content: "\f21f" -.spot-icon_time-tracking-start:before +.spot-icon_boards:before content: "\f21f" -@mixin spot-icon-time-tracking-stop +@mixin spot-icon-blocked content: "\f220" -.spot-icon_time-tracking-stop:before +.spot-icon_blocked:before content: "\f220" -@mixin spot-icon-time +@mixin spot-icon-billing-information content: "\f221" -.spot-icon_time:before +.spot-icon_billing-information:before content: "\f221" -@mixin spot-icon-to-fullscreen +@mixin spot-icon-bell content: "\f222" -.spot-icon_to-fullscreen:before +.spot-icon_bell:before content: "\f222" -@mixin spot-icon-today-arrows +@mixin spot-icon-bcf content: "\f223" -.spot-icon_today-arrows:before +.spot-icon_bcf:before content: "\f223" -@mixin spot-icon-training-consulting +@mixin spot-icon-baseline content: "\f224" -.spot-icon_training-consulting:before +.spot-icon_baseline:before content: "\f224" -@mixin spot-icon-two-factor-authentication +@mixin spot-icon-baseline-delete content: "\f225" -.spot-icon_two-factor-authentication:before +.spot-icon_baseline-delete:before content: "\f225" -@mixin spot-icon-two-factor-authentification +@mixin spot-icon-baseline-add content: "\f226" -.spot-icon_two-factor-authentification:before +.spot-icon_baseline-add:before content: "\f226" -@mixin spot-icon-types +@mixin spot-icon-backlogs content: "\f227" -.spot-icon_types:before +.spot-icon_backlogs:before content: "\f227" -@mixin spot-icon-underline +@mixin spot-icon-back-up content: "\f228" -.spot-icon_underline:before +.spot-icon_back-up:before content: "\f228" -@mixin spot-icon-undo +@mixin spot-icon-attention content: "\f229" -.spot-icon_undo:before +.spot-icon_attention:before content: "\f229" -@mixin spot-icon-unit +@mixin spot-icon-attachment content: "\f22a" -.spot-icon_unit:before +.spot-icon_attachment:before content: "\f22a" -@mixin spot-icon-unlocked +@mixin spot-icon-assigned content: "\f22b" -.spot-icon_unlocked:before +.spot-icon_assigned:before content: "\f22b" -@mixin spot-icon-unordered-list +@mixin spot-icon-assigned-to-me content: "\f22c" -.spot-icon_unordered-list:before +.spot-icon_assigned-to-me:before content: "\f22c" -@mixin spot-icon-unwatched +@mixin spot-icon-arrow-up2 content: "\f22d" -.spot-icon_unwatched:before +.spot-icon_arrow-up2:before content: "\f22d" -@mixin spot-icon-up-down-stepper +@mixin spot-icon-arrow-up1 content: "\f22e" -.spot-icon_up-down-stepper:before +.spot-icon_arrow-up1:before content: "\f22e" -@mixin spot-icon-upload-arrow +@mixin spot-icon-arrow-thin content: "\f22f" -.spot-icon_upload-arrow:before +.spot-icon_arrow-thin:before content: "\f22f" -@mixin spot-icon-upload +@mixin spot-icon-arrow-thin-left content: "\f230" -.spot-icon_upload:before +.spot-icon_arrow-thin-left:before content: "\f230" -@mixin spot-icon-user-minus +@mixin spot-icon-arrow-right7 content: "\f231" -.spot-icon_user-minus:before +.spot-icon_arrow-right7:before content: "\f231" -@mixin spot-icon-user-missing +@mixin spot-icon-arrow-right6 content: "\f232" -.spot-icon_user-missing:before +.spot-icon_arrow-right6:before content: "\f232" -@mixin spot-icon-user-plus +@mixin spot-icon-arrow-right5 content: "\f233" -.spot-icon_user-plus:before +.spot-icon_arrow-right5:before content: "\f233" -@mixin spot-icon-user +@mixin spot-icon-arrow-right4 content: "\f234" -.spot-icon_user:before +.spot-icon_arrow-right4:before content: "\f234" -@mixin spot-icon-view-card +@mixin spot-icon-arrow-right3 content: "\f235" -.spot-icon_view-card:before +.spot-icon_arrow-right3:before content: "\f235" -@mixin spot-icon-view-fullscreen +@mixin spot-icon-arrow-right2 content: "\f236" -.spot-icon_view-fullscreen:before +.spot-icon_arrow-right2:before content: "\f236" -@mixin spot-icon-view-list +@mixin spot-icon-arrow-out content: "\f237" -.spot-icon_view-list:before +.spot-icon_arrow-out:before content: "\f237" -@mixin spot-icon-view-model +@mixin spot-icon-arrow-left4 content: "\f238" -.spot-icon_view-model:before +.spot-icon_arrow-left4:before content: "\f238" -@mixin spot-icon-view-split-viewer-table +@mixin spot-icon-arrow-left3 content: "\f239" -.spot-icon_view-split-viewer-table:before +.spot-icon_arrow-left3:before content: "\f239" -@mixin spot-icon-view-split +@mixin spot-icon-arrow-left2 content: "\f23a" -.spot-icon_view-split:before +.spot-icon_arrow-left2:before content: "\f23a" -@mixin spot-icon-view-split2 +@mixin spot-icon-arrow-left1 content: "\f23b" -.spot-icon_view-split2:before +.spot-icon_arrow-left1:before content: "\f23b" -@mixin spot-icon-view-timeline +@mixin spot-icon-arrow-left-right content: "\f23c" -.spot-icon_view-timeline:before +.spot-icon_arrow-left-right:before content: "\f23c" -@mixin spot-icon-warning +@mixin spot-icon-arrow-in content: "\f23d" -.spot-icon_warning:before +.spot-icon_arrow-in:before content: "\f23d" -@mixin spot-icon-watched +@mixin spot-icon-arrow-down2 content: "\f23e" -.spot-icon_watched:before +.spot-icon_arrow-down2:before content: "\f23e" -@mixin spot-icon-watching +@mixin spot-icon-arrow-down1 content: "\f23f" -.spot-icon_watching:before +.spot-icon_arrow-down1:before content: "\f23f" -@mixin spot-icon-wiki-edit +@mixin spot-icon-align-right content: "\f240" -.spot-icon_wiki-edit:before +.spot-icon_align-right:before content: "\f240" -@mixin spot-icon-wiki +@mixin spot-icon-align-left content: "\f241" -.spot-icon_wiki:before +.spot-icon_align-left:before content: "\f241" -@mixin spot-icon-wiki2 +@mixin spot-icon-align-justify content: "\f242" -.spot-icon_wiki2:before +.spot-icon_align-justify:before content: "\f242" -@mixin spot-icon-work-packages +@mixin spot-icon-align-center content: "\f243" -.spot-icon_work-packages:before +.spot-icon_align-center:before content: "\f243" -@mixin spot-icon-workflow +@mixin spot-icon-add content: "\f244" -.spot-icon_workflow:before +.spot-icon_add:before content: "\f244" -@mixin spot-icon-yes +@mixin spot-icon-add-link content: "\f245" -.spot-icon_yes:before +.spot-icon_add-link:before content: "\f245" -@mixin spot-icon-zen-mode +@mixin spot-icon-add-attachment content: "\f246" -.spot-icon_zen-mode:before +.spot-icon_add-attachment:before content: "\f246" -@mixin spot-icon-zoom-auto +@mixin spot-icon-activity-history content: "\f247" -.spot-icon_zoom-auto:before +.spot-icon_activity-history:before content: "\f247" -@mixin spot-icon-zoom-in +@mixin spot-icon-accountable content: "\f248" -.spot-icon_zoom-in:before +.spot-icon_accountable:before content: "\f248" -@mixin spot-icon-zoom-out +@mixin spot-icon-accessibility content: "\f249" -.spot-icon_zoom-out:before +.spot-icon_accessibility:before content: "\f249" diff --git a/frontend/src/assets/fonts/openproject_icon/openproject-icon-font.html b/frontend/src/assets/fonts/openproject_icon/openproject-icon-font.html index 14f11926b2e5..265938846694 100644 --- a/frontend/src/assets/fonts/openproject_icon/openproject-icon-font.html +++ b/frontend/src/assets/fonts/openproject_icon/openproject-icon-font.html @@ -25,3897 +25,4313 @@ font-size: 16px; } - -@mixin icon-mixin-accessibility + +@mixin icon-mixin-zoom-out content: "\f101" -.icon-accessibility:before +.icon-zoom-out:before content: "\f101" -@mixin icon-mixin-accountable +@mixin icon-mixin-zoom-in content: "\f102" -.icon-accountable:before +.icon-zoom-in:before content: "\f102" -@mixin icon-mixin-activity-history +@mixin icon-mixin-zoom-auto content: "\f103" -.icon-activity-history:before +.icon-zoom-auto:before content: "\f103" -@mixin icon-mixin-add-attachment +@mixin icon-mixin-zen-mode content: "\f104" -.icon-add-attachment:before +.icon-zen-mode:before content: "\f104" -@mixin icon-mixin-add-link +@mixin icon-mixin-yes content: "\f105" -.icon-add-link:before +.icon-yes:before content: "\f105" -@mixin icon-mixin-add +@mixin icon-mixin-workflow content: "\f106" -.icon-add:before +.icon-workflow:before content: "\f106" -@mixin icon-mixin-align-center +@mixin icon-mixin-work-packages content: "\f107" -.icon-align-center:before +.icon-work-packages:before content: "\f107" -@mixin icon-mixin-align-justify +@mixin icon-mixin-wiki2 content: "\f108" -.icon-align-justify:before +.icon-wiki2:before content: "\f108" -@mixin icon-mixin-align-left +@mixin icon-mixin-wiki content: "\f109" -.icon-align-left:before +.icon-wiki:before content: "\f109" -@mixin icon-mixin-align-right +@mixin icon-mixin-wiki-edit content: "\f10a" -.icon-align-right:before +.icon-wiki-edit:before content: "\f10a" -@mixin icon-mixin-arrow-down1 +@mixin icon-mixin-watching content: "\f10b" -.icon-arrow-down1:before +.icon-watching:before content: "\f10b" -@mixin icon-mixin-arrow-down2 +@mixin icon-mixin-watched content: "\f10c" -.icon-arrow-down2:before +.icon-watched:before content: "\f10c" -@mixin icon-mixin-arrow-in +@mixin icon-mixin-warning content: "\f10d" -.icon-arrow-in:before +.icon-warning:before content: "\f10d" -@mixin icon-mixin-arrow-left-right +@mixin icon-mixin-view-timeline content: "\f10e" -.icon-arrow-left-right:before +.icon-view-timeline:before content: "\f10e" -@mixin icon-mixin-arrow-left1 +@mixin icon-mixin-view-split2 content: "\f10f" -.icon-arrow-left1:before +.icon-view-split2:before content: "\f10f" -@mixin icon-mixin-arrow-left2 +@mixin icon-mixin-view-split content: "\f110" -.icon-arrow-left2:before +.icon-view-split:before content: "\f110" -@mixin icon-mixin-arrow-left3 +@mixin icon-mixin-view-split-viewer-table content: "\f111" -.icon-arrow-left3:before +.icon-view-split-viewer-table:before content: "\f111" -@mixin icon-mixin-arrow-left4 +@mixin icon-mixin-view-model content: "\f112" -.icon-arrow-left4:before +.icon-view-model:before content: "\f112" -@mixin icon-mixin-arrow-out +@mixin icon-mixin-view-list content: "\f113" -.icon-arrow-out:before +.icon-view-list:before content: "\f113" -@mixin icon-mixin-arrow-right2 +@mixin icon-mixin-view-fullscreen content: "\f114" -.icon-arrow-right2:before +.icon-view-fullscreen:before content: "\f114" -@mixin icon-mixin-arrow-right3 +@mixin icon-mixin-view-card content: "\f115" -.icon-arrow-right3:before +.icon-view-card:before content: "\f115" -@mixin icon-mixin-arrow-right4 +@mixin icon-mixin-user content: "\f116" -.icon-arrow-right4:before +.icon-user:before content: "\f116" -@mixin icon-mixin-arrow-right5 +@mixin icon-mixin-user-plus content: "\f117" -.icon-arrow-right5:before +.icon-user-plus:before content: "\f117" -@mixin icon-mixin-arrow-right6 +@mixin icon-mixin-user-missing content: "\f118" -.icon-arrow-right6:before +.icon-user-missing:before content: "\f118" -@mixin icon-mixin-arrow-right7 +@mixin icon-mixin-user-minus content: "\f119" -.icon-arrow-right7:before +.icon-user-minus:before content: "\f119" -@mixin icon-mixin-arrow-thin +@mixin icon-mixin-upload content: "\f11a" -.icon-arrow-thin:before +.icon-upload:before content: "\f11a" -@mixin icon-mixin-arrow-up1 +@mixin icon-mixin-upload-arrow content: "\f11b" -.icon-arrow-up1:before +.icon-upload-arrow:before content: "\f11b" -@mixin icon-mixin-arrow-up2 +@mixin icon-mixin-up-down-stepper content: "\f11c" -.icon-arrow-up2:before +.icon-up-down-stepper:before content: "\f11c" -@mixin icon-mixin-assigned-to-me +@mixin icon-mixin-unwatched content: "\f11d" -.icon-assigned-to-me:before +.icon-unwatched:before content: "\f11d" -@mixin icon-mixin-assigned +@mixin icon-mixin-unordered-list content: "\f11e" -.icon-assigned:before +.icon-unordered-list:before content: "\f11e" -@mixin icon-mixin-attachment +@mixin icon-mixin-unlocked content: "\f11f" -.icon-attachment:before +.icon-unlocked:before content: "\f11f" -@mixin icon-mixin-attention +@mixin icon-mixin-unit content: "\f120" -.icon-attention:before +.icon-unit:before content: "\f120" -@mixin icon-mixin-back-up +@mixin icon-mixin-undo content: "\f121" -.icon-back-up:before +.icon-undo:before content: "\f121" -@mixin icon-mixin-backlogs +@mixin icon-mixin-underline content: "\f122" -.icon-backlogs:before +.icon-underline:before content: "\f122" -@mixin icon-mixin-baseline +@mixin icon-mixin-types content: "\f123" -.icon-baseline:before +.icon-types:before content: "\f123" -@mixin icon-mixin-bcf +@mixin icon-mixin-two-factor-authentification content: "\f124" -.icon-bcf:before +.icon-two-factor-authentification:before content: "\f124" -@mixin icon-mixin-bell +@mixin icon-mixin-two-factor-authentication content: "\f125" -.icon-bell:before +.icon-two-factor-authentication:before content: "\f125" -@mixin icon-mixin-billing-information +@mixin icon-mixin-training-consulting content: "\f126" -.icon-billing-information:before +.icon-training-consulting:before content: "\f126" -@mixin icon-mixin-boards +@mixin icon-mixin-today-arrows content: "\f127" -.icon-boards:before +.icon-today-arrows:before content: "\f127" -@mixin icon-mixin-bold +@mixin icon-mixin-to-fullscreen content: "\f128" -.icon-bold:before +.icon-to-fullscreen:before content: "\f128" -@mixin icon-mixin-budget +@mixin icon-mixin-time content: "\f129" -.icon-budget:before +.icon-time:before content: "\f129" -@mixin icon-mixin-bug +@mixin icon-mixin-time-tracking-stop content: "\f12a" -.icon-bug:before +.icon-time-tracking-stop:before content: "\f12a" -@mixin icon-mixin-calendar +@mixin icon-mixin-time-tracking-start content: "\f12b" -.icon-calendar:before +.icon-time-tracking-start:before content: "\f12b" -@mixin icon-mixin-calendar2 +@mixin icon-mixin-time-tracking-running content: "\f12c" -.icon-calendar2:before +.icon-time-tracking-running:before content: "\f12c" -@mixin icon-mixin-camera +@mixin icon-mixin-ticket content: "\f12d" -.icon-camera:before +.icon-ticket:before content: "\f12d" -@mixin icon-mixin-cancel-circle +@mixin icon-mixin-ticket-note content: "\f12e" -.icon-cancel-circle:before +.icon-ticket-note:before content: "\f12e" -@mixin icon-mixin-cancel +@mixin icon-mixin-ticket-minus content: "\f12f" -.icon-cancel:before +.icon-ticket-minus:before content: "\f12f" -@mixin icon-mixin-cart +@mixin icon-mixin-ticket-edit content: "\f130" -.icon-cart:before +.icon-ticket-edit:before content: "\f130" -@mixin icon-mixin-changeset-down +@mixin icon-mixin-ticket-down content: "\f131" -.icon-changeset-down:before +.icon-ticket-down:before content: "\f131" -@mixin icon-mixin-changeset-up +@mixin icon-mixin-ticket-checked content: "\f132" -.icon-changeset-up:before +.icon-ticket-checked:before content: "\f132" -@mixin icon-mixin-changeset +@mixin icon-mixin-text content: "\f133" -.icon-changeset:before +.icon-text:before content: "\f133" -@mixin icon-mixin-chart1 +@mixin icon-mixin-team-planner content: "\f134" -.icon-chart1:before +.icon-team-planner:before content: "\f134" -@mixin icon-mixin-chart2 +@mixin icon-mixin-sum-sign content: "\f135" -.icon-chart2:before +.icon-sum-sign:before content: "\f135" -@mixin icon-mixin-chart3 +@mixin icon-mixin-sum-error content: "\f136" -.icon-chart3:before +.icon-sum-error:before content: "\f136" -@mixin icon-mixin-checkmark-circle +@mixin icon-mixin-strike-through content: "\f137" -.icon-checkmark-circle:before +.icon-strike-through:before content: "\f137" -@mixin icon-mixin-checkmark +@mixin icon-mixin-stop content: "\f138" -.icon-checkmark:before +.icon-stop:before content: "\f138" -@mixin icon-mixin-clipboard +@mixin icon-mixin-status content: "\f139" -.icon-clipboard:before +.icon-status:before content: "\f139" -@mixin icon-mixin-close +@mixin icon-mixin-status-reporting content: "\f13a" -.icon-close:before +.icon-status-reporting:before content: "\f13a" -@mixin icon-mixin-code-tag +@mixin icon-mixin-star content: "\f13b" -.icon-code-tag:before +.icon-star:before content: "\f13b" -@mixin icon-mixin-color-text +@mixin icon-mixin-star-filled content: "\f13c" -.icon-color-text:before +.icon-star-filled:before content: "\f13c" -@mixin icon-mixin-color-underline +@mixin icon-mixin-star-empty content: "\f13d" -.icon-color-underline:before +.icon-star-empty:before content: "\f13d" -@mixin icon-mixin-column-left +@mixin icon-mixin-square content: "\f13e" -.icon-column-left:before +.icon-square:before content: "\f13e" -@mixin icon-mixin-column-right +@mixin icon-mixin-sort-up content: "\f13f" -.icon-column-right:before +.icon-sort-up:before content: "\f13f" -@mixin icon-mixin-columns +@mixin icon-mixin-sort-down content: "\f140" -.icon-columns:before +.icon-sort-down:before content: "\f140" -@mixin icon-mixin-compare2 +@mixin icon-mixin-sort-descending content: "\f141" -.icon-compare2:before +.icon-sort-descending:before content: "\f141" -@mixin icon-mixin-concept +@mixin icon-mixin-sort-by content: "\f142" -.icon-concept:before +.icon-sort-by:before content: "\f142" -@mixin icon-mixin-console-light +@mixin icon-mixin-sort-ascending content: "\f143" -.icon-console-light:before +.icon-sort-ascending:before content: "\f143" -@mixin icon-mixin-console +@mixin icon-mixin-snooze content: "\f144" -.icon-console:before +.icon-snooze:before content: "\f144" -@mixin icon-mixin-contacts +@mixin icon-mixin-slack content: "\f145" -.icon-contacts:before +.icon-slack:before content: "\f145" -@mixin icon-mixin-copy +@mixin icon-mixin-show-more content: "\f146" -.icon-copy:before +.icon-show-more:before content: "\f146" -@mixin icon-mixin-cost-reports +@mixin icon-mixin-show-more-horizontal content: "\f147" -.icon-cost-reports:before +.icon-show-more-horizontal:before content: "\f147" -@mixin icon-mixin-cost-types +@mixin icon-mixin-show-all-projects content: "\f148" -.icon-cost-types:before +.icon-show-all-projects:before content: "\f148" -@mixin icon-mixin-cursor +@mixin icon-mixin-shortcuts content: "\f149" -.icon-cursor:before +.icon-shortcuts:before content: "\f149" -@mixin icon-mixin-custom-development +@mixin icon-mixin-share content: "\f14a" -.icon-custom-development:before +.icon-share:before content: "\f14a" -@mixin icon-mixin-custom-fields +@mixin icon-mixin-settings4 content: "\f14b" -.icon-custom-fields:before +.icon-settings4:before content: "\f14b" -@mixin icon-mixin-cut +@mixin icon-mixin-settings3 content: "\f14c" -.icon-cut:before +.icon-settings3:before content: "\f14c" -@mixin icon-mixin-date-alert +@mixin icon-mixin-settings2 content: "\f14d" -.icon-date-alert:before +.icon-settings2:before content: "\f14d" -@mixin icon-mixin-date-alerts +@mixin icon-mixin-settings content: "\f14e" -.icon-date-alerts:before +.icon-settings:before content: "\f14e" -@mixin icon-mixin-delete-folder +@mixin icon-mixin-settings-display content: "\f14f" -.icon-delete-folder:before +.icon-settings-display:before content: "\f14f" -@mixin icon-mixin-delete +@mixin icon-mixin-server-key content: "\f150" -.icon-delete:before +.icon-server-key:before content: "\f150" -@mixin icon-mixin-delta-triangle +@mixin icon-mixin-send-mail content: "\f151" -.icon-delta-triangle:before +.icon-send-mail:before content: "\f151" -@mixin icon-mixin-dependency +@mixin icon-mixin-select-all content: "\f152" -.icon-dependency:before +.icon-select-all:before content: "\f152" -@mixin icon-mixin-design +@mixin icon-mixin-search content: "\f153" -.icon-design:before +.icon-search:before content: "\f153" -@mixin icon-mixin-double-arrow-left +@mixin icon-mixin-save content: "\f154" -.icon-double-arrow-left:before +.icon-save:before content: "\f154" -@mixin icon-mixin-double-arrow-right +@mixin icon-mixin-rubber content: "\f155" -.icon-double-arrow-right:before +.icon-rubber:before content: "\f155" -@mixin icon-mixin-download-arrow +@mixin icon-mixin-rss content: "\f156" -.icon-download-arrow:before +.icon-rss:before content: "\f156" -@mixin icon-mixin-download +@mixin icon-mixin-roadmap content: "\f157" -.icon-download:before +.icon-roadmap:before content: "\f157" -@mixin icon-mixin-drag-handle +@mixin icon-mixin-return-to-previous content: "\f158" -.icon-drag-handle:before +.icon-return-to-previous:before content: "\f158" -@mixin icon-mixin-dropdown-open +@mixin icon-mixin-resizer-vertical-lines content: "\f159" -.icon-dropdown-open:before +.icon-resizer-vertical-lines:before content: "\f159" -@mixin icon-mixin-dropdown +@mixin icon-mixin-resizer-bottom-right content: "\f15a" -.icon-dropdown:before +.icon-resizer-bottom-right:before content: "\f15a" -@mixin icon-mixin-duplicate +@mixin icon-mixin-reported-by-me content: "\f15b" -.icon-duplicate:before +.icon-reported-by-me:before content: "\f15b" -@mixin icon-mixin-edit +@mixin icon-mixin-rename content: "\f15c" -.icon-edit:before +.icon-rename:before content: "\f15c" -@mixin icon-mixin-email-alert +@mixin icon-mixin-remove content: "\f15d" -.icon-email-alert:before +.icon-remove:before content: "\f15d" -@mixin icon-mixin-enterprise-addons +@mixin icon-mixin-remove-link content: "\f15e" -.icon-enterprise-addons:before +.icon-remove-link:before content: "\f15e" -@mixin icon-mixin-enterprise +@mixin icon-mixin-remove-1 content: "\f15f" -.icon-enterprise:before +.icon-remove-1:before content: "\f15f" -@mixin icon-mixin-enumerations +@mixin icon-mixin-reminder content: "\f160" -.icon-enumerations:before +.icon-reminder:before content: "\f160" -@mixin icon-mixin-error +@mixin icon-mixin-reload content: "\f161" -.icon-error:before +.icon-reload:before content: "\f161" -@mixin icon-mixin-export-atom +@mixin icon-mixin-relations content: "\f162" -.icon-export-atom:before +.icon-relations:before content: "\f162" -@mixin icon-mixin-export-bcf +@mixin icon-mixin-relation-precedes content: "\f163" -.icon-export-bcf:before +.icon-relation-precedes:before content: "\f163" -@mixin icon-mixin-export-csv +@mixin icon-mixin-relation-new-child content: "\f164" -.icon-export-csv:before +.icon-relation-new-child:before content: "\f164" -@mixin icon-mixin-export-pdf-descr +@mixin icon-mixin-relation-follows content: "\f165" -.icon-export-pdf-descr:before +.icon-relation-follows:before content: "\f165" -@mixin icon-mixin-export-pdf-with-descriptions +@mixin icon-mixin-redo content: "\f166" -.icon-export-pdf-with-descriptions:before +.icon-redo:before content: "\f166" -@mixin icon-mixin-export-pdf +@mixin icon-mixin-quote2 content: "\f167" -.icon-export-pdf:before +.icon-quote2:before content: "\f167" -@mixin icon-mixin-export-xls-descr +@mixin icon-mixin-quote content: "\f168" -.icon-export-xls-descr:before +.icon-quote:before content: "\f168" -@mixin icon-mixin-export-xls-with-descriptions +@mixin icon-mixin-pulldown content: "\f169" -.icon-export-xls-with-descriptions:before +.icon-pulldown:before content: "\f169" -@mixin icon-mixin-export-xls-with-relations +@mixin icon-mixin-pulldown-up content: "\f16a" -.icon-export-xls-with-relations:before +.icon-pulldown-up:before content: "\f16a" -@mixin icon-mixin-export-xls +@mixin icon-mixin-publish content: "\f16b" -.icon-export-xls:before +.icon-publish:before content: "\f16b" -@mixin icon-mixin-export +@mixin icon-mixin-projects content: "\f16c" -.icon-export:before +.icon-projects:before content: "\f16c" -@mixin icon-mixin-external-link +@mixin icon-mixin-project-types content: "\f16d" -.icon-external-link:before +.icon-project-types:before content: "\f16d" -@mixin icon-mixin-faq +@mixin icon-mixin-priority content: "\f16e" -.icon-faq:before +.icon-priority:before content: "\f16e" -@mixin icon-mixin-file-doc +@mixin icon-mixin-print content: "\f16f" -.icon-file-doc:before +.icon-print:before content: "\f16f" -@mixin icon-mixin-file-form +@mixin icon-mixin-preview content: "\f170" -.icon-file-form:before +.icon-preview:before content: "\f170" -@mixin icon-mixin-file-presentation +@mixin icon-mixin-presentation content: "\f171" -.icon-file-presentation:before +.icon-presentation:before content: "\f171" -@mixin icon-mixin-file-sheet +@mixin icon-mixin-pre content: "\f172" -.icon-file-sheet:before +.icon-pre:before content: "\f172" -@mixin icon-mixin-file-text +@mixin icon-mixin-plus content: "\f173" -.icon-file-text:before +.icon-plus:before content: "\f173" -@mixin icon-mixin-filter +@mixin icon-mixin-plugins content: "\f174" -.icon-filter:before +.icon-plugins:before content: "\f174" -@mixin icon-mixin-flag +@mixin icon-mixin-play content: "\f175" -.icon-flag:before +.icon-play:before content: "\f175" -@mixin icon-mixin-folder-add +@mixin icon-mixin-pin content: "\f176" -.icon-folder-add:before +.icon-pin:before content: "\f176" -@mixin icon-mixin-folder-locked +@mixin icon-mixin-phone content: "\f177" -.icon-folder-locked:before +.icon-phone:before content: "\f177" -@mixin icon-mixin-folder-open +@mixin icon-mixin-payment-history content: "\f178" -.icon-folder-open:before +.icon-payment-history:before content: "\f178" -@mixin icon-mixin-folder-remove +@mixin icon-mixin-paragraph content: "\f179" -.icon-folder-remove:before +.icon-paragraph:before content: "\f179" -@mixin icon-mixin-folder +@mixin icon-mixin-paragraph-right content: "\f17a" -.icon-folder:before +.icon-paragraph-right:before content: "\f17a" -@mixin icon-mixin-forums +@mixin icon-mixin-paragraph-left content: "\f17b" -.icon-forums:before +.icon-paragraph-left:before content: "\f17b" -@mixin icon-mixin-from-fullscreen +@mixin icon-mixin-outline content: "\f17c" -.icon-from-fullscreen:before +.icon-outline:before content: "\f17c" -@mixin icon-mixin-getting-started +@mixin icon-mixin-ordered-list content: "\f17d" -.icon-getting-started:before +.icon-ordered-list:before content: "\f17d" -@mixin icon-mixin-glossar +@mixin icon-mixin-openproject content: "\f17e" -.icon-glossar:before +.icon-openproject:before content: "\f17e" -@mixin icon-mixin-google-plus +@mixin icon-mixin-openid content: "\f17f" -.icon-google-plus:before +.icon-openid:before content: "\f17f" -@mixin icon-mixin-group-by +@mixin icon-mixin-notes content: "\f180" -.icon-group-by:before +.icon-notes:before content: "\f180" -@mixin icon-mixin-group +@mixin icon-mixin-not-watching content: "\f181" -.icon-group:before +.icon-not-watching:before content: "\f181" -@mixin icon-mixin-hamburger +@mixin icon-mixin-not-supported content: "\f182" -.icon-hamburger:before +.icon-not-supported:before content: "\f182" -@mixin icon-mixin-headline1 +@mixin icon-mixin-no-zen-mode content: "\f183" -.icon-headline1:before +.icon-no-zen-mode:before content: "\f183" -@mixin icon-mixin-headline2 +@mixin icon-mixin-no-hierarchy content: "\f184" -.icon-headline2:before +.icon-no-hierarchy:before content: "\f184" -@mixin icon-mixin-headline3 +@mixin icon-mixin-nextcloud content: "\f185" -.icon-headline3:before +.icon-nextcloud:before content: "\f185" -@mixin icon-mixin-headset +@mixin icon-mixin-nextcloud-circle content: "\f186" -.icon-headset:before +.icon-nextcloud-circle:before content: "\f186" -@mixin icon-mixin-help +@mixin icon-mixin-news content: "\f187" -.icon-help:before +.icon-news:before content: "\f187" -@mixin icon-mixin-help1 +@mixin icon-mixin-new-planning-element content: "\f188" -.icon-help1:before +.icon-new-planning-element:before content: "\f188" -@mixin icon-mixin-help2 +@mixin icon-mixin-music content: "\f189" -.icon-help2:before +.icon-music:before content: "\f189" -@mixin icon-mixin-hierarchy +@mixin icon-mixin-movie content: "\f18a" -.icon-hierarchy:before +.icon-movie:before content: "\f18a" -@mixin icon-mixin-home +@mixin icon-mixin-move content: "\f18b" -.icon-home:before +.icon-move:before content: "\f18b" -@mixin icon-mixin-hosting +@mixin icon-mixin-more content: "\f18c" -.icon-hosting:before +.icon-more:before content: "\f18c" -@mixin icon-mixin-ifc +@mixin icon-mixin-modules content: "\f18d" -.icon-ifc:before +.icon-modules:before content: "\f18d" -@mixin icon-mixin-image1 +@mixin icon-mixin-mobile content: "\f18e" -.icon-image1:before +.icon-mobile:before content: "\f18e" -@mixin icon-mixin-image2 +@mixin icon-mixin-minus2 content: "\f18f" -.icon-image2:before +.icon-minus2:before content: "\f18f" -@mixin icon-mixin-import +@mixin icon-mixin-minus1 content: "\f190" -.icon-import:before +.icon-minus1:before content: "\f190" -@mixin icon-mixin-inbox +@mixin icon-mixin-milestone content: "\f191" -.icon-inbox:before +.icon-milestone:before content: "\f191" -@mixin icon-mixin-info1 +@mixin icon-mixin-microphone content: "\f192" -.icon-info1:before +.icon-microphone:before content: "\f192" -@mixin icon-mixin-info2 +@mixin icon-mixin-merge-branch content: "\f193" -.icon-info2:before +.icon-merge-branch:before content: "\f193" -@mixin icon-mixin-input-disabled +@mixin icon-mixin-menu content: "\f194" -.icon-input-disabled:before +.icon-menu:before content: "\f194" -@mixin icon-mixin-installation-services +@mixin icon-mixin-mention content: "\f195" -.icon-installation-services:before +.icon-mention:before content: "\f195" -@mixin icon-mixin-italic +@mixin icon-mixin-mention-comment content: "\f196" -.icon-italic:before +.icon-mention-comment:before content: "\f196" -@mixin icon-mixin-key +@mixin icon-mixin-meetings content: "\f197" -.icon-key:before +.icon-meetings:before content: "\f197" -@mixin icon-mixin-link +@mixin icon-mixin-medal content: "\f198" -.icon-link:before +.icon-medal:before content: "\f198" -@mixin icon-mixin-loading1 +@mixin icon-mixin-mark-read content: "\f199" -.icon-loading1:before +.icon-mark-read:before content: "\f199" -@mixin icon-mixin-loading2 +@mixin icon-mixin-mark-all-read content: "\f19a" -.icon-loading2:before +.icon-mark-all-read:before content: "\f19a" -@mixin icon-mixin-location +@mixin icon-mixin-maintenance-support content: "\f19b" -.icon-location:before +.icon-maintenance-support:before content: "\f19b" -@mixin icon-mixin-locked +@mixin icon-mixin-mail2 content: "\f19c" -.icon-locked:before +.icon-mail2:before content: "\f19c" -@mixin icon-mixin-logout +@mixin icon-mixin-mail1 content: "\f19d" -.icon-logout:before +.icon-mail1:before content: "\f19d" -@mixin icon-mixin-mail1 +@mixin icon-mixin-logout content: "\f19e" -.icon-mail1:before +.icon-logout:before content: "\f19e" -@mixin icon-mixin-mail2 +@mixin icon-mixin-locked content: "\f19f" -.icon-mail2:before +.icon-locked:before content: "\f19f" -@mixin icon-mixin-maintenance-support +@mixin icon-mixin-location content: "\f1a0" -.icon-maintenance-support:before +.icon-location:before content: "\f1a0" -@mixin icon-mixin-mark-all-read +@mixin icon-mixin-loading2 content: "\f1a1" -.icon-mark-all-read:before +.icon-loading2:before content: "\f1a1" -@mixin icon-mixin-mark-read +@mixin icon-mixin-loading1 content: "\f1a2" -.icon-mark-read:before +.icon-loading1:before content: "\f1a2" -@mixin icon-mixin-medal +@mixin icon-mixin-link content: "\f1a3" -.icon-medal:before +.icon-link:before content: "\f1a3" -@mixin icon-mixin-meetings +@mixin icon-mixin-like-hand content: "\f1a4" -.icon-meetings:before +.icon-like-hand:before content: "\f1a4" -@mixin icon-mixin-mention +@mixin icon-mixin-key content: "\f1a5" -.icon-mention:before +.icon-key:before content: "\f1a5" -@mixin icon-mixin-menu +@mixin icon-mixin-italic content: "\f1a6" -.icon-menu:before +.icon-italic:before content: "\f1a6" -@mixin icon-mixin-merge-branch +@mixin icon-mixin-installation-services content: "\f1a7" -.icon-merge-branch:before +.icon-installation-services:before content: "\f1a7" -@mixin icon-mixin-microphone +@mixin icon-mixin-input-disabled content: "\f1a8" -.icon-microphone:before +.icon-input-disabled:before content: "\f1a8" -@mixin icon-mixin-milestone +@mixin icon-mixin-info2 content: "\f1a9" -.icon-milestone:before +.icon-info2:before content: "\f1a9" -@mixin icon-mixin-minus1 +@mixin icon-mixin-info1 content: "\f1aa" -.icon-minus1:before +.icon-info1:before content: "\f1aa" -@mixin icon-mixin-minus2 +@mixin icon-mixin-inbox content: "\f1ab" -.icon-minus2:before +.icon-inbox:before content: "\f1ab" -@mixin icon-mixin-mobile +@mixin icon-mixin-import content: "\f1ac" -.icon-mobile:before +.icon-import:before content: "\f1ac" -@mixin icon-mixin-modules +@mixin icon-mixin-image2 content: "\f1ad" -.icon-modules:before +.icon-image2:before content: "\f1ad" -@mixin icon-mixin-more +@mixin icon-mixin-image1 content: "\f1ae" -.icon-more:before +.icon-image1:before content: "\f1ae" -@mixin icon-mixin-move +@mixin icon-mixin-ifc content: "\f1af" -.icon-move:before +.icon-ifc:before content: "\f1af" -@mixin icon-mixin-movie +@mixin icon-mixin-iconfont-scaler content: "\f1b0" -.icon-movie:before +.icon-iconfont-scaler:before content: "\f1b0" -@mixin icon-mixin-music +@mixin icon-mixin-hosting content: "\f1b1" -.icon-music:before +.icon-hosting:before content: "\f1b1" -@mixin icon-mixin-new-planning-element +@mixin icon-mixin-home content: "\f1b2" -.icon-new-planning-element:before +.icon-home:before content: "\f1b2" -@mixin icon-mixin-news +@mixin icon-mixin-hierarchy content: "\f1b3" -.icon-news:before +.icon-hierarchy:before content: "\f1b3" -@mixin icon-mixin-nextcloud-circle +@mixin icon-mixin-hide content: "\f1b4" -.icon-nextcloud-circle:before +.icon-hide:before content: "\f1b4" -@mixin icon-mixin-nextcloud +@mixin icon-mixin-help2 content: "\f1b5" -.icon-nextcloud:before +.icon-help2:before content: "\f1b5" -@mixin icon-mixin-no-hierarchy +@mixin icon-mixin-help1 content: "\f1b6" -.icon-no-hierarchy:before +.icon-help1:before content: "\f1b6" -@mixin icon-mixin-no-zen-mode +@mixin icon-mixin-help content: "\f1b7" -.icon-no-zen-mode:before +.icon-help:before content: "\f1b7" -@mixin icon-mixin-not-supported +@mixin icon-mixin-headset content: "\f1b8" -.icon-not-supported:before +.icon-headset:before content: "\f1b8" -@mixin icon-mixin-notes +@mixin icon-mixin-headline3 content: "\f1b9" -.icon-notes:before +.icon-headline3:before content: "\f1b9" -@mixin icon-mixin-openid +@mixin icon-mixin-headline2 content: "\f1ba" -.icon-openid:before +.icon-headline2:before content: "\f1ba" -@mixin icon-mixin-openproject +@mixin icon-mixin-headline1 content: "\f1bb" -.icon-openproject:before +.icon-headline1:before content: "\f1bb" -@mixin icon-mixin-ordered-list +@mixin icon-mixin-hamburger content: "\f1bc" -.icon-ordered-list:before +.icon-hamburger:before content: "\f1bc" -@mixin icon-mixin-outline +@mixin icon-mixin-group content: "\f1bd" -.icon-outline:before +.icon-group:before content: "\f1bd" -@mixin icon-mixin-paragraph-left +@mixin icon-mixin-group-by content: "\f1be" -.icon-paragraph-left:before +.icon-group-by:before content: "\f1be" -@mixin icon-mixin-paragraph-right +@mixin icon-mixin-google-plus content: "\f1bf" -.icon-paragraph-right:before +.icon-google-plus:before content: "\f1bf" -@mixin icon-mixin-paragraph +@mixin icon-mixin-glossar content: "\f1c0" -.icon-paragraph:before +.icon-glossar:before content: "\f1c0" -@mixin icon-mixin-payment-history +@mixin icon-mixin-gitlab_logo content: "\f1c1" -.icon-payment-history:before +.icon-gitlab_logo:before content: "\f1c1" -@mixin icon-mixin-phone +@mixin icon-mixin-github_logo content: "\f1c2" -.icon-phone:before +.icon-github_logo:before content: "\f1c2" -@mixin icon-mixin-pin +@mixin icon-mixin-getting-started content: "\f1c3" -.icon-pin:before +.icon-getting-started:before content: "\f1c3" -@mixin icon-mixin-play +@mixin icon-mixin-from-fullscreen content: "\f1c4" -.icon-play:before +.icon-from-fullscreen:before content: "\f1c4" -@mixin icon-mixin-plugins +@mixin icon-mixin-forums content: "\f1c5" -.icon-plugins:before +.icon-forums:before content: "\f1c5" -@mixin icon-mixin-plus +@mixin icon-mixin-folder content: "\f1c6" -.icon-plus:before +.icon-folder:before content: "\f1c6" -@mixin icon-mixin-pre +@mixin icon-mixin-folder-remove content: "\f1c7" -.icon-pre:before +.icon-folder-remove:before content: "\f1c7" -@mixin icon-mixin-presentation +@mixin icon-mixin-folder-open content: "\f1c8" -.icon-presentation:before +.icon-folder-open:before content: "\f1c8" -@mixin icon-mixin-preview +@mixin icon-mixin-folder-locked content: "\f1c9" -.icon-preview:before +.icon-folder-locked:before content: "\f1c9" -@mixin icon-mixin-print +@mixin icon-mixin-folder-add content: "\f1ca" -.icon-print:before +.icon-folder-add:before content: "\f1ca" -@mixin icon-mixin-priority +@mixin icon-mixin-flag content: "\f1cb" -.icon-priority:before +.icon-flag:before content: "\f1cb" -@mixin icon-mixin-project-types +@mixin icon-mixin-filter content: "\f1cc" -.icon-project-types:before +.icon-filter:before content: "\f1cc" -@mixin icon-mixin-projects +@mixin icon-mixin-file-text content: "\f1cd" -.icon-projects:before +.icon-file-text:before content: "\f1cd" -@mixin icon-mixin-publish +@mixin icon-mixin-file-storage-connection content: "\f1ce" -.icon-publish:before +.icon-file-storage-connection:before content: "\f1ce" -@mixin icon-mixin-pulldown-up +@mixin icon-mixin-file-sheet content: "\f1cf" -.icon-pulldown-up:before +.icon-file-sheet:before content: "\f1cf" -@mixin icon-mixin-pulldown +@mixin icon-mixin-file-presentation content: "\f1d0" -.icon-pulldown:before +.icon-file-presentation:before content: "\f1d0" -@mixin icon-mixin-quote +@mixin icon-mixin-file-form content: "\f1d1" -.icon-quote:before +.icon-file-form:before content: "\f1d1" -@mixin icon-mixin-quote2 +@mixin icon-mixin-file-doc content: "\f1d2" -.icon-quote2:before +.icon-file-doc:before content: "\f1d2" -@mixin icon-mixin-redo +@mixin icon-mixin-faq content: "\f1d3" -.icon-redo:before +.icon-faq:before content: "\f1d3" -@mixin icon-mixin-relation-follows +@mixin icon-mixin-external-link content: "\f1d4" -.icon-relation-follows:before +.icon-external-link:before content: "\f1d4" -@mixin icon-mixin-relation-new-child +@mixin icon-mixin-export content: "\f1d5" -.icon-relation-new-child:before +.icon-export:before content: "\f1d5" -@mixin icon-mixin-relation-precedes +@mixin icon-mixin-export-xls content: "\f1d6" -.icon-relation-precedes:before +.icon-export-xls:before content: "\f1d6" -@mixin icon-mixin-relations +@mixin icon-mixin-export-xls-with-relations content: "\f1d7" -.icon-relations:before +.icon-export-xls-with-relations:before content: "\f1d7" -@mixin icon-mixin-reload +@mixin icon-mixin-export-xls-with-descriptions content: "\f1d8" -.icon-reload:before +.icon-export-xls-with-descriptions:before content: "\f1d8" -@mixin icon-mixin-reminder +@mixin icon-mixin-export-xls-descr content: "\f1d9" -.icon-reminder:before +.icon-export-xls-descr:before content: "\f1d9" -@mixin icon-mixin-remove-link +@mixin icon-mixin-export-pdf content: "\f1da" -.icon-remove-link:before +.icon-export-pdf:before content: "\f1da" -@mixin icon-mixin-remove +@mixin icon-mixin-export-pdf-with-descriptions content: "\f1db" -.icon-remove:before +.icon-export-pdf-with-descriptions:before content: "\f1db" -@mixin icon-mixin-rename +@mixin icon-mixin-export-pdf-descr content: "\f1dc" -.icon-rename:before +.icon-export-pdf-descr:before content: "\f1dc" -@mixin icon-mixin-reported-by-me +@mixin icon-mixin-export-pdf-1 content: "\f1dd" -.icon-reported-by-me:before +.icon-export-pdf-1:before content: "\f1dd" -@mixin icon-mixin-resizer-bottom-right +@mixin icon-mixin-export-csv content: "\f1de" -.icon-resizer-bottom-right:before +.icon-export-csv:before content: "\f1de" -@mixin icon-mixin-resizer-vertical-lines +@mixin icon-mixin-export-bcf content: "\f1df" -.icon-resizer-vertical-lines:before +.icon-export-bcf:before content: "\f1df" -@mixin icon-mixin-roadmap +@mixin icon-mixin-export-atom content: "\f1e0" -.icon-roadmap:before +.icon-export-atom:before content: "\f1e0" -@mixin icon-mixin-rss +@mixin icon-mixin-error content: "\f1e1" -.icon-rss:before +.icon-error:before content: "\f1e1" -@mixin icon-mixin-rubber +@mixin icon-mixin-enumerations content: "\f1e2" -.icon-rubber:before +.icon-enumerations:before content: "\f1e2" -@mixin icon-mixin-save +@mixin icon-mixin-enterprise content: "\f1e3" -.icon-save:before +.icon-enterprise:before content: "\f1e3" -@mixin icon-mixin-search +@mixin icon-mixin-enterprise-badge content: "\f1e4" -.icon-search:before +.icon-enterprise-badge:before content: "\f1e4" -@mixin icon-mixin-select-all +@mixin icon-mixin-enterprise-addons content: "\f1e5" -.icon-select-all:before +.icon-enterprise-addons:before content: "\f1e5" -@mixin icon-mixin-send-mail +@mixin icon-mixin-email-alert content: "\f1e6" -.icon-send-mail:before +.icon-email-alert:before content: "\f1e6" -@mixin icon-mixin-server-key +@mixin icon-mixin-edit content: "\f1e7" -.icon-server-key:before +.icon-edit:before content: "\f1e7" -@mixin icon-mixin-settings +@mixin icon-mixin-duplicate content: "\f1e8" -.icon-settings:before +.icon-duplicate:before content: "\f1e8" -@mixin icon-mixin-settings2 +@mixin icon-mixin-dropdown content: "\f1e9" -.icon-settings2:before +.icon-dropdown:before content: "\f1e9" -@mixin icon-mixin-settings3 +@mixin icon-mixin-dropdown-open content: "\f1ea" -.icon-settings3:before +.icon-dropdown-open:before content: "\f1ea" -@mixin icon-mixin-settings4 +@mixin icon-mixin-drag-handle content: "\f1eb" -.icon-settings4:before +.icon-drag-handle:before content: "\f1eb" -@mixin icon-mixin-share +@mixin icon-mixin-download content: "\f1ec" -.icon-share:before +.icon-download:before content: "\f1ec" -@mixin icon-mixin-shortcuts +@mixin icon-mixin-download-arrow content: "\f1ed" -.icon-shortcuts:before +.icon-download-arrow:before content: "\f1ed" -@mixin icon-mixin-show-all-projects +@mixin icon-mixin-double-arrow-right content: "\f1ee" -.icon-show-all-projects:before +.icon-double-arrow-right:before content: "\f1ee" -@mixin icon-mixin-show-more-horizontal +@mixin icon-mixin-double-arrow-left content: "\f1ef" -.icon-show-more-horizontal:before +.icon-double-arrow-left:before content: "\f1ef" -@mixin icon-mixin-show-more +@mixin icon-mixin-design content: "\f1f0" -.icon-show-more:before +.icon-design:before content: "\f1f0" -@mixin icon-mixin-slack +@mixin icon-mixin-dependency content: "\f1f1" -.icon-slack:before +.icon-dependency:before content: "\f1f1" -@mixin icon-mixin-sort-ascending +@mixin icon-mixin-delta-triangle content: "\f1f2" -.icon-sort-ascending:before +.icon-delta-triangle:before content: "\f1f2" -@mixin icon-mixin-sort-by +@mixin icon-mixin-delete content: "\f1f3" -.icon-sort-by:before +.icon-delete:before content: "\f1f3" -@mixin icon-mixin-sort-descending +@mixin icon-mixin-delete-folder content: "\f1f4" -.icon-sort-descending:before +.icon-delete-folder:before content: "\f1f4" -@mixin icon-mixin-sort-down +@mixin icon-mixin-date-alerts content: "\f1f5" -.icon-sort-down:before +.icon-date-alerts:before content: "\f1f5" -@mixin icon-mixin-sort-up +@mixin icon-mixin-date-alert content: "\f1f6" -.icon-sort-up:before +.icon-date-alert:before content: "\f1f6" -@mixin icon-mixin-square +@mixin icon-mixin-cut content: "\f1f7" -.icon-square:before +.icon-cut:before content: "\f1f7" -@mixin icon-mixin-star +@mixin icon-mixin-custom-fields content: "\f1f8" -.icon-star:before +.icon-custom-fields:before content: "\f1f8" -@mixin icon-mixin-status-reporting +@mixin icon-mixin-custom-development content: "\f1f9" -.icon-status-reporting:before +.icon-custom-development:before content: "\f1f9" -@mixin icon-mixin-status +@mixin icon-mixin-cursor content: "\f1fa" -.icon-status:before +.icon-cursor:before content: "\f1fa" -@mixin icon-mixin-strike-through +@mixin icon-mixin-cost-types content: "\f1fb" -.icon-strike-through:before +.icon-cost-types:before content: "\f1fb" -@mixin icon-mixin-team-planner +@mixin icon-mixin-cost-reports content: "\f1fc" -.icon-team-planner:before +.icon-cost-reports:before content: "\f1fc" -@mixin icon-mixin-text +@mixin icon-mixin-copy content: "\f1fd" -.icon-text:before +.icon-copy:before content: "\f1fd" -@mixin icon-mixin-ticket-checked +@mixin icon-mixin-copy-documents content: "\f1fe" -.icon-ticket-checked:before +.icon-copy-documents:before content: "\f1fe" -@mixin icon-mixin-ticket-down +@mixin icon-mixin-contacts content: "\f1ff" -.icon-ticket-down:before +.icon-contacts:before content: "\f1ff" -@mixin icon-mixin-ticket-edit +@mixin icon-mixin-console content: "\f200" -.icon-ticket-edit:before +.icon-console:before content: "\f200" -@mixin icon-mixin-ticket-minus +@mixin icon-mixin-console-light content: "\f201" -.icon-ticket-minus:before +.icon-console-light:before content: "\f201" -@mixin icon-mixin-ticket-note +@mixin icon-mixin-configure-knobs content: "\f202" -.icon-ticket-note:before +.icon-configure-knobs:before content: "\f202" -@mixin icon-mixin-ticket +@mixin icon-mixin-concept content: "\f203" -.icon-ticket:before +.icon-concept:before content: "\f203" -@mixin icon-mixin-time-tracking-running +@mixin icon-mixin-compare2 content: "\f204" -.icon-time-tracking-running:before +.icon-compare2:before content: "\f204" -@mixin icon-mixin-time-tracking-start +@mixin icon-mixin-comments content: "\f205" -.icon-time-tracking-start:before +.icon-comments:before content: "\f205" -@mixin icon-mixin-time-tracking-stop +@mixin icon-mixin-columns content: "\f206" -.icon-time-tracking-stop:before +.icon-columns:before content: "\f206" -@mixin icon-mixin-time +@mixin icon-mixin-column-right content: "\f207" -.icon-time:before +.icon-column-right:before content: "\f207" -@mixin icon-mixin-to-fullscreen +@mixin icon-mixin-column-left content: "\f208" -.icon-to-fullscreen:before +.icon-column-left:before content: "\f208" -@mixin icon-mixin-training-consulting +@mixin icon-mixin-color-underline content: "\f209" -.icon-training-consulting:before +.icon-color-underline:before content: "\f209" -@mixin icon-mixin-two-factor-authentication +@mixin icon-mixin-color-text content: "\f20a" -.icon-two-factor-authentication:before +.icon-color-text:before content: "\f20a" -@mixin icon-mixin-types +@mixin icon-mixin-code-tag content: "\f20b" -.icon-types:before +.icon-code-tag:before content: "\f20b" -@mixin icon-mixin-underline +@mixin icon-mixin-close content: "\f20c" -.icon-underline:before +.icon-close:before content: "\f20c" -@mixin icon-mixin-undo +@mixin icon-mixin-clipboard content: "\f20d" -.icon-undo:before +.icon-clipboard:before content: "\f20d" -@mixin icon-mixin-unit +@mixin icon-mixin-checkmark content: "\f20e" -.icon-unit:before +.icon-checkmark:before content: "\f20e" -@mixin icon-mixin-unlocked +@mixin icon-mixin-checkmark-circle content: "\f20f" -.icon-unlocked:before +.icon-checkmark-circle:before content: "\f20f" -@mixin icon-mixin-unordered-list +@mixin icon-mixin-chart3 content: "\f210" -.icon-unordered-list:before +.icon-chart3:before content: "\f210" -@mixin icon-mixin-unwatched +@mixin icon-mixin-chart2 content: "\f211" -.icon-unwatched:before +.icon-chart2:before content: "\f211" -@mixin icon-mixin-upload-arrow +@mixin icon-mixin-chart1 content: "\f212" -.icon-upload-arrow:before +.icon-chart1:before content: "\f212" -@mixin icon-mixin-upload +@mixin icon-mixin-changeset content: "\f213" -.icon-upload:before +.icon-changeset:before content: "\f213" -@mixin icon-mixin-user-minus +@mixin icon-mixin-changeset-up content: "\f214" -.icon-user-minus:before +.icon-changeset-up:before content: "\f214" -@mixin icon-mixin-user-plus +@mixin icon-mixin-changeset-down content: "\f215" -.icon-user-plus:before +.icon-changeset-down:before content: "\f215" -@mixin icon-mixin-user +@mixin icon-mixin-cart content: "\f216" -.icon-user:before +.icon-cart:before content: "\f216" -@mixin icon-mixin-view-card +@mixin icon-mixin-cancel content: "\f217" -.icon-view-card:before +.icon-cancel:before content: "\f217" -@mixin icon-mixin-view-fullscreen +@mixin icon-mixin-cancel-circle content: "\f218" -.icon-view-fullscreen:before +.icon-cancel-circle:before content: "\f218" -@mixin icon-mixin-view-list +@mixin icon-mixin-camera content: "\f219" -.icon-view-list:before +.icon-camera:before content: "\f219" -@mixin icon-mixin-view-model +@mixin icon-mixin-calendar2 content: "\f21a" -.icon-view-model:before +.icon-calendar2:before content: "\f21a" -@mixin icon-mixin-view-split-viewer-table +@mixin icon-mixin-calendar content: "\f21b" -.icon-view-split-viewer-table:before +.icon-calendar:before content: "\f21b" -@mixin icon-mixin-view-split +@mixin icon-mixin-bug content: "\f21c" -.icon-view-split:before +.icon-bug:before content: "\f21c" -@mixin icon-mixin-view-split2 +@mixin icon-mixin-budget content: "\f21d" -.icon-view-split2:before +.icon-budget:before content: "\f21d" -@mixin icon-mixin-view-timeline +@mixin icon-mixin-bookmark content: "\f21e" -.icon-view-timeline:before +.icon-bookmark:before content: "\f21e" -@mixin icon-mixin-warning +@mixin icon-mixin-bookmark-filled content: "\f21f" -.icon-warning:before +.icon-bookmark-filled:before content: "\f21f" -@mixin icon-mixin-watched +@mixin icon-mixin-bold content: "\f220" -.icon-watched:before +.icon-bold:before content: "\f220" -@mixin icon-mixin-watching +@mixin icon-mixin-boards content: "\f221" -.icon-watching:before +.icon-boards:before content: "\f221" -@mixin icon-mixin-wiki-edit +@mixin icon-mixin-blocked content: "\f222" -.icon-wiki-edit:before +.icon-blocked:before content: "\f222" -@mixin icon-mixin-wiki +@mixin icon-mixin-billing-information content: "\f223" -.icon-wiki:before +.icon-billing-information:before content: "\f223" -@mixin icon-mixin-wiki2 +@mixin icon-mixin-bell content: "\f224" -.icon-wiki2:before +.icon-bell:before content: "\f224" -@mixin icon-mixin-work-packages +@mixin icon-mixin-bcf content: "\f225" -.icon-work-packages:before +.icon-bcf:before content: "\f225" -@mixin icon-mixin-workflow +@mixin icon-mixin-baseline content: "\f226" -.icon-workflow:before +.icon-baseline:before content: "\f226" -@mixin icon-mixin-yes +@mixin icon-mixin-baseline-delete content: "\f227" -.icon-yes:before +.icon-baseline-delete:before content: "\f227" -@mixin icon-mixin-zen-mode +@mixin icon-mixin-baseline-add content: "\f228" -.icon-zen-mode:before +.icon-baseline-add:before content: "\f228" -@mixin icon-mixin-zoom-auto +@mixin icon-mixin-backlogs content: "\f229" -.icon-zoom-auto:before +.icon-backlogs:before content: "\f229" -@mixin icon-mixin-zoom-in +@mixin icon-mixin-back-up content: "\f22a" -.icon-zoom-in:before +.icon-back-up:before content: "\f22a" -@mixin icon-mixin-zoom-out +@mixin icon-mixin-attention content: "\f22b" -.icon-zoom-out:before +.icon-attention:before content: "\f22b" +@mixin icon-mixin-attachment + content: "\f22c" + +.icon-attachment:before + content: "\f22c" + + +@mixin icon-mixin-assigned + content: "\f22d" + +.icon-assigned:before + content: "\f22d" + + +@mixin icon-mixin-assigned-to-me + content: "\f22e" + +.icon-assigned-to-me:before + content: "\f22e" + + +@mixin icon-mixin-arrow-up2 + content: "\f22f" + +.icon-arrow-up2:before + content: "\f22f" + + +@mixin icon-mixin-arrow-up1 + content: "\f230" + +.icon-arrow-up1:before + content: "\f230" + + +@mixin icon-mixin-arrow-thin + content: "\f231" + +.icon-arrow-thin:before + content: "\f231" + + +@mixin icon-mixin-arrow-thin-left + content: "\f232" + +.icon-arrow-thin-left:before + content: "\f232" + + +@mixin icon-mixin-arrow-right7 + content: "\f233" + +.icon-arrow-right7:before + content: "\f233" + + +@mixin icon-mixin-arrow-right6 + content: "\f234" + +.icon-arrow-right6:before + content: "\f234" + + +@mixin icon-mixin-arrow-right5 + content: "\f235" + +.icon-arrow-right5:before + content: "\f235" + + +@mixin icon-mixin-arrow-right4 + content: "\f236" + +.icon-arrow-right4:before + content: "\f236" + + +@mixin icon-mixin-arrow-right3 + content: "\f237" + +.icon-arrow-right3:before + content: "\f237" + + +@mixin icon-mixin-arrow-right2 + content: "\f238" + +.icon-arrow-right2:before + content: "\f238" + + +@mixin icon-mixin-arrow-out + content: "\f239" + +.icon-arrow-out:before + content: "\f239" + + +@mixin icon-mixin-arrow-left4 + content: "\f23a" + +.icon-arrow-left4:before + content: "\f23a" + + +@mixin icon-mixin-arrow-left3 + content: "\f23b" + +.icon-arrow-left3:before + content: "\f23b" + + +@mixin icon-mixin-arrow-left2 + content: "\f23c" + +.icon-arrow-left2:before + content: "\f23c" + + +@mixin icon-mixin-arrow-left1 + content: "\f23d" + +.icon-arrow-left1:before + content: "\f23d" + + +@mixin icon-mixin-arrow-left-right + content: "\f23e" + +.icon-arrow-left-right:before + content: "\f23e" + + +@mixin icon-mixin-arrow-in + content: "\f23f" + +.icon-arrow-in:before + content: "\f23f" + + +@mixin icon-mixin-arrow-down2 + content: "\f240" + +.icon-arrow-down2:before + content: "\f240" + + +@mixin icon-mixin-arrow-down1 + content: "\f241" + +.icon-arrow-down1:before + content: "\f241" + + +@mixin icon-mixin-align-right + content: "\f242" + +.icon-align-right:before + content: "\f242" + + +@mixin icon-mixin-align-left + content: "\f243" + +.icon-align-left:before + content: "\f243" + + +@mixin icon-mixin-align-justify + content: "\f244" + +.icon-align-justify:before + content: "\f244" + + +@mixin icon-mixin-align-center + content: "\f245" + +.icon-align-center:before + content: "\f245" + + +@mixin icon-mixin-add + content: "\f246" + +.icon-add:before + content: "\f246" + + +@mixin icon-mixin-add-link + content: "\f247" + +.icon-add-link:before + content: "\f247" + + +@mixin icon-mixin-add-attachment + content: "\f248" + +.icon-add-attachment:before + content: "\f248" + + +@mixin icon-mixin-activity-history + content: "\f249" + +.icon-activity-history:before + content: "\f249" + + +@mixin icon-mixin-accountable + content: "\f24a" + +.icon-accountable:before + content: "\f24a" + + +@mixin icon-mixin-accessibility + content: "\f24b" + +.icon-accessibility:before + content: "\f24b" + +

openproject-icon-font

- + - accessibility + zoom-out
- + - accountable + zoom-in
- + - activity-history + zoom-auto
- + - add-attachment + zen-mode
- + - add-link + yes
- + - add + workflow
- + - align-center + work-packages
- + - align-justify + wiki2
- + - align-left + wiki
- + - align-right + wiki-edit
- + - arrow-down1 + watching
- + - arrow-down2 + watched
- + - arrow-in + warning
- + - arrow-left-right + view-timeline
- + - arrow-left1 + view-split2
- + - arrow-left2 + view-split
- + - arrow-left3 + view-split-viewer-table
- + - arrow-left4 + view-model
- + - arrow-out + view-list
- + - arrow-right2 + view-fullscreen
- + - arrow-right3 + view-card
- + - arrow-right4 + user
- + - arrow-right5 + user-plus
- + - arrow-right6 + user-missing
- + - arrow-right7 + user-minus
- + - arrow-thin + upload
- + - arrow-up1 + upload-arrow
- + - arrow-up2 + up-down-stepper
- + - assigned-to-me + unwatched
- + - assigned + unordered-list
- + - attachment + unlocked +
+
+ + + + unit +
+
+ + + + undo +
+
+ + + + underline +
+
+ + + + types +
+
+ + + + two-factor-authentification +
+
+ + + + two-factor-authentication +
+
+ + + + training-consulting +
+
+ + + + today-arrows +
+
+ + + + to-fullscreen +
+
+ + + + time +
+
+ + + + time-tracking-stop +
+
+ + + + time-tracking-start +
+
+ + + + time-tracking-running +
+
+ + + + ticket +
+
+ + + + ticket-note +
+
+ + + + ticket-minus +
+
+ + + + ticket-edit +
+
+ + + + ticket-down +
+
+ + + + ticket-checked +
+
+ + + + text +
+
+ + + + team-planner +
+
+ + + + sum-sign +
+
+ + + + sum-error +
+
+ + + + strike-through +
+
+ + + + stop +
+
+ + + + status +
+
+ + + + status-reporting +
+
+ + + + star +
+
+ + + + star-filled +
+
+ + + + star-empty +
+
+ + + + square +
+
+ + + + sort-up
- + - attention + sort-down
- + - back-up + sort-descending
- + - backlogs + sort-by
- + - baseline + sort-ascending
- + - bcf + snooze
- + - bell + slack
- + - billing-information + show-more
- + - boards + show-more-horizontal
- + - bold + show-all-projects
- + - budget + shortcuts
- + - bug + share
- + - calendar + settings4
- + - calendar2 + settings3
- + - camera + settings2
- + - cancel-circle + settings
- + - cancel + settings-display
- + - cart + server-key
- + - changeset-down + send-mail
- + - changeset-up + select-all
- + - changeset + search
- + - chart1 + save
- + - chart2 + rubber
- + - chart3 + rss
- + - checkmark-circle + roadmap
- + - checkmark + return-to-previous
- + - clipboard + resizer-vertical-lines
- + - close + resizer-bottom-right
- + - code-tag + reported-by-me
- + - color-text + rename
- + - color-underline + remove
- + - column-left + remove-link
- + - column-right + remove-1
- + - columns + reminder
- + - compare2 + reload
- + - concept + relations
- + - console-light + relation-precedes
- + - console + relation-new-child
- + - contacts + relation-follows
- + - copy + redo
- + - cost-reports + quote2
- + - cost-types + quote
- + - cursor + pulldown
- + - custom-development + pulldown-up
- + - custom-fields + publish
- + - cut + projects
- + - date-alert + project-types
- + - date-alerts + priority
- + - delete-folder + print
- + - delete + preview
- + - delta-triangle + presentation
- + - dependency + pre
- + - design + plus
- + - double-arrow-left + plugins
- + - double-arrow-right + play
- + - download-arrow + pin
- + - download + phone
- + - drag-handle + payment-history
- + - dropdown-open + paragraph
- + - dropdown + paragraph-right
- + - duplicate + paragraph-left
- + - edit + outline
- + - email-alert + ordered-list
- + - enterprise-addons + openproject
- + - enterprise + openid
- + - enumerations + notes
- + - error + not-watching
- + - export-atom + not-supported
- + - export-bcf + no-zen-mode
- + - export-csv + no-hierarchy
- + - export-pdf-descr + nextcloud
- + - export-pdf-with-descriptions + nextcloud-circle
- + - export-pdf + news
- + - export-xls-descr + new-planning-element
- + - export-xls-with-descriptions + music
- + - export-xls-with-relations + movie
- + - export-xls + move
- + - export + more
- + - external-link + modules
- + - faq + mobile
- + - file-doc + minus2
- + - file-form + minus1
- + - file-presentation + milestone
- + - file-sheet + microphone
- + - file-text + merge-branch
- + - filter + menu
- + - flag + mention
- + - folder-add + mention-comment
- + - folder-locked + meetings
- + - folder-open + medal
- + - folder-remove + mark-read
- + - folder + mark-all-read
- + - forums + maintenance-support
- + - from-fullscreen + mail2
- + - getting-started + mail1
- + - glossar + logout
- + - google-plus + locked
- + - group-by + location
- + - group + loading2
- + - hamburger + loading1
- + - headline1 + link
- + - headline2 + like-hand
- + - headline3 + key
- + - headset + italic
- + - help + installation-services
- + - help1 + input-disabled
- + - help2 + info2
- + - hierarchy + info1
- + - home + inbox
- + - hosting + import
- + - ifc + image2
- + image1
- + - image2 + ifc
- + - import + iconfont-scaler
- + - inbox + hosting
- + - info1 + home
- + - info2 + hierarchy
- + - input-disabled + hide
- + - installation-services + help2
- + - italic + help1
- + - key + help
- + - link + headset
- + - loading1 + headline3
- + - loading2 + headline2
- + - location + headline1
- + - locked + hamburger
- + - logout + group
- + - mail1 + group-by
- + - mail2 + google-plus
- + - maintenance-support + glossar
- + - mark-all-read + gitlab_logo
- + - mark-read + github_logo
- + - medal + getting-started
- + - meetings + from-fullscreen
- + - mention + forums
- + - menu + folder
- + - merge-branch + folder-remove
- + - microphone + folder-open
- + - milestone + folder-locked
- + - minus1 + folder-add
- + - minus2 + flag
- + - mobile + filter
- + - modules + file-text
- + - more + file-storage-connection
- + - move + file-sheet
- + - movie + file-presentation
- + - music + file-form
- + - new-planning-element + file-doc
- + - news + faq
- + - nextcloud-circle + external-link
- + - nextcloud + export
- + - no-hierarchy + export-xls
- + - no-zen-mode + export-xls-with-relations
- + - not-supported + export-xls-with-descriptions
- + - notes + export-xls-descr
- + - openid + export-pdf
- + - openproject + export-pdf-with-descriptions
- + - ordered-list + export-pdf-descr
- + - outline + export-pdf-1
- + - paragraph-left + export-csv
- + - paragraph-right + export-bcf
- + - paragraph + export-atom
- + - payment-history + error
- + - phone + enumerations
- + - pin + enterprise
- + - play + enterprise-badge
- + - plugins + enterprise-addons
- + - plus + email-alert
- + - pre + edit
- + - presentation + duplicate
- + - preview + dropdown
- + - print + dropdown-open
- + - priority + drag-handle
- + - project-types + download
- + - projects + download-arrow
- + - publish + double-arrow-right
- + - pulldown-up + double-arrow-left
- + - pulldown + design
- + - quote + dependency
- + - quote2 + delta-triangle
- + - redo + delete
- + - relation-follows + delete-folder
- + - relation-new-child + date-alerts
- + - relation-precedes + date-alert
- + - relations + cut
- + - reload + custom-fields
- + - reminder + custom-development
- + - remove-link + cursor
- + - remove + cost-types
- + - rename + cost-reports
- + - reported-by-me + copy
- + - resizer-bottom-right + copy-documents
- + - resizer-vertical-lines + contacts
- + - roadmap + console
- + - rss + console-light
- + - rubber + configure-knobs
- + - save + concept
- + - search + compare2
- + - select-all + comments
- + - send-mail + columns
- + - server-key + column-right
- + - settings + column-left
- + - settings2 + color-underline
- + - settings3 + color-text
- + - settings4 + code-tag
- + - share + close
- + - shortcuts + clipboard
- + - show-all-projects + checkmark
- + - show-more-horizontal + checkmark-circle
- + - show-more + chart3
- + - slack + chart2
- + - sort-ascending + chart1
- + - sort-by + changeset
- + - sort-descending + changeset-up
- + - sort-down + changeset-down
- + - sort-up + cart
- + - square + cancel
- + - star + cancel-circle
- + - status-reporting + camera
- + - status + calendar2
- + - strike-through + calendar
- + - team-planner + bug
- + - text + budget
- + - ticket-checked + bookmark
- + - ticket-down + bookmark-filled
- + - ticket-edit + bold
- + - ticket-minus + boards
- + - ticket-note + blocked
- + - ticket + billing-information
- + - time-tracking-running + bell
- + - time-tracking-start + bcf
- + - time-tracking-stop + baseline
- + - time + baseline-delete
- + - to-fullscreen + baseline-add
- + - training-consulting + backlogs
- + - two-factor-authentication + back-up
- + - types + attention
- + - underline + attachment
- + - undo + assigned
- + - unit + assigned-to-me
- + - unlocked + arrow-up2
- + - unordered-list + arrow-up1
- + - unwatched + arrow-thin
- + - upload-arrow + arrow-thin-left
- + - upload + arrow-right7
- + - user-minus + arrow-right6
- + - user-plus + arrow-right5
- + - user + arrow-right4
- + - view-card + arrow-right3
- + - view-fullscreen + arrow-right2
- + - view-list + arrow-out
- + - view-model + arrow-left4
- + - view-split-viewer-table + arrow-left3
- + - view-split + arrow-left2
- + - view-split2 + arrow-left1
- + - view-timeline + arrow-left-right
- + - warning + arrow-in
- + - watched + arrow-down2
- + - watching + arrow-down1
- + - wiki-edit + align-right
- + - wiki + align-left
- + - wiki2 + align-justify
- + - work-packages + align-center
- + - workflow + add
- + - yes + add-link
- + - zen-mode + add-attachment
- + - zoom-auto + activity-history
- + - zoom-in + accountable
- + - zoom-out + accessibility
diff --git a/frontend/src/assets/fonts/openproject_icon/openproject-icon-font.svg b/frontend/src/assets/fonts/openproject_icon/openproject-icon-font.svg index 9422702eb990..ef9977cb6c7d 100644 --- a/frontend/src/assets/fonts/openproject_icon/openproject-icon-font.svg +++ b/frontend/src/assets/fonts/openproject_icon/openproject-icon-font.svg @@ -1,909 +1,1998 @@ - + - + - - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + horiz-adv-x="1024" d="M352 312L44 518L512 896L980 518L672 312L1024 6V546L512 982L0 546V6zM966 -30L600 290H424L58 -30z" /> + + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + + horiz-adv-x="1024" d="M522 108C478 108 444 144 444 186C444 230 478 264 522 264C564 264 600 230 600 186C600 144 564 108 522 108zM566 380C564 364 562 362 548 362H494C482 362 478 364 476 380L456 742C454 758 454 754 454 760C454 772 464 772 470 772H570C576 772 588 772 588 760V742zM512 986C230 986 2 758 2 476S230 -34 512 -34S1022 194 1022 476S794 986 512 986zM512 42C272 42 78 236 78 476S272 910 512 910S946 716 946 476S752 42 512 42z" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/src/assets/fonts/openproject_icon/openproject-icon-font.ttf b/frontend/src/assets/fonts/openproject_icon/openproject-icon-font.ttf index 95a24ff90fca2c2e7baf06aaa412703f69e572da..6d6f571c700ba13ed6f6f606ba0f12caabbf9747 100644 GIT binary patch literal 90040 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 Z%)6d;3xK*_2QlG8mz6A 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 Md8ghpJvB7^AAmpJN&o-= diff --git a/frontend/src/assets/fonts/openproject_icon/openproject-icon-font.woff b/frontend/src/assets/fonts/openproject_icon/openproject-icon-font.woff index f3668283d26c487ad6a1068bb2a758b3bbbacbcf..c3581d42b9088f46f0836434c13bf89b8a364fd1 100644 GIT binary patch literal 47080 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 z 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

-+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 W(8M~d#r{~cXwm-w&cN9D0001RE9>9@ delta 32448 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 BUKjuX diff --git a/frontend/src/assets/fonts/openproject_icon/openproject-icon-font.woff2 b/frontend/src/assets/fonts/openproject_icon/openproject-icon-font.woff2 index 806f8f3f51a35a729be885eb73dfe30545f905ad..76fb23abaf33d8c94d289653960a167565dce607 100644 GIT binary patch literal 39208 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 X@Ug8#|08ATw{U4~InT~al;y7yHuW(h diff --git a/frontend/src/assets/fonts/openproject_spot_icon/openproject-spot-icon-font.svg b/frontend/src/assets/fonts/openproject_spot_icon/openproject-spot-icon-font.svg index bf93a75397e6..2535965e6231 100644 --- a/frontend/src/assets/fonts/openproject_spot_icon/openproject-spot-icon-font.svg +++ b/frontend/src/assets/fonts/openproject_spot_icon/openproject-spot-icon-font.svg @@ -1,4 +1,4 @@ - + @@ -7,993 +7,1980 @@ units-per-em="1024" ascent="1024" descent="0" /> - - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + + horiz-adv-x="1024" d="M764.0405333333333 694.97472C773.0133333333333 641.9456 766.6048000000001 591.6373333333333 746.0949333333333 545.4037333333333C725.5893333333333 499.1744000000001 692.2624000000001 471.9786666666666 647.3984 463.8208C619.1999999999999 458.3808 590.9973333333332 458.3808 562.7989333333333 462.4597333333334L484.608 327.8464000000002L438.464 319.6885333333334L370.5288533333333 204.1130666666667C364.1198933333333 190.5152000000001 355.14752 183.7184000000001 341.0474666666667 180.9962666666668L291.0570666666667 171.4773333333333C285.93024 170.1205333333335 280.8029866666667 170.1205333333335 275.6757333333333 174.1994666666667C271.8301866666667 178.2784 269.2667733333334 183.7184000000001 267.98464 189.1541333333333L257.73056 258.5002666666667C253.8850133333333 272.0981333333334 256.4484266666667 284.3349333333334 265.4212266666667 296.576L434.6197333333334 565.8026666666667C424.3648 588.9152 416.6737066666667 616.1105066666667 410.2647466666666 648.7441066666668C402.57408 699.05408 414.1102933333333 741.20576 444.8725333333333 779.27808C475.6352 817.3504 516.6549333333332 840.46592 566.6432 849.984C612.7914666666666 859.50208 655.0869333333333 848.6242133333334 694.8266666666666 818.7101866666667C733.2778666666666 788.79616 756.352 746.64448 764.0405333333333 694.97472zM682.0053333333333 641.9451733333334C694.8266666666666 662.34112 699.9509333333333 685.45664 696.1066666666667 709.9319466666667C692.2624000000001 734.4068266666667 680.7253333333333 753.4429866666667 661.4997333333333 767.0404266666667C643.5541333333333 781.9972266666666 623.0442666666667 787.4363733333333 601.2544 783.3570133333334C579.4645333333333 777.9182933333334 562.7989333333333 765.68064 548.6976 745.2846933333333L541.0090666666666 728.9681066666667C539.7248 723.52896 539.7248 719.4500266666666 541.0090666666666 715.3706666666667C542.2890666666666 711.2917333333334 543.5733333333333 707.2123733333333 543.5733333333333 704.4928C544.8533333333332 700.4138666666666 547.4176 697.6942933333333 552.5461333333333 692.2551466666666C557.6704 688.1762133333334 561.5189333333333 684.0968533333333 564.0789333333332 681.3777066666667C567.9274666666666 680.01792 571.7717333333333 675.93856 578.1802666666666 670.4998400000001C585.8730666666667 665.0606933333333 590.9973333333332 662.34112 593.5616 659.6219733333334C596.1258666666666 656.9024000000001 601.2544 652.82304 607.6629333333333 647.38432C615.3514666666666 641.9451733333334 620.48 637.8662400000001 623.0442666666667 636.5064533333334C626.8885333333333 635.1466666666668 630.7328 632.4270933333333 635.8613333333333 628.34816C640.9898666666666 624.2688 644.8341333333333 622.9090133333334 648.6784 622.9090133333334H658.9354666666666C664.0597333333333 624.2688 667.9082666666666 625.6285866666667 671.7525333333333 629.7079466666667C674.3168 632.4270933333333 678.1610666666666 636.5064533333334 682.0053333333333 641.9451733333334z" /> + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + + horiz-adv-x="1024" d="M512 853.3333333333334C323.7751466666666 853.3333333333334 170.6666666666667 700.2248533333334 170.6666666666667 512C170.6666666666667 323.7760000000001 323.7751466666666 170.6666666666668 512 170.6666666666668C700.2239999999999 170.6666666666668 853.3333333333333 323.7760000000001 853.3333333333333 512C853.3333333333333 700.2248533333334 700.2239999999999 853.3333333333334 512 853.3333333333334zM512 224.0426666666667C354.6777600000001 224.0426666666667 224.0439466666667 354.6794666666667 224.0439466666667 512C224.0439466666667 669.32224 354.6777600000001 799.9560533333333 512 799.9560533333333C669.3205333333333 799.9560533333333 799.9573333333333 669.32224 799.9573333333333 512C799.9573333333333 354.6794666666667 669.3205333333333 224.0426666666667 512 224.0426666666667zM512 740.9604266666666C385.5803733333333 740.9604266666666 283.0395733333334 638.4196266666668 283.0395733333334 512C283.0395733333334 385.5786666666668 385.5803733333333 283.0378666666668 512 283.0378666666668C638.4213333333332 283.0378666666668 740.9621333333332 385.5786666666668 740.9621333333332 512C740.9621333333332 638.4196266666668 638.4213333333332 740.9604266666666 512 740.9604266666666zM512 696.0110933333333C526.0458666666666 696.0110933333333 534.4725333333333 691.7969066666667 542.9034666666666 683.36896C552.7338666666667 673.5364266666667 556.9493333333332 665.1084800000001 556.9493333333332 651.06176C556.9493333333332 624.3733333333333 538.688 606.1124266666667 512 606.1124266666667C485.312 606.1124266666667 467.0506666666666 624.3733333333333 467.0506666666666 651.06176C467.0506666666666 665.1084800000001 471.2661333333333 673.5364266666667 481.0965333333334 683.36896C489.5274666666667 691.7969066666667 497.9541333333333 696.0110933333333 512 696.0110933333333zM583.6373333333333 336.4181333333334C575.2106666666666 332.2026666666668 565.376 336.4181333333334 556.9493333333332 346.2485333333334V350.4640000000001C538.688 377.1520000000001 526.0458666666666 413.6746666666667 512 448.7893333333334C497.9541333333333 413.6746666666667 485.312 377.1520000000001 467.0506666666666 346.2485333333334V340.6293333333333C458.624 332.2026666666668 448.7893333333333 327.9872000000001 440.3626666666667 332.2026666666668C436.1472 336.4181333333334 430.528 346.2485333333334 436.1472 354.6794666666667C436.1472 358.8906666666667 436.1472 358.8906666666667 440.3626666666667 363.1061333333335C458.624 399.6288000000001 475.4773333333333 440.3626666666667 485.312 481.0965333333334V548.5226666666667C448.7893333333333 548.5226666666667 413.6733866666667 552.7338666666667 377.1524266666667 556.9493333333334C368.72448 556.9493333333334 358.89152 565.376 358.89152 575.2106666666667C358.89152 583.6373333333333 368.72448 593.472 377.1524266666667 593.472C467.0506666666666 583.6373333333333 552.7338666666667 583.6373333333333 642.6325333333333 593.472C651.0634666666666 593.472 660.8938666666666 587.8528 665.1093333333333 575.2106666666667C665.1093333333333 565.376 655.2746666666667 556.9493333333334 646.848 556.9493333333334C610.3253333333333 552.7338666666667 575.2106666666666 552.7338666666667 538.688 552.7338666666667V489.5274666666667C548.5226666666666 444.5781333333335 565.376 408.0554666666667 583.6373333333333 372.9365333333334C583.6373333333333 368.7253333333333 587.8527999999999 368.7253333333333 587.8527999999999 363.1061333333335C593.472 350.4640000000001 593.472 340.6293333333333 583.6373333333333 336.4181333333334z" /> + diff --git a/frontend/src/assets/fonts/openproject_spot_icon/openproject-spot-icon-font.ttf b/frontend/src/assets/fonts/openproject_spot_icon/openproject-spot-icon-font.ttf index 8b48b74f6ba0a4bbd8792375003133b962b8acf9..dc8db62f96af47ddb494ea51b08619e7a69b6082 100644 GIT binary patch delta 22980 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 delta 10687 zcmY+K31AdO*2iBZlgWKSID!EZ2sZ;HgqvW100F`c;XdZ*BqKA^!yF_*bO7bhMFh*G z(N)(2*8`UYqefjk@WW#f6tST1O;CVs!qjd4o%*m)i*)I{b zUsdO8s(mfj2oe>XCpuPKZ#X@@+|!R>?rAW*9s|i+lcqpE1d8kZk;e85fB6OXJ4=+* z*=M@To$23yaFM9XGNObXerIDaAs}ADgw9YX3^@J9frnoGBhi0yaQ(}m8IIiEcf`X) zcpl{}+I6T$g_s;IbKAu7e@ymD!{!NzM zL~RDyF{F1wBwmvD6pqQRP~yVW`1ECHMe}EccG29o&j!())8i{4zbdi`n^c95$g+Oz zVu@$tx|HxSc2VDDAU@NGFm6kD5`7!~V*J8X{q9QW7JYqtfyE?3O2P_~DTPv@mrfa! zNm-OlIh0H7s6FLT2kJ!c)PrI@shE0EZ|XyRsUP*H0a$>8 z2GL*|LM2p6L#d30(Qq0;BWV<~2&7=9WfNE$VEuzJ=gqG4WT23oyC9NW7j9la<4;fTTbyQDYx{g+pkNgzC zUz39PyM{s(rU*r8Ej3UhHPJe{p4QV1bR)%R18%*MHqlLVGi|0Vw3W8eEp#jWhPKmf zw1aM^owSSYAW3)9Z)rDKw1@7ZyXkjy58X?#`{?&{KRrMX(nGYD9;QFgBlIXeMvv1z zdV>B)`{_?~fDY1=)J#v&)AS6r(6jU$Jx_mzVZJ~w(o6I*9i~_4f9MFkO0UuD^alNf zj?$ZSjNYQR=^Z*wC+J=JE1jhG=x_9QdY?X^59uFtiax5MkLjPV_%rkg{fo}hr}P>9 zo6gaH=yUpCSn3z_CHk z!Mg%)o3&r7$ocQmG6~i4=@bqm5CeGcYew zaA6G$jZ`KBlOvVI!1zdIGcZF^@IDO;l2k5HOgFGiQtcR6DXI1h?3Gj=1Is1Vfq@N^ z>d3&FNp)gi*QDU?8dx}~dX5`A>$j9-P7;c9E)L5XDGM zWf0FuO=A$*NKI!D<49FAh<2oAFo=7kW-^F?q-HUQg`{RPGz;gi<}e75q~ZCjj!aFI0L7<2K*P;Uu^GVe)i2kJN z8RP*{UIrO~)O8GU1F6*vvIHp~gM2~C&meP<3NXkaq)Z06gj6sN_Fs3_Fi0_^LJU$3 zsW20lBai_S5UD7GR77emgQP^NfkApA)yN=Gk!oU)vPi9Cki1A;uh0K_+*D6q&mg0b zx`9D%BXuK#EQj-Aknc!sV37GpZDf!GNo`_a+oWz{NYA~QiQC6!$be#6aSMaANop&D z1WIZfgH%fD76wU`)U6ECE2-ZwNVKH3Gf26lZex&qN$p^ehDqJdAR&|5sm~t`axLZU*@u{{K64 z07?N;_b@05NZrezJRo%+gF=DS?-`T~r0!=>Jdk>TK^Z~nL58&6LkublQhOQFdJk)G zMkqH({eeN@LFy3(B?zfU85AR=9%E3Jkb0a!fkJ8@gHnam6AX$LQh#JnzL46_ppYT; zCk7=A?CAg+fa-?SK?ZdWsV5m!JfxZ#)IOx1Vo(KGBkvhtt#v}D6gKCe| zF$Q%XskazZfTZ4LPz#cJhoLud{^~e`0+G}S2BjjYcNr9or2fjFd?a;}K_N-%Jq9Hu zslPEOE=m2JL77SFeFg<5sSg;Go}@kmF*K+`N&SOCJxb~ngUXcDM+|CIQXey@R!RMn zLETE~G=mD3)ES1f-X{!-T2lXFP~MU{%MkQp>Qi(8YF<*GF{pk?{hL7@OzIqiikQ@Y z7}Un3K4(xRllor<^)jjR3@T?*UofblNqxznnkMz%IM{!!_!Xmn7*vWuu}$g%gR+~{ z*9;19Qr|Er#Yuh3peQHx9fR_m)b|Vuby61@l}J&6>}M(727dF zE4F6@bS~sELhE&4gx2fG2(8zN5n8V^BeY&VBRatUFLXf%2(5SxBeY@xqrX46(3KHd zu^S__UUx=ly+TH4y&^_vy&jCvdOaDT^@=svf1wq7F+wZ$W`tJk!w9X|ml0aAA0xD0 ze@1A%0gTXk0~w+99E{L*v{H6C8Z_xPAW^PPVyvei6z}>Pq6!v(~^V9 zTT&=xe##T6w$wM$GSV8;UQ4@>UY-7I`uPlB#w(e{nXb%xGT+VoCTn<>C+p6vXR^*` z7iLe$4rcGj{xGL7XJ*dsoC7&WbI#`$1$-mx~S+o$8U+<4BJ$d-mvA)AP=r$BGk*^NJT0?f)ytKT!d`tNogCJ7Ld+BNMkz{Je5x<+{pGCgn{UJtcNv%8OHuRoSZs zRjsPpR`pEP>8W$4Zl9Jlt?#tJv{$B`oxW-M1fItn8aa zf%Ww!G+Q?bpEYrlm~1_;5mUSy#W1VKM$yUobb~0j-rfM|t_>IqY``P?Z@^8n^w^vm z#VPBC8^p<$l67LNuc-Q)9HJ-P5wOC>O{W`JVn&cJlTldz9`bX|H@cozah$pO#ZgIpK?-J{+IZhF= z)~rI~Un0g@8&~2k`&Nj#)|us^-gtsJ|N#JqL*%_T-*D>>YCRIu0!=9X>3#tanjqw}cKwW#bY=QSMNCSHV}xMOmMr ziG!c(xw3v`&*zGU3@J+Z813a?;n+d>m!HocG*;aHbB|lHI^~Kzxt+3ZNqnlfZ{Om9 zg_q724jfpRSWq~yQ>OtVx_2Kjpwp#2i3Pp-^vdbjF$W)HO<#Zn46AQ&|>!F3B z%rX~>L6)k)`ghfcTI-(+#N3u$^TkYI{WK4A7R(d(Tkp*k8(MCdEd~m!Xtr=!&9g+n znlww)w`9%`1;YBE8aK+HE>5=`uF{iEOcobgo}Q#H`8(oiXDY=>>xN35q+1`3$AR569tJUNyr{CyREYW42pu33_9fKl@5@D>L9)~;*C2J6H)@p8)_%SExUQpaMQ4~!CJ5J$p1){GE)ti!{^cI(7Ytmucq z;=E`%;}995<*@-+UCXY1TK>6@xKFgaS*+V$g<`$1KJ6|lEJt^-tmV0`A_CjE21Z|W zjaX~F-bF02%DccomgkG0r8>g|oSj9n^+6}G&GL6bSLo(19mPnis3X*JJ7Ck_$rGbn zZfh?lh?bXfgiBbHazwDDJX@rQmU}bBAB43p9UJdR6OF>!m?Fkl15?BTYeup-+cMRL zJ6es2;;6M&h@YD0{E{Q&uAe`X|GKna{_xWf`Sedy<&vM4%BCMrHIMrKejyKk*CiefgUF(-$@JgY(Cmo&Px`q&Rm# z?)vvSIpE)`<*lDtvgosbyy?@?%_mMjYHL36af*-~K0YK*oEqEwz&}O{`J4B@l)L`k z*u3UFENA1%M(I3R*d=~$i8ToW@QVd%U(}&!U&7-*qgzArr@u~XKJ#vYkp2^kg zi+)$x{MeqcLLRg(%3G|yvdF5JYj#)3qTlY2^3EM{{GC;Djoc>19nZ?9T|4E*+b_z8 zcbshYZ!ZwdGq&X<$TM4ga?KW8-Mqdz|E3{AzPf3?^ln-v4{ls0U)bFLz>1<*Rl#4_%QUv*y3uJZw&(kjrPkFQ1!vOnPT7k_%?$$+u=y$Qj_H z>YyyIo-IF}zQ{VfRdkjQOs|xV>DY{En`Fb(7n|2qB@6lNl;`BIDeL8e$(TK9yL_Rt zLQbuW$R8%omJ25Cm9I|N*|K@3$WBZUlUwi`j_nCC%5=KjMmX$sd41kUQ#yKPG!SvR zd`6Db9r3QkprhU!j+mjQET_lga7H3dcfH>TL{fCu=MAh*gplF%dFuiWH^z-nCU>rj zh9lnErZn#PjM_*#iy?1aJ>*cxj5RnsW<#JP-eI{kMPF!ecmp{sXhp}bDh&=j(59i~ z(pGIP54}n*OXVAw(MSeM@w=2>)ya+wy{Z=}vsOMK@?*oV9vhL(x{-QsApYpIU;C{O zhz3ipNTpd$>}FlS@Hir-!*8Utb<=*`xm1YQD6bhvb~)Xv9noNl{`8r3;S85EJkY?d z8V>AgHhSFg7(OFnU>f%mUG7?&%kcTyTer&iKpAqmlL#b^-sojlV^@g08ZfC%4_#AF;$n7&Q zsCzcIGZe{k*E<7sM%akN&n^SqSZhBTOucf^4k;8V;SbzZ_lD-U>kT(Aif@ehtpllU zpEnp^eu~@l7>giJ-n$pw?R#4H=Hr0n-)EL_ci$3>Y))QqR&o=)(`(k#LsV3^w6a-O>2% zY`UA_#_zu!AtPvpBH=VVAH7IZ&y9pDtk>z^KC_L2> zW0TYl(5`jpDud6`F6J|xa9-_MDQ(?!Psmy4z+rlPMy4lZ2K5DpiD#s=^-?|2pwH{Z zI&Fr>8%a0(POp!boEvxbV8|QR&-Zw+YdKd9xty@Ev|k4@i~#m8frU=p|*)ZPpr1>VxupNO~=Lj*4cWX!5gW^ zVfpysZECn;=Si6`Fe4Oj`Z%1`I@hGYWek1hsd1s!4Eb~8QZNL=hh6B`NQ;kz>kT6z z(#a}+SagcT;RQ>-%v^$ktkxH*fLzDGYxVf#~@CB1}Qxb1WZS`J{ky`J? zafaOWO}2W|ZzR{l2WDV}*~QZheXF&c5eh(!=1R=XiD{YR~vDIwduT*qHP*aENK%;A;4B~ zH1^hTsJAB?NzztZ5^qbb`yUi}vCMc}bozWS3#TVF-qTWw-!SwxhqJZI;zo|vD3aXT zx8XCI0Yk1c9Ig<8Vttz5>xS>tn*k%$537OS2MoL48;FKW_@mVBH<4bAWWVW&VuH;d zGed^WZ>}|x(0I{C!(Mk@z-Yj6IRgQG&WQK=kv0s5a{@3Zx6h1vTElVbm4S?aiS*oh z5b5ZwGXf4g$H)wrIDu$T@3i5;w1}g@8F3?t)g=XDW(1*1Tb z^9I7`#G>Iucv8mI-js|E_M#yPAqB++S~G;=BeQjB99}UTUuZZvh`{F!*QW>JBJsF| zB-$n?t%>3V?eVtMhW9aZ+Pq%}Sf6R-{9a_l^nPPQe4gAZSFr}Sf%uWyHWIc&f|;d+ z3>+yoM+-POM@f3Cpe+%T^dLU;|C7q%ynt+|cD1Fo z$vPosw2sH!z3l>g&9L)@4iT>(PYz)pv{Q$oap!IyA6;-|SieG~-T$AeS8mfonJ|T4 z^FT(#^f;S1k%!yk4&HdQ&^1fcr;pjny;}^5)#{v$@RbxVN>ZeijqK= zj9JmZ)n1Re@i<|4vXL_4o)wN5!JrY!Kq+vgh_G`fEeb<(#NR%nRYdh0h}EUWdph~p zw3Mnn+kxuQlO30SeIdT0<4s!pijG~rPH_>|>Ww(Gh-buqB;hIX@$_G(lxD_dy;(Y5 zB{w*IA-yXQ5b#j=wgtY_2JdRGL!X;XOG&yZ&1^7HA_s9oNKxSw-K+JP4T(+Yv<1`D WbtW9w8I739amgDjOVt-JxX%-Kg;dOUVgL~u42)2>%|3KeR*``j3=9eR)5rIT zib|@ovw@YK?WZOO1_rAN28M1PRyZ1AV(DfK28LAx2Ih|r1}@#@f7r)tYNTff2A1CS z*^coOc8atz0@F|NQ@i}E6MRAn9rP8|)XLEn3@iirvrY{L1|wPv(0_bb+8BIZn86DM z2KfO7_JtIC*TUXP&(#(TEay`LBmCqCBo}z6wVsvHr>6NCyC@hK#CcU-U%9P~gCiJN zZZ;Sg!e;> z6Xg~K`vWyF^h7^bbANtE&$HWzXc7~PGhI#kfy(+*js!cF7Y(&&K{|qVu4H+U3u6(ofd6RzRW8jZj``D?#)CRh4d6| z|M4RbcUY9cEJZ&2d+8{V)Vc(y)w9~k80+(f(*RuR&as>HCSMzVSO4nqv>#rP@W2aP^Ts09#<;xQ)l7}*vw86jef=HdB^Rug*`a`)OljXapFMjG!G$6jynNQzMwJ8p6^s6`2j*aM_x#V|G z^Z*`(bwivfWRiyUWeKWAVW+V&R?~Xi;!z7j+#&~u%`KuyCv4M1es<6rBx98hi@&aB zeb*EbCHmdM7BAqACazfb$bVKAZ$(m}Tg|g$)4b*EA*OQ|zZ^0+p8&j0 zNaaKF)8EXl!QQXX4;uuVpHhatY2z}Bt5*rb>g+!Tm{pp345CcBzv8Zg5Ca1J;x|$( z@eD!f)P-iXNoRCuls6_JZ5O6$#1Ol@2Nr+gQ@^)pD*d@MBWZ>{6PQ<}`u? znw3`#`^%3TtvQa3I3ibb6TH7;I&KUXM*9GjXB>h%KRAjKJkxh$M)n#Ep-I6@87`;=`6ds$_{OvOAaNs<(K2E&SuAeGgc^fp^%P@Dxj$cTVX35LxW3KBE&^Lec?j?nid z*TZ7UeKnj%|8Mo{YOeJCDSQS_eHLjQZqp1jr*~{R)yN*Zn>hQRNmp(8bl}^A@)FT? z1n&d}(KR%4mj&Db4HJdaGz-h*AJmWayrjPt)tLl!A=>%|35O5fuYhW#<0YT$1cQB@ z$Tu9Gi|MA0EajaA5!j|A`JleZa_hm_$gJ2Wm~$AW7s&C(7RpP2XOcX08qhx?G> ztS8XWSVyHAh>WpvBbNz0W=+Lz11gWANEW(DNFE6fb5ZUI6u|9{_8#4{Spsi1>^?AG z+9uX0qRnqMO7RYvncwU8eS$#jSz|DP&#DP!I`h36a(Z|;kK)mqxYIv>Ye&&)1m^&7MQ%uzbfnQ$Vy??>v^)5A zrG>+|=LYXUJ|HdHEK0&L<9z>w75fNhBze;JQH+3yz|eIE(H<-d#GH(|R-Qd$(eZus z^u4nqof;Y#$`s4hq`x1FGSuC*+8x9u_JRh?++E{__FlW$kL$jqc94b4^dO`?j`BU=Uun$M zPbG%i#i?3fi0Ncr&JBW`Da?TYWgqw+brp*I?Q8zY%Z%C80iBB8x7aMGIg#nH)!G7+ z=f+&E32Z81tNe)E$U@*XenT^T<7N)Y@coI#=#w9AObbP}8d4=EV>*TW9Hmp;e$*58~}? znstRkVNr5IdHEJz2=_SGiH9cd>0bVf?hWSQL38myi&IEF9keOG?L`(^v}{Ayz>CIV z0hqYL?TDB#Be}X|Y9eug5>upysJ+;XUYv%E;uHU6_|fma7@N(%KT#^|S~{cVrn!>0 z$vw{=YhXZwV(_TNr0JPd&==w?60`23?-Ih?2T`vbhHJv(d`Ovb`S&L<+kVsQdEvh( zjO%-yO~6$qI8a{%PtYqhA)ucO^ZxKJ2U2$M$9vQg-;gdvKtfRnt0*w?HVtg=44A+9 zc7{5*w2p<_9lmD$NEo?_H^^V}AHKqRe6U=+)z=-xF(c12N&>^UPC!fHkeP|nf-3z> zJ@*rBXL#R*rRE;II@SE~9Bh?I`vY;;qgwOhF2TK%{&xAFI@Cm&naNHflHbw!=cnNw zE(5hsH;vw+elb7LZM@*;S010kA3Bs$eqDj&8Uvf~GhXQQ>q5-SfC)#mNTG;qad?V7 zT{N34&G!(K-GcBwUM`#1`)0q|lG4AHMf9(4zE0P;n>J%*Rj~?D&NZ!AwR1FXWwZgy z*Q$ZtSKoR(!c9i)Npi=jF`eb8L4cxlewNCfhb~Cbv%(@K&5soAj%+vSRpII`Cg!8{5_@VPp;&v1t)twlku=v%N!dS0#cn;jOq z2@GV)4z~LYli=e6kAH5E`{F z34H3a{Gin`T~R(XB;J0eM7BLzjIL2rWuGr}JMTj}*g!8V74g_c87pz3ttu&T!gV{U zw7#sdoI5oxS-E&<5&={3SgBYUSXrD*Okzn8_=?@!XPIV3eP53^ z@Jy))ghBCp%kUeXpyT%GL`f0*$`Y2mfG1VqYj?dow7E>vMVlGVu}6aan?T4I<2W1s zMxtvn8b}$@qQM5&5WDesLC{6s=E0E-(!tH$u>U$k&*nkIgQ(YE88cFq%zEn~FA0y- zvQe0zQzEWnINB4ea1`}C%Y5+LaQwii{T08tRuQ)jVab8ke9q)4?blFN1b-6j+cR+< z_qM1kvPhgAe59()Gck)rj{S%nmw3XPq+rFe9WdcQ0M~h^F9OBaq z&~jWn;D6UofyejJD;r$_(HIXpo#APz0Xj+-U1)QcOLHXesqfGZ9CLDDuIUE4hUN;_i~=-e-u!7dYjB$C4+2pw6+OqcH<&#FY>Fy|Dx>!bEU0 z+~joPXhV3rP~PJ=*7*J+hyq&)p<| zl2HZDE{bUxUa|OPt%|E9587Sd;&$5ND9qcv0FnttqzXS!PXc}bCcKw2ydNvPkMq=* zuNw2dpMMeaWeW^1*w2;`aY!`?HaYlLayV6Ts2L}OgdVrCE_q}hEnd`8vR^YNEQJBT zOy3bFq{+5rdf1IEKYg!Q6IRkTvt}efV@p=iU*Ckdu=8~_IL(&Dy1Tpyp>YRsHK5fF z>AdgF6&YzukN1zn6&Aq&n(H^&9T0C2<|VQAzY$lc%5AnbUydvG_3lDOO}{?o;Y#>_p2<;{^8Eb+Po!D`nU4o3mjeLf^or897n{O z-)4T@D)lp5y(Q!sBIU!KjaMr5Q*KRm#pAFld!56grOZR**hwepmYM|)p?2lt#VX3& zg`j+;+4}YHFed`QOu2nLFWkaWhQkn>hc&XDk zbH%J%n_bK}TDaJO<>yUhSu3Ww21-=84{%fu(@lmIzR<<-Q;$%5XGkD%Ms3@; zf$Yc$Z-c{bSdPO$jrOosew9iFkuQitiH|+x6rA{GF9-KbQqMK zk6G&vMAmYw-Y990uXfR9OFt0Vt?+t@3hMnhXX`wWcckH9?2^skh!8o-iF?1y@C!?^ z(g9?>q%+3CQtagvz29ddg{9c&sC!vw8ieum)Iq@{(jIVj@n&vB1!?S9`hjK1Lfo#wm$-+paSOBI&y7F2PF$89|&=b&tpnQY%PI3w01E zH&PzRcClvI#4_wwqPi2;6VFX$|LN#J_);9eVl2yVJ(}tHFL~|pFH`Fkm4WllO#f-WN%&I41Wqk(7K)l4glEDR5ZR>jde&q&>u}iznXvcF`GX7l-lgAN>f%DWr|7jM0RqMddWIXXYlgxKh z%+$KaV&FV-(0`f;VAslaFdAohnvL>54JUhD*E7BB;u_o!HTIvzL46YNN!9Cz%y$Fl zL1GJU8(MbbELtYu^T1{tM9X4qL(5^TTE_SZtFb^C^C#?|Fnz*iOi{)%ZWCE%tVH-7 zXAU}_xdiEVguIuWdBm~L^uHoRO1g;Qx9Q=cRR$+Jv$eyz6#Wtb~jFsUlAX ztMK86>G@AXT71vL%tWam>0W%#^+;DKG6}c~A3mR+DmtY<(YSFqG*og!s#!iUGE z*NVz$HE;#?s&QIejR)UUE_W#DGVpJucq8x~o05U52G#Xf_YlrW}ja0CWm5dYc!-vai z^8WYZCMX(FmGg220|NJygEtS|4om->p}sq-R+Gno5}R;gNX5_pWt-4bvCP@qsHsf{ zhjZP_@kerKaU{wWs^!EYn3P6{B}KH?oR1<11&5@nU-~LLoXwAykF-wAp5Iz%ESL`n zZ3ryck+grNa|qmH<*rA_5vvnWAqTOW znA?&wN19hKb00mx(|eM-c`bw67K~)wV&!-cB-v;PTnNhgIIIOpy6Ct_+$Y8gct{@g zEUXFD_KvM@pO9Yn9Cj!~4|e|f+XnRwW|&t{l`0}PRJ(Z2TBtIY=}?Ve?d}0(+#YA1 z%rt1K!oGh9n1hDTh|mtP4z~?4kALpV8W{01RWurmT&U8ZbhDZ;i&KSPipbl>s#wrR zym0jd(3>ysosc=*5ni)<26U92wpR@)2Bt z1nBA>U$0X#^K^y~*g3)@&zR{gClL3h^ZBA${UVB+XQpQz%IIkfMtozU^Hz0fSx=1D z{U^qpw~pCwx)bWxjO##+L#{m(2M4cl4ipD~oEzfUpOXpx`^6!s$8(JR;oxUj<;)k@ zw%QczZ53*CR@LH1mIRYd-WEjyv0sxbZj|M_37Rt@-2&hEv^d-l-v+!P`#NyUvBE{t{DofQYX49j^dtN!X$EmEo@P>|DI@u~yFSX|D#L zQS!yf70)>h#EjQ&v^c{k{-b46r_l>XSOxmQMm3-APTOP@`_~QC>}$w!a;hc4VpWc1 zq6AC5p*4F_nUOeAonDXc{$GGuWwudy-oD7i#RD^QZEk%HSDLkd;-8IK6P5CPGqp4c zX>oBpHIe9y@~r_#x|xsFMvZLr>E;&@a*$7&8j%`l{8c2LFaO=j9Mb8zgq@Qn;!tVw zyw10QD8OW2ZZWzD(Sah|+WW|HS-E#*cex0u9!I-Suc3XmCVN}2mAbtZ+C<{^$lG-3 zjCV!j$Xl@aXUh+7UwdEsx&1IuL|=6=mNBS}F3w9?Z zOSvJe+C~kUe8OT8uj^ubzuVJ}JmH7na=K1?=JvzF8EE8$Vb*pB9;2aJ$9D88 zVAWON)Yrao_tH!imMQ1oW0`ZTLYVZKmmBxYAy4R;AM9`CC@^D4CI$v_bm}?jnq2I! zua6a?6(;!}lMpRz2+T9w&{qPRaVf6Na>Eoi`NCY8Tx6RY%Z+E@R$jh0L1pCM-P~+< zHg$a^Acz_4@)5Y}a$#tK){5QGj^WRQN=w%onuLp|O8PM736?%m-X!Kf-(iK6GPPoD z?-4;VmJg)GQ7ulr`cB#9wt)N+H;-1a)P!|;8nNJiwSPa06^m4eac# zRxgu~YFN9;yO@?vG<<7-EkkpiB+bE)njcsc)GAKc=@NYo2TXJoiOD~L>ujHr0K3?lsJ@`3R5 zw&JmVQ+d%%F~M&~>^`Sl*?e4bs;s)^x+@!b_8eyb)Lqk6RYlOd4{X$tLwBm4EsKuW~vI6Xd1)}3JpV~flB?O+U z89G1SPS!uXZ~Z2M1UwH4q;VrNJSsk>NC3}y5a8**UT5~PKlWg=4u3w}!ni^eB`k(6 z7FO_$#`o94Yv=t3&Rn2e3Q`fS9C*LYPq=I=W|C;oG*!1*-?Cxo+z{qS zKwJf6fUvrIm}XU4J_7kRl#JmnmOf{~z~b0$!vQlr(BC%9L`h!T(nZ7~PtSJthnA7` z-%YSFm>?^eq@*NT+g}YT?$W~+X^z|>A$)JYAydBwC#|9B{HA|0Fuz4>NoV9nmTFG^ z)PAm#Da6f^nG;yw|B~wMi(!0_^LYLUE#(qJ7CO-E2yap;RGmBE8#Av z;wTR!V#sd==1aad6(zT!#yE;l9k{pB1iRZh-#0dBZMoP-^Z%q$Ld_my$uaU_)kRRX zD?P)oqzDs7rky(bDw}vLUfkuz7F1iF+~YQh1>l3@i3q09+Ut9EVE^F;%W3SltGaZ^ zH--hv(e1X`S{jYSx1h7I+FXx=^zk#2PTX5D{^!3_Tihf^^_y7w8P<$Rkdg!hN7DBA zqri;{w-_VTnQ<3Ny$-oY7}&C87E79uO!6Gnw;&!j89I z_ufV?a#?`ANk#H1_H34>D+D^svy0S8E?;!4q4PT8tZ~bsf@{`&^hat-*suJfx`8u0 z2;!~1o29O97g2KgxktIhfh@@xy=G*&z_KGtEY>u<2(FZPDx)9vZyXA%N6NwP1rlU4 zN`v23Qc}3kKVGdYW>Tt*&;EXnsj<75gel_~?DR+mVXP7~gUS5rv~h!C)+>5Yl`Mo? zEvnWRBR?mpEWgzMU^2@t&%uIU)h`B<4xEqrk>&}N_eDCW{?L&>V|ATGr421#8|YxB zR+V6k#IkV6{SjSSLs+bffbGT?dUj^-__v6s0aBgELt?;KIEg4HBxL z4#2dy(At%OO4;6kO3O74Eqd9D6?M17VYPoRFq&n80^~*T%6~e(sI6!SYiDHP2y$c( zysh))8&@yVo;^`{FLNu6-2%7p54Y)_sU~x6_(;Qarj#Obv@=$LRwLQ&wen(vR;u!G z@n#x$Q5O}2rjJoMaV$qUTREdr2Av-^iYP)gwGFhBEN3KVWAAQ>GyMEX~2 zm`o@j7d)*<#@WhpP2;B(7BFTr`58HO!%=kI4)ZUyav0T6U`#NK5P*#be8g9@sR?v3 zRcD*USLig3({s(&IDG~L1TVwM(}JUO@bxoyVA4hOCD3o z42vrZs`I>{8Rq8IOW=N{(fB#u;GN_0=#9n8%Y(k{_>Z=-vZT5D$$5Ftl4XI-E-~vg zcA8RG=g}X9(UxCD4j?6xP2;#PY*OyfiJZbQhs*S^4Rgz@*Q911&aU^aI#gLh&M4Gh zo>d()0a+JSZfuuy^9nh^gO>+ZV~Q~O+DW#Ti0jInvgm_66yP|4Mn6i5l+n-bc67B( zKmvy9;^)JC#TBoo{dkt2jg@tsi!{>p{5@?1-7BZ^7fPGNuDdA}jGk5P%0Ai(Ve(!K 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±k6*+zAR$ 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 I2k5>Qa(5?TfB*mh delta 37830 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 z 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 Date: Wed, 29 May 2024 14:54:29 +0300 Subject: [PATCH 042/176] [#54749] Create add project modal https://community.openproject.org/work_packages/54749 From 7ea0cb550cc113453ca2804a7d3ec5c817b03f89 Mon Sep 17 00:00:00 2001 From: Kabiru Mwenja Date: Wed, 29 May 2024 18:43:52 +0300 Subject: [PATCH 043/176] WIP[Op#54749]: Lay out blueprint of project add modal --- .../new_project_mapping_component.html.erb | 53 ++++++++++++++++ .../new_project_mapping_component.rb | 62 +++++++++++++++++++ .../project_custom_fields_controller.rb | 23 ++++++- .../project_mappings.html.erb | 6 ++ config/routes.rb | 1 + 5 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb create mode 100644 app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.rb diff --git a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb new file mode 100644 index 000000000000..75c0e713ce2e --- /dev/null +++ b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb @@ -0,0 +1,53 @@ +<% + new_project_mapping_form = Class.new(ApplicationForm) do + form do |f| + f.project_autocompleter( + name: :id, + label: Project.model_name.human, + visually_hide_label: true, + autocomplete_options: { + openDirectly: false, + focusDirectly: false, + dropdownPosition: 'bottom', + disabledProjects: Project.visible.take(10).pluck(:id).to_h { |id| [id, "Disabled reason!"] } + } + ) + end + end +%> + +<%= + render( + Primer::Alpha::Dialog.new( + id: dialog_id, + title:, + test_selector: dialog_id + ) + ) do |dialog| + dialog.with_show_button(icon: :project, aria: { label: show_button_text }) { show_button_text } + + dialog.with_header( + show_divider: false, + visually_hide_title: false + ) + + render(Primer::Beta::Text.new(tag: :div, test_selector: 'storage-oauth-client-form')) do + primer_form_with( + model: @project_mapping, + url: link_admin_settings_project_custom_field_path(@project_custom_field), + method: :post + ) do |form| + concat(render(Primer::Alpha::Dialog::Body.new( + id: dialog_body_id, test_selector: dialog_body_id, aria: { label: title } + )) do + render(new_project_mapping_form.new(form)) + end) + + concat(render(Primer::Alpha::Dialog::Footer.new(show_divider: false)) do + concat(render(Primer::ButtonComponent.new(data: { 'close-dialog-id': dialog_id })) { cancel_button_text }) + concat(render(Primer::ButtonComponent.new(scheme: :primary)) { submit_button_text }) + end) + end + end + end +%> diff --git a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.rb b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.rb new file mode 100644 index 000000000000..093061c08bc0 --- /dev/null +++ b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.rb @@ -0,0 +1,62 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2012-2023 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +module Settings + module ProjectCustomFields + module ProjectCustomFieldMapping + class NewProjectMappingComponent < ApplicationComponent # rubocop:disable OpenProject/AddPreviewForViewComponent + options dialog_id: "settings--new-project-custom-field-mapping-component", + dialog_body_id: "settings--new-project-custom-field-mapping-body-component" + + def initialize(project_mapping:, project_custom_field:, **) + @project_mapping = project_mapping + @project_custom_field = project_custom_field + super(@project_mapping, **) + end + + private + + def title + "Add projects" + end + + def show_button_text + "Add projects" + end + + def cancel_button_text + I18n.t("button_cancel") + end + + def submit_button_text + I18n.t("button_add") + end + end + end + end +end diff --git a/app/controllers/admin/settings/project_custom_fields_controller.rb b/app/controllers/admin/settings/project_custom_fields_controller.rb index 188395ad404a..00830c436d28 100644 --- a/app/controllers/admin/settings/project_custom_fields_controller.rb +++ b/app/controllers/admin/settings/project_custom_fields_controller.rb @@ -68,7 +68,28 @@ def new def edit; end - def project_mappings; end + def project_mappings + @project_mapping = ProjectCustomFieldProjectMapping.new(project_custom_field: @custom_field) + end + + def link + @project_mapping = ProjectCustomFieldProjectMapping.new(permitted_params.project_custom_field_project_mapping) + + create_service = ProjectCustomFieldProjectMappings::CreateService + .new(user: current_user, model: @project_mapping) + .call + + create_service.on_success { render_unlink_response(project: @project_mapping.project) } + + create_service.on_failure do + update_flash_message_via_turbo_stream( + message: join_flash_messages(create_service.errors.full_messages), + full: true, dismiss_scheme: :hide, scheme: :danger + ) + end + + respond_to_with_turbo_streams(status: create_service.success? ? :ok : :unprocessable_entity) + end def unlink delete_service = ProjectCustomFieldProjectMappings::DeleteService diff --git a/app/views/admin/settings/project_custom_fields/project_mappings.html.erb b/app/views/admin/settings/project_custom_fields/project_mappings.html.erb index b5ca90e77db9..325c1891711a 100644 --- a/app/views/admin/settings/project_custom_fields/project_mappings.html.erb +++ b/app/views/admin/settings/project_custom_fields/project_mappings.html.erb @@ -35,7 +35,13 @@ See COPYRIGHT and LICENSE files for more details. %> <%= + render(Settings::ProjectCustomFields::ProjectCustomFieldMapping::NewProjectMappingComponent.new( + project_mapping: @project_mapping, + project_custom_field: @custom_field + )) +%> +<%= if @custom_field.required? render Primer::Beta::Blankslate.new(border: true) do |component| component.with_visual_icon(icon: :checklist) diff --git a/config/routes.rb b/config/routes.rb index 06c8a660b8b4..9ac3deb4dee9 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -464,6 +464,7 @@ put :drop get :project_mappings + post :link delete :unlink end end From 4b92af5661f0844f163a9182e176df4fb45ccf9d Mon Sep 17 00:00:00 2001 From: Christophe Bliard Date: Wed, 29 May 2024 18:00:25 +0200 Subject: [PATCH 044/176] [49409] Display modal when clicking excluded info icon --- frontend/src/app/app.module.ts | 4 ++ .../excluded-icon-helper.service.ts | 11 +--- .../info/op-exclusion-info.component.html | 34 ++++++++++++ .../info/op-exclusion-info.component.sass | 39 ++++++++++++++ .../info/op-exclusion-info.component.ts | 54 +++++++++++++++++++ .../fields/openproject-fields.module.ts | 2 + .../inplace_editing/_display_fields.sass | 6 --- 7 files changed, 135 insertions(+), 15 deletions(-) create mode 100644 frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.html create mode 100644 frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.sass create mode 100644 frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.ts diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts index 31994a02083d..977203c614b9 100644 --- a/frontend/src/app/app.module.ts +++ b/frontend/src/app/app.module.ts @@ -151,6 +151,9 @@ import { import { AttributeHelpTextComponent, } from 'core-app/shared/components/attribute-help-texts/attribute-help-text.component'; +import { + OpExclusionInfoComponent, +} from 'core-app/shared/components/fields/display/info/op-exclusion-info.component'; export function initializeServices(injector:Injector) { return () => { @@ -334,5 +337,6 @@ export class OpenProjectModule { registerCustomElement('opce-ckeditor-augmented-textarea', CkeditorAugmentedTextareaComponent, { injector }); registerCustomElement('opce-draggable-autocompleter', DraggableAutocompleteComponent, { injector }); registerCustomElement('opce-attribute-help-text', AttributeHelpTextComponent, { injector }); + registerCustomElement('opce-exclusion-info', OpExclusionInfoComponent, { injector }); } } diff --git a/frontend/src/app/shared/components/fields/display/field-types/excluded-icon-helper.service.ts b/frontend/src/app/shared/components/fields/display/field-types/excluded-icon-helper.service.ts index a22029340237..84c818c3577f 100644 --- a/frontend/src/app/shared/components/fields/display/field-types/excluded-icon-helper.service.ts +++ b/frontend/src/app/shared/components/fields/display/field-types/excluded-icon-helper.service.ts @@ -51,14 +51,7 @@ export class ExcludedIconHelperService { } public addExcludedInfoIcon(element:HTMLElement):void { - // This should work, but does not work when adding it through javascript - // - const icon = document.createElement('i'); - icon.classList.add('icon-info1', 'excluded-from-totals'); - element.appendChild(icon); + const infoIcon = document.createElement('opce-exclusion-info'); + element.appendChild(infoIcon); } } diff --git a/frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.html b/frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.html new file mode 100644 index 000000000000..d2c17c901a89 --- /dev/null +++ b/frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.html @@ -0,0 +1,34 @@ + + + + +

+ + diff --git a/frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.sass b/frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.sass new file mode 100644 index 000000000000..424f99422588 --- /dev/null +++ b/frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.sass @@ -0,0 +1,39 @@ +@import "../../global_styles/openproject/variables" + +.op-exclusion-info + display: inline-block + + &--icon + margin-left: 0.25rem + cursor: pointer + color: var(--fgColor-muted) + &:hover + color: var(--fgColor-default) + + @media screen and (min-width: $breakpoint-lg) + &--modal + width: 200px + + &--modal + color: var(--fgColor-default) + display: flex + flex-direction: column + font-family: var(--body-font-family) + gap: 1rem + margin: 1.5rem + + &-header + font-size: 14px + line-height: 20px + font-weight: 600 + + &-content + font-size: 14px + line-height: 20px + + &-buttons + display: flex + flex-direction: row + + & button + margin: 0 diff --git a/frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.ts b/frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.ts new file mode 100644 index 000000000000..03a39dcacfcf --- /dev/null +++ b/frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.ts @@ -0,0 +1,54 @@ +/* + * -- copyright + * OpenProject is an open source project management software. + * Copyright (C) 2010-2024 the OpenProject GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 3. + * + * OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: + * Copyright (C) 2006-2013 Jean-Philippe Lang + * Copyright (C) 2010-2013 the ChiliProject Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * See COPYRIGHT and LICENSE files for more details. + * ++ + */ + +import { + ChangeDetectionStrategy, + Component, +} from '@angular/core'; +import { I18nService } from 'core-app/core/i18n/i18n.service'; + +@Component({ + selector: 'op-exclusion-info', + templateUrl: './op-exclusion-info.component.html', + styleUrls: ['./op-exclusion-info.component.sass'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class OpExclusionInfoComponent { + public opened = false; + + constructor( + readonly I18n:I18nService, + ) {} + + public toggleOpen(event:Event):void { + event.stopPropagation(); + this.opened = !this.opened; + } +} diff --git a/frontend/src/app/shared/components/fields/openproject-fields.module.ts b/frontend/src/app/shared/components/fields/openproject-fields.module.ts index c03fd9f1c1bf..bf36f72d8af0 100644 --- a/frontend/src/app/shared/components/fields/openproject-fields.module.ts +++ b/frontend/src/app/shared/components/fields/openproject-fields.module.ts @@ -99,6 +99,7 @@ import { HoursDurationEditFieldComponent, } from 'core-app/shared/components/fields/edit/field-types/hours-duration-edit-field.component'; import { ProgressPopoverEditFieldComponent } from 'core-app/shared/components/fields/edit/field-types/progress-popover-edit-field.component'; +import { OpExclusionInfoComponent } from 'core-app/shared/components/fields/display/info/op-exclusion-info.component'; import { UserEditFieldComponent } from './edit/field-types/user-edit-field.component'; import { DaysDurationEditFieldComponent, @@ -152,6 +153,7 @@ import { FormsModule } from '@angular/forms'; EditFormPortalComponent, HoursDurationEditFieldComponent, ProgressPopoverEditFieldComponent, + OpExclusionInfoComponent, DaysDurationEditFieldComponent, FloatEditFieldComponent, PlainFormattableEditFieldComponent, diff --git a/frontend/src/global_styles/content/work_packages/inplace_editing/_display_fields.sass b/frontend/src/global_styles/content/work_packages/inplace_editing/_display_fields.sass index 03a2802913fb..9885543e2036 100644 --- a/frontend/src/global_styles/content/work_packages/inplace_editing/_display_fields.sass +++ b/frontend/src/global_styles/content/work_packages/inplace_editing/_display_fields.sass @@ -100,12 +100,6 @@ display-field .-actual-value @include wp-table--actual-time-values - .excluded-from-totals - padding-left: 0.25rem - color: var(--fgColor-muted) - &:hover - color: var(--fgColor-default) - .-separator display: inline-block width: 1rem From db7cbe2b99a46c6e0cdfce3c85209403d59716b0 Mon Sep 17 00:00:00 2001 From: Kabiru Mwenja Date: Thu, 30 May 2024 08:52:25 +0300 Subject: [PATCH 045/176] WIP[Op#54749]: more building blocks --- .../new_project_mapping_component.html.erb | 37 ++++++++++++++++--- .../new_project_mapping_component.rb | 4 +- config/locales/en.yml | 3 ++ 3 files changed, 36 insertions(+), 8 deletions(-) diff --git a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb index 75c0e713ce2e..ce0f1e1750a0 100644 --- a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb +++ b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb @@ -9,9 +9,33 @@ openDirectly: false, focusDirectly: false, dropdownPosition: 'bottom', - disabledProjects: Project.visible.take(10).pluck(:id).to_h { |id| [id, "Disabled reason!"] } + disabledProjects: projects_with_custom_field_mapping } ) + + f.check_box( + name: :include_sub_projects, + label: I18n.t("projects.settings.project_custom_fields.new_project_mapping_form.include_sub_projects"), + checked: false + ) + end + + def initialize(project_custom_field:) + super() + @project_custom_field = project_custom_field + end + + private + + def projects_with_custom_field_mapping + ProjectCustomFieldProjectMapping + .where(project_custom_field: @project_custom_field) + .pluck(:project_id) + .to_h { |id| [id, project_disabled_reason] } + end + + def project_disabled_reason + I18n.t("projects.settings.project_custom_fields.new_project_mapping_form.autocompleter_disabled_reason") end end %> @@ -21,17 +45,18 @@ Primer::Alpha::Dialog.new( id: dialog_id, title:, - test_selector: dialog_id + test_selector: dialog_id, + size: :large ) ) do |dialog| - dialog.with_show_button(icon: :project, aria: { label: show_button_text }) { show_button_text } + dialog.with_show_button(scheme: :primary) { show_button_text } dialog.with_header( show_divider: false, visually_hide_title: false ) - render(Primer::Beta::Text.new(tag: :div, test_selector: 'storage-oauth-client-form')) do + render(Primer::Beta::Text.new(tag: :div)) do primer_form_with( model: @project_mapping, url: link_admin_settings_project_custom_field_path(@project_custom_field), @@ -40,12 +65,12 @@ concat(render(Primer::Alpha::Dialog::Body.new( id: dialog_body_id, test_selector: dialog_body_id, aria: { label: title } )) do - render(new_project_mapping_form.new(form)) + render(new_project_mapping_form.new(form, project_custom_field: @project_custom_field)) end) concat(render(Primer::Alpha::Dialog::Footer.new(show_divider: false)) do concat(render(Primer::ButtonComponent.new(data: { 'close-dialog-id': dialog_id })) { cancel_button_text }) - concat(render(Primer::ButtonComponent.new(scheme: :primary)) { submit_button_text }) + concat(render(Primer::ButtonComponent.new(scheme: :primary, type: :submit)) { submit_button_text }) end) end end diff --git a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.rb b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.rb index 093061c08bc0..765e1b769388 100644 --- a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.rb +++ b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.rb @@ -42,11 +42,11 @@ def initialize(project_mapping:, project_custom_field:, **) private def title - "Add projects" + I18n.t("projects.settings.project_custom_fields.new_project_mapping_form.add_projects") end def show_button_text - "Add projects" + I18n.t("projects.settings.project_custom_fields.new_project_mapping_form.add_projects") end def cancel_button_text diff --git a/config/locales/en.yml b/config/locales/en.yml index 5c221a64da4c..845f868a6402 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -333,6 +333,9 @@ Project attributes and sections are defined in the Date: Thu, 30 May 2024 09:51:59 +0200 Subject: [PATCH 046/176] Reuse existing styles --- .../info/op-exclusion-info.component.html | 24 ++++++++++--------- .../info/op-exclusion-info.component.sass | 24 +++---------------- .../styles/sass/components/action-bar.sass | 1 - 3 files changed, 16 insertions(+), 33 deletions(-) diff --git a/frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.html b/frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.html index d2c17c901a89..8944b6e6a59d 100644 --- a/frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.html +++ b/frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.html @@ -2,7 +2,6 @@ [opened]="opened" (closed)="opened = false" class="op-exclusion-info" - alignment="bottom-end" > - +
-
- Status excluded from hierarchy totals +
+
Status excluded from hierarchy totals
+
-
+
The status 'Rejected (TODO: replace me)' has been configured to be excluded from hierarchy totals of Work, Remaining work, and % Complete. The totals do not take this value into account.
-
- +
+
+ +
diff --git a/frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.sass b/frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.sass index 424f99422588..ae629081de13 100644 --- a/frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.sass +++ b/frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.sass @@ -12,28 +12,10 @@ @media screen and (min-width: $breakpoint-lg) &--modal - width: 200px + width: 240px &--modal - color: var(--fgColor-default) - display: flex - flex-direction: column - font-family: var(--body-font-family) - gap: 1rem - margin: 1.5rem + margin: 0.5rem - &-header - font-size: 14px + & .spot-drop-modal--header-title line-height: 20px - font-weight: 600 - - &-content - font-size: 14px - line-height: 20px - - &-buttons - display: flex - flex-direction: row - - & button - margin: 0 diff --git a/frontend/src/app/spot/styles/sass/components/action-bar.sass b/frontend/src/app/spot/styles/sass/components/action-bar.sass index 89f88adc337b..c3cd906dbb60 100644 --- a/frontend/src/app/spot/styles/sass/components/action-bar.sass +++ b/frontend/src/app/spot/styles/sass/components/action-bar.sass @@ -16,7 +16,6 @@ flex-wrap: wrap align-items: center justify-content: flex-end - margin-top: -$spot-spacing-0_25 > .spot-action-bar--action // We need to set the margins on the buttons itself because From 4933b449f517761e1174e2b6d9d798ecce0c00b1 Mon Sep 17 00:00:00 2001 From: Christophe Bliard Date: Thu, 30 May 2024 12:31:03 +0200 Subject: [PATCH 047/176] Fix floating modal position --- .../fields/display/info/op-exclusion-info.component.ts | 3 +++ .../app/spot/components/drop-modal/drop-modal.component.ts | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.ts b/frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.ts index 03a39dcacfcf..e126e548ef46 100644 --- a/frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.ts +++ b/frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.ts @@ -30,6 +30,7 @@ import { ChangeDetectionStrategy, + ChangeDetectorRef, Component, } from '@angular/core'; import { I18nService } from 'core-app/core/i18n/i18n.service'; @@ -45,10 +46,12 @@ export class OpExclusionInfoComponent { constructor( readonly I18n:I18nService, + readonly cdRef:ChangeDetectorRef, ) {} public toggleOpen(event:Event):void { event.stopPropagation(); this.opened = !this.opened; + this.cdRef.detectChanges(); } } diff --git a/frontend/src/app/spot/components/drop-modal/drop-modal.component.ts b/frontend/src/app/spot/components/drop-modal/drop-modal.component.ts index 44915c491f34..ffeb9b9167ba 100644 --- a/frontend/src/app/spot/components/drop-modal/drop-modal.component.ts +++ b/frontend/src/app/spot/components/drop-modal/drop-modal.component.ts @@ -207,7 +207,10 @@ export class SpotDropModalComponent implements OnDestroy { private onGlobalClick = this.close.bind(this) as () => void; ngOnDestroy():void { - this.teleportationService.clear(); + if (this.opened) { + this.teleportationService.clear(); + } + document.body.removeEventListener('click', this.onGlobalClick); document.body.removeEventListener('keydown', this.onEscape); window.removeEventListener('resize', this.onResize); From 8752302407a10fb2ff6b4326d501e0df8075b5bf Mon Sep 17 00:00:00 2001 From: as-op Date: Thu, 30 May 2024 15:45:32 +0200 Subject: [PATCH 048/176] [#54377] Embedded work package attributes in PDF export https://community.openproject.org/work_packages/54377 --- Gemfile | 2 + Gemfile.lock | 1 + app/models/exports/formatters/custom_field.rb | 2 +- .../projects/exports/formatters/active.rb | 42 +++++ .../projects/exports/formatters/public.rb | 42 +++++ .../work_package/exports/macros/attributes.rb | 168 ++++++++++++++++++ .../work_package/pdf_export/markdown_field.rb | 48 ++++- .../pdf_export/work_package_detail.rb | 2 +- config/initializers/export_formats.rb | 2 + .../pdf_export/work_package_to_pdf_spec.rb | 152 ++++++++++++++-- 10 files changed, 442 insertions(+), 19 deletions(-) create mode 100644 app/models/projects/exports/formatters/active.rb create mode 100644 app/models/projects/exports/formatters/public.rb create mode 100644 app/models/work_package/exports/macros/attributes.rb diff --git a/Gemfile b/Gemfile index ca1db68f251a..9882d01a33d2 100644 --- a/Gemfile +++ b/Gemfile @@ -157,9 +157,11 @@ gem "structured_warnings", "~> 0.4.0" # don't require by default, instead load on-demand when actually configured gem "airbrake", "~> 13.0.0", require: false +gem "markly", "~> 0.10" gem "md_to_pdf", git: "https://github.com/opf/md-to-pdf", ref: "8f14736a88ad0064d2a97be108fe7061ffbcee91" gem "prawn", "~> 2.4" gem "ttfunk", "~> 1.7.0" # remove after https://github.com/prawnpdf/prawn/issues/1346 resolved. + # prawn implicitly depends on matrix gem no longer in ruby core with 3.1 gem "matrix", "~> 0.4.2" diff --git a/Gemfile.lock b/Gemfile.lock index fac96af70f9a..d8c3ea81140e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1233,6 +1233,7 @@ DEPENDENCIES lograge (~> 0.14.0) lookbook (~> 2.3.0) mail (= 2.8.1) + markly (~> 0.10) matrix (~> 0.4.2) md_to_pdf! meta-tags (~> 2.21.0) diff --git a/app/models/exports/formatters/custom_field.rb b/app/models/exports/formatters/custom_field.rb index 5815fb2a18ff..045b197bb9f2 100644 --- a/app/models/exports/formatters/custom_field.rb +++ b/app/models/exports/formatters/custom_field.rb @@ -24,7 +24,7 @@ def format_for_export(object, custom_field) case custom_field.field_format when "bool" value = object.typed_custom_value_for(custom_field) - value == nil ? false : value + value ? I18n.t(:general_text_Yes) : I18n.t(:general_text_No) when "text" object.typed_custom_value_for(custom_field) else diff --git a/app/models/projects/exports/formatters/active.rb b/app/models/projects/exports/formatters/active.rb new file mode 100644 index 000000000000..81980c07a751 --- /dev/null +++ b/app/models/projects/exports/formatters/active.rb @@ -0,0 +1,42 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2012-2024 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ +module Projects::Exports + module Formatters + class Active < ::Exports::Formatters::Default + def self.apply?(attribute, export_format) + export_format == :pdf && %i[active].include?(attribute.to_sym) + end + + ## + # Takes a project and returns the localized status code + def format(project, **) + project.active ? I18n.t(:general_text_Yes) : I18n.t(:general_text_No) + end + end + end +end diff --git a/app/models/projects/exports/formatters/public.rb b/app/models/projects/exports/formatters/public.rb new file mode 100644 index 000000000000..40a6e85d1f0f --- /dev/null +++ b/app/models/projects/exports/formatters/public.rb @@ -0,0 +1,42 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2012-2024 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ +module Projects::Exports + module Formatters + class Public < ::Exports::Formatters::Default + def self.apply?(attribute, export_format) + export_format == :pdf && %i[public].include?(attribute.to_sym) + end + + ## + # Takes a project and returns the localized status code + def format(project, **) + project.active ? I18n.t(:general_text_Yes) : I18n.t(:general_text_No) + end + end + end +end diff --git a/app/models/work_package/exports/macros/attributes.rb b/app/models/work_package/exports/macros/attributes.rb new file mode 100644 index 000000000000..6ce70aee38a2 --- /dev/null +++ b/app/models/work_package/exports/macros/attributes.rb @@ -0,0 +1,168 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2012-2024 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ +module WorkPackage::Exports + module Macros + # OpenProject attribute macros syntax + # Examples: + # workPackageLabel:1234:subject # Outputs work package label attribute "Subject" + help text + # workPackageValue:1234:subject # Outputs the actual subject of #1234 + # + # projectLabel:statusExplanation # Outputs current project label attribute "Status description" + help text + # projectValue:statusExplanation # Outputs current project value for "Status description" + class Attributes < OpenProject::TextFormatting::Matchers::RegexMatcher + DISABLED_PROJECT_RICH_TEXT_FIELDS = %i[description status_explanation status_description].freeze + DISABLED_WORK_PACKAGE_RICH_TEXT_FIELDS = %i[description].freeze + + def self.regexp + %r{ + (\w+)(Label|Value) # The model type we try to reference + (?::(?:([^"\s]+)|"([^"]+)"))? # Optional: An ID or subject reference + (?::([^"\s.]+|"([^".]+)")) # The attribute name we're trying to reference + }x + end + + ## + # Faster inclusion check before the regex is being applied + def self.applicable?(content) + content.include?("Label:") || content.include?("Value:") + end + + def self.process_match(match, _matched_string, context) + context => { user:, work_package: } + type = match[2].downcase + model_s = match[1] + id = match[4] || match[3] + attribute = match[6] || match[5] + resolve_match(type, model_s, id, attribute, work_package, user) + end + + def self.resolve_match(type, model_s, id, attribute, work_package, user) + if model_s == "workPackage" + resolve_work_package_match(id || work_package.id, type, attribute, user) + elsif model_s == "project" + resolve_project_match(id || work_package.project.id, type, attribute, user) + else + "[Error: Invalid attribute macro: #{model_s}]" + end + end + + def self.resolve_label_work_package(attribute) + resolve_label(WorkPackage, attribute) + end + + def self.resolve_label_project(attribute) + resolve_label(Project, attribute) + end + + def self.resolve_label(model, attribute) + model.human_attribute_name( + ::API::Utilities::PropertyNameConverter.to_ar_name(attribute.to_sym, context: model.new) + ) + end + + def self.resolve_work_package_match(id, type, attribute, user) + return resolve_label_work_package(attribute) if type == "label" + return "[Error: Invalid attribute macro: #{type}]" unless type == "value" + + work_package = WorkPackage.find_by(id:) + if work_package.nil? || !user.allowed_in_project?(:view_work_packages, work_package.project) + return "[Error: #{WorkPackage.name} #{id} not found}]" + end + + resolve_value_work_package(work_package, attribute) + end + + def self.resolve_project_match(id, type, attribute, user) + return resolve_label_project(attribute) if type == "label" + return "[Error: Invalid attribute macro: #{type}]" unless type == "value" + + project = Project.find_by(id:) + if project.nil? || !user.allowed_in_project?(:view_project, project) + return "[Error: #{Project.name} #{id} not found}]" + end + + resolve_value_project(project, attribute) + end + + def self.escape_tags(value) + # only disable html tags, but do not replace html entities + value.to_s.gsub("<", "<").gsub(">", ">") + end + + def self.resolve_value_project(project, attribute) + cf = CustomField.find_by(name: attribute, type: "ProjectCustomField") + if cf.nil? + ar_name = ::API::Utilities::PropertyNameConverter.to_ar_name(attribute.to_sym, context: project) + else + ar_name = "cf_#{cf.id}" + # currently we do not support embedding rich text fields: long text custom fields + return "[Rich text embedding currently not supported in export]" if cf.formattable? + + # TODO: Is the user allowed to see this custom field/"project attribute"? + end + + # currently we do not support embedding rich text field: e.g. projectValue:1234:description + if DISABLED_PROJECT_RICH_TEXT_FIELDS.include?(ar_name.to_sym) + return "[Rich text embedding currently not supported in export]" + + end + + format_attribute_value(ar_name, Project, project) + end + + def self.resolve_value_work_package(work_package, attribute) + cf = CustomField.find_by(name: attribute, type: "WorkPackageCustomField") + if cf.nil? + ar_name = ::API::Utilities::PropertyNameConverter.to_ar_name(attribute.to_sym, context: work_package) + else + ar_name = "cf_#{cf.id}" + # currently we do not support embedding rich text fields: long text custom fields + return "[Rich text embedding currently not supported in export]" if cf.formattable? + + # TODO: Are there access restrictions on work_package custom fields? + end + + # currently we do not support embedding rich text field: workPackageValue:1234:description + if DISABLED_WORK_PACKAGE_RICH_TEXT_FIELDS.include?(ar_name.to_sym) + return "[Rich text embedding currently not supported in export]" + + end + + format_attribute_value(ar_name, WorkPackage, work_package) + end + + def self.format_attribute_value(ar_name, model, obj) + formatter = Exports::Register.formatter_for(model, ar_name, :pdf) + value = formatter.format(obj) + # important NOT to return empty string as this could change meaning of markdown + # e.g. **to_be_replaced** could be rendered as **** (horizontal line and a *) + value.blank? ? " " : escape_tags(value) + end + end + end +end diff --git a/app/models/work_package/pdf_export/markdown_field.rb b/app/models/work_package/pdf_export/markdown_field.rb index 963396d30067..b3a6447b8a94 100644 --- a/app/models/work_package/pdf_export/markdown_field.rb +++ b/app/models/work_package/pdf_export/markdown_field.rb @@ -28,6 +28,7 @@ module WorkPackage::PDFExport::MarkdownField include WorkPackage::PDFExport::Markdown + PREFORMATTED_BLOCKS = %w(pre code).freeze def write_markdown_field!(work_package, markdown, label) return if markdown.blank? @@ -37,7 +38,52 @@ def write_markdown_field!(work_package, markdown, label) pdf.formatted_text([styles.wp_markdown_label.merge({ text: label })]) end with_margin(styles.wp_markdown_margins) do - write_markdown! work_package, markdown + write_markdown! work_package, apply_markdown_field_macros(markdown) + end + end + + private + + def apply_markdown_field_macros(markdown) + apply_macros(markdown, WorkPackage::Exports::Macros::Attributes) + end + + def apply_macros(markdown, formatter) + return markdown unless formatter.applicable?(markdown) + + document = Markly.parse(markdown) + document.walk do |node| + if node.type == :html + node.string_content = apply_macro_html(node.string_content, work_package, formatter) + elsif node.type == :text + node.string_content = apply_macro_text(node.string_content, work_package, formatter) + end + end + document.to_markdown + end + + def apply_macro_text(text, work_package, formatter) + return text unless formatter.applicable?(text) + + text.gsub!(formatter.regexp) do |matched_string| + matchdata = Regexp.last_match + formatter.process_match(matchdata, matched_string, { user: User.current, work_package: }) + end + end + + def apply_macro_html(html, work_package, formatter) + return html unless formatter.applicable?(html) + + doc = Nokogiri::HTML.fragment(html) + apply_macro_html_node(doc, work_package, formatter) + doc.to_html + end + + def apply_macro_html_node(node, work_package, formatter) + if node.text? + node.content = apply_macro_text(node.content, work_package, formatter) + elsif PREFORMATTED_BLOCKS.exclude?(node.name) + node.children.each { |child| apply_macro_html_node(child, work_package, formatter) } end end end diff --git a/app/models/work_package/pdf_export/work_package_detail.rb b/app/models/work_package/pdf_export/work_package_detail.rb index 2d4aae33e8e7..2f575c12bdc6 100644 --- a/app/models/work_package/pdf_export/work_package_detail.rb +++ b/app/models/work_package/pdf_export/work_package_detail.rb @@ -143,7 +143,7 @@ def form_key_to_column_entries(form_key, work_package) return [] unless cf.is_for_all? || work_package.project.work_package_custom_field_ids.include?(cf.id) - return [{ label: cf.name || form_key, name: form_key }] + return [{ label: cf.name || form_key, name: form_key.to_s.sub("custom_field_", "cf_") }] end if form_key == :date diff --git a/config/initializers/export_formats.rb b/config/initializers/export_formats.rb index f95759cdf163..26f2092b4128 100644 --- a/config/initializers/export_formats.rb +++ b/config/initializers/export_formats.rb @@ -20,6 +20,8 @@ formatter Project, Exports::Formatters::CustomField formatter Project, Projects::Exports::Formatters::Status formatter Project, Projects::Exports::Formatters::Description + formatter Project, Projects::Exports::Formatters::Public + formatter Project, Projects::Exports::Formatters::Active end end end diff --git a/spec/models/work_packages/pdf_export/work_package_to_pdf_spec.rb b/spec/models/work_packages/pdf_export/work_package_to_pdf_spec.rb index f6fd8f60c8db..4491fbbd77e7 100644 --- a/spec/models/work_packages/pdf_export/work_package_to_pdf_spec.rb +++ b/spec/models/work_packages/pdf_export/work_package_to_pdf_spec.rb @@ -36,10 +36,17 @@ t.attribute_groups.first.attributes.push(cf_disabled_in_project.attribute_name, cf_long_text.attribute_name) end end + let(:parent_project) do + create(:project, name: "Parent project") + end let(:project) do create(:project, name: "Foo Bla. Report No. 4/2021 with/for Case 42", types: [type], + public: true, + status_code: "on_track", + active: true, + parent: parent_project, work_package_custom_fields: [cf_long_text, cf_disabled_in_project, cf_global_bool], work_package_custom_field_ids: [cf_long_text.id, cf_global_bool.id]) # cf_disabled_in_project.id is disabled end @@ -47,11 +54,15 @@ create(:user, member_with_permissions: { project => %w[view_work_packages export_work_packages] }) end + let(:category) { create(:category, project:, name: "Demo") } + let(:version) { create(:version, project:) } let(:export_time) { DateTime.new(2023, 6, 30, 23, 59) } let(:export_time_formatted) { format_time(export_time, true) } let(:image_path) { Rails.root.join("spec/fixtures/files/image.png") } + let(:priority) { create(:priority_normal) } let(:image_attachment) { Attachment.new author: user, file: File.open(image_path) } let(:attachments) { [image_attachment] } + let(:cf_long_text_description) { "foo" } let(:cf_long_text) { create(:issue_custom_field, :text, name: "LongText") } let!(:cf_disabled_in_project) do # NOT enabled by project.work_package_custom_field_ids => NOT in PDF @@ -65,8 +76,11 @@ default_value: true ) end - let(:work_package) do - description = <<~DESCRIPTION + let(:status) { create(:status, name: "random", is_default: true) } + let!(:parent_work_package) { create(:work_package, type:, subject: "Parent wp") } + + let(:description) do + <<~DESCRIPTION **Lorem** _ipsum_ ~~dolor~~ `sit` [amet](https://example.com/), consetetur sadipscing elitr. @OpenProject Admin ![](/api/v3/attachments/#{image_attachment.id}/content) @@ -80,14 +94,32 @@

Foo

DESCRIPTION + end + let(:work_package) do create(:work_package, + id: 1, project:, type:, subject: "Work package 1", + start_date: "2024-05-30", + due_date: "2024-05-30", + created_at: export_time, + updated_at: export_time, + author: user, + assigned_to: user, + responsible: user, story_points: 1, + estimated_hours: 10, + done_ratio: 25, + remaining_hours: 9, + parent: parent_work_package, + priority:, + version:, + status:, + category:, description:, custom_values: { - cf_long_text.id => "foo", + cf_long_text.id => cf_long_text_description, cf_disabled_in_project.id => "6.25", cf_global_bool.id => true }).tap do |wp| @@ -109,6 +141,15 @@ export.export! end end + let(:expected_details) do + exporter.send(:attributes_data_by_wp, work_package) + .flat_map do |item| + value = get_column_value(item[:name]) + result = [item[:label].upcase] + result << value if value.present? + result + end + end def get_column_value(column_name) formatter = Exports::Register.formatter_for(WorkPackage, column_name, :pdf) @@ -126,18 +167,10 @@ def get_column_value(column_name) describe "with a request for a PDF" do it "contains correct data" do - details = exporter.send(:attributes_data_by_wp, work_package) - .flat_map do |item| - value = get_column_value(item[:name]) - result = [item[:label].upcase] - result << value if value.present? - result - end - # Joining the results for comparison since word wrapping leads to a different array for the same content - result = pdf[:strings].join(" ") + result = pdf[:strings] expected_result = [ "#{type.name} ##{work_package.id} - #{work_package.subject}", - *details, + *expected_details, label_title(:description), "Lorem", " ", "ipsum", " ", "dolor", " ", "sit", " ", "amet", ", consetetur sadipscing elitr.", " ", "@OpenProject Admin", @@ -145,10 +178,97 @@ def get_column_value(column_name) "Foo", "LongText", "foo", "1", export_time_formatted, project.name - ].join(" ") - expect(result).to eq(expected_result) - expect(result).not_to include("DisabledCustomField") + ].flatten + # Joining the results for comparison since word wrapping leads to a different array for the same content + expect(result.join(" ")).to eq(expected_result.join(" ")) + expect(result.join(" ")).not_to include("DisabledCustomField") expect(pdf[:images].length).to eq(2) end + + describe "with embedded attributes" do + let(:supported_work_package_embeds) do + [ + ["assignee", user.name], + ["author", user.name], + ["category", category.name], + ["createdAt", export_time_formatted], + ["updatedAt", export_time_formatted], + ["estimatedTime", "10.0 h"], + ["remainingTime", "9.0 h"], + ["version", version.name], + ["responsible", user.name], + ["dueDate", "05/30/2024"], + ["spentTime", "0.0 h"], + ["startDate", "05/30/2024"], + ["parent", "#{type.name} ##{parent_work_package.id}: #{parent_work_package.name}"], + ["priority", priority.name], + ["project", project.name], + ["status", status.name], + ["subject", "Work package 1"], + ["type", type.name], + ["description", "[Rich text embedding currently not supported in export]"] + ] + end + let(:supported_project_embeds) do + [ + ["active", "Yes"], + ["description", "[Rich text embedding currently not supported in export]"], + ["identifier", project.identifier], + ["name", project.name], + ["status", I18n.t("activerecord.attributes.project.status_codes.#{project.status_code}")], + ["statusExplanation", "[Rich text embedding currently not supported in export]"], + ["parent", parent_project.name], + ["public", "Yes"] + ] + end + let(:supported_work_package_embeds_table) do + supported_work_package_embeds.map do |embed| + "
" + end + end + let(:description) do + <<~DESCRIPTION + ## Work package attributes and labels +
workPackageLabel:#{embed[0]}workPackageValue:#{embed[0]}
#{supported_work_package_embeds_table}
+ DESCRIPTION + end + let(:supported_project_embeds_table) do + supported_project_embeds.map do |embed| + "projectLabel:#{embed[0]}projectValue:#{embed[0]}" + end + end + let(:cf_long_text_description) do + <<~DESCRIPTION + ## Project attributes and labels + #{supported_project_embeds_table}
+ DESCRIPTION + end + + it "contains resolved attributes and labels" do + result = pdf[:strings] + expected_result = [ + "#{type.name} ##{work_package.id} - #{work_package.subject}", + *expected_details, + label_title(:description), + "Work package attributes and labels", + supported_work_package_embeds.map do |embed| + [WorkPackage.human_attribute_name( + API::Utilities::PropertyNameConverter.to_ar_name(embed[0].to_sym, context: work_package) + ), embed[1]] + end, + "1", export_time_formatted, project.name, + "LongText", + "Project attributes and labels", + supported_project_embeds.map do |embed| + [Project.human_attribute_name( + API::Utilities::PropertyNameConverter.to_ar_name(embed[0].to_sym, context: project) + ), embed[1]] + end, + "2", export_time_formatted, project.name + ].flatten + # Joining the results for comparison since word wrapping leads to a different array for the same content + expect(result.join(" ")).to eq(expected_result.join(" ")) + end + end end end From d01ba3be1cc0ee5d373b7da63026e05343bd3a1c Mon Sep 17 00:00:00 2001 From: as-op Date: Thu, 30 May 2024 15:49:50 +0200 Subject: [PATCH 049/176] fix(lint): obey rubocop --- .../pdf_export/work_package_detail.rb | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/app/models/work_package/pdf_export/work_package_detail.rb b/app/models/work_package/pdf_export/work_package_detail.rb index 2f575c12bdc6..632ea724c8fc 100644 --- a/app/models/work_package/pdf_export/work_package_detail.rb +++ b/app/models/work_package/pdf_export/work_package_detail.rb @@ -135,15 +135,19 @@ def form_configuration_columns(work_package) end.flatten end - def form_key_to_column_entries(form_key, work_package) - if CustomField.custom_field_attribute? form_key - id = form_key.to_s.sub("custom_field_", "").to_i - cf = CustomField.find_by(id:) - return [] if cf.nil? || cf.formattable? + def form_key_custom_field_to_column_entries(form_key, work_package) + id = form_key.to_s.sub("custom_field_", "").to_i + cf = CustomField.find_by(id:) + return [] if cf.nil? || cf.formattable? + + return [] unless cf.is_for_all? || work_package.project.work_package_custom_field_ids.include?(cf.id) - return [] unless cf.is_for_all? || work_package.project.work_package_custom_field_ids.include?(cf.id) + [{ label: cf.name || form_key, name: form_key.to_s.sub("custom_field_", "cf_") }] + end - return [{ label: cf.name || form_key, name: form_key.to_s.sub("custom_field_", "cf_") }] + def form_key_to_column_entries(form_key, work_package) + if CustomField.custom_field_attribute? form_key + return form_key_custom_field_to_column_entries(form_key, work_package) end if form_key == :date From a611a7b77b468c7803caacb5eea832aaeffc6ac8 Mon Sep 17 00:00:00 2001 From: Christophe Bliard Date: Thu, 30 May 2024 18:01:19 +0200 Subject: [PATCH 050/176] Localize exclusion info modal title and content --- config/locales/js-en.yml | 8 ++++++++ .../field-types/excluded-icon-helper.service.ts | 5 +++-- .../info/op-exclusion-info.component.html | 11 +++++------ .../display/info/op-exclusion-info.component.ts | 16 +++++++++++++++- 4 files changed, 31 insertions(+), 9 deletions(-) diff --git a/config/locales/js-en.yml b/config/locales/js-en.yml index c21e4e8a6e19..ac33937f1785 100644 --- a/config/locales/js-en.yml +++ b/config/locales/js-en.yml @@ -1370,6 +1370,14 @@ en: group: "The group is now a part of %{project}. Meanwhile you can already plan with that group and assign work packages for instance." next_button: "Continue" + exclusion_info: + modal: + title: "Status excluded from hierarchy totals" + content: >- + The status '%{status_name}' has been configured to be excluded from hierarchy + totals of Work, Remaining work, and % Complete. The totals do not take + this value into account. + favorite_projects: no_results: "You have no favorite projects" no_results_subtext: "Add one or multiple projects as favorite through their overview or in a project list." diff --git a/frontend/src/app/shared/components/fields/display/field-types/excluded-icon-helper.service.ts b/frontend/src/app/shared/components/fields/display/field-types/excluded-icon-helper.service.ts index 84c818c3577f..3863215923ae 100644 --- a/frontend/src/app/shared/components/fields/display/field-types/excluded-icon-helper.service.ts +++ b/frontend/src/app/shared/components/fields/display/field-types/excluded-icon-helper.service.ts @@ -43,15 +43,16 @@ export class ExcludedIconHelperService { this.apiV3Service.statuses.id(resource.status as StatusResource).get().subscribe( (status:StatusResource) => { if (status.excludedFromTotals) { - this.addExcludedInfoIcon(element); + this.addExcludedInfoIcon(element, status.name); } }, ); } } - public addExcludedInfoIcon(element:HTMLElement):void { + public addExcludedInfoIcon(element:HTMLElement, name:string):void { const infoIcon = document.createElement('opce-exclusion-info'); + infoIcon.setAttribute('status-name', name); element.appendChild(infoIcon); } } diff --git a/frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.html b/frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.html index 8944b6e6a59d..5c55fa59999c 100644 --- a/frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.html +++ b/frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.html @@ -14,20 +14,19 @@
-
Status excluded from hierarchy totals
- +
+ {{text.modalTitle}} +
- The status 'Rejected (TODO: replace me)' has been configured to be excluded from hierarchy - totals of Work, Remaining work, and % Complete. The totals do not take - this value into account. + {{text.modalContent}}
diff --git a/frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.ts b/frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.ts index e126e548ef46..becf0144ccfa 100644 --- a/frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.ts +++ b/frontend/src/app/shared/components/fields/display/info/op-exclusion-info.component.ts @@ -32,6 +32,8 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, + Input, + OnInit, } from '@angular/core'; import { I18nService } from 'core-app/core/i18n/i18n.service'; @@ -41,14 +43,26 @@ import { I18nService } from 'core-app/core/i18n/i18n.service'; styleUrls: ['./op-exclusion-info.component.sass'], changeDetection: ChangeDetectionStrategy.OnPush, }) -export class OpExclusionInfoComponent { +export class OpExclusionInfoComponent implements OnInit { public opened = false; + @Input() public statusName:string; + + public text = { + modalTitle: this.I18n.t('js.exclusion_info.modal.title'), + modalContent: '', + buttonClose: this.I18n.t('js.button_close'), + }; + constructor( readonly I18n:I18nService, readonly cdRef:ChangeDetectorRef, ) {} + ngOnInit() { + this.text.modalContent = this.I18n.t('js.exclusion_info.modal.content', { status_name: this.statusName || '' }); + } + public toggleOpen(event:Event):void { event.stopPropagation(); this.opened = !this.opened; From 006856077baa06863dcc69346fd8e1a0cb675038 Mon Sep 17 00:00:00 2001 From: Andreas Pfohl Date: Fri, 31 May 2024 07:54:22 +0200 Subject: [PATCH 051/176] WIP[Op#54749]: Added permitted params for project attribute mapping --- app/models/permitted_params.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/models/permitted_params.rb b/app/models/permitted_params.rb index 241c79b26db5..37f61a33e889 100644 --- a/app/models/permitted_params.rb +++ b/app/models/permitted_params.rb @@ -560,9 +560,11 @@ def self.permitted_attributes { type_ids: [] } ], project_custom_field_project_mapping: %i( + id project_id custom_field_id custom_field_section_id + include_sub_projects ), query: %i( name From 461d13b89eff275760dc49923437da51e4882acb Mon Sep 17 00:00:00 2001 From: Andreas Pfohl Date: Fri, 31 May 2024 09:52:07 +0200 Subject: [PATCH 052/176] WIP[Op#54749]: Enabled creation of project attributes --- .../new_project_mapping_component.html.erb | 3 +- .../project_custom_fields_controller.rb | 11 ++++-- .../create_service.rb | 37 +++++++++++++++++++ 3 files changed, 46 insertions(+), 5 deletions(-) create mode 100644 app/services/project_custom_field_project_mappings/create_service.rb diff --git a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb index ce0f1e1750a0..d6d7f4c13ab1 100644 --- a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb +++ b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb @@ -9,7 +9,8 @@ openDirectly: false, focusDirectly: false, dropdownPosition: 'bottom', - disabledProjects: projects_with_custom_field_mapping + disabledProjects: projects_with_custom_field_mapping, + inputName: 'project_custom_field_project_mapping[project_id]' } ) diff --git a/app/controllers/admin/settings/project_custom_fields_controller.rb b/app/controllers/admin/settings/project_custom_fields_controller.rb index 00830c436d28..a4336ea29f67 100644 --- a/app/controllers/admin/settings/project_custom_fields_controller.rb +++ b/app/controllers/admin/settings/project_custom_fields_controller.rb @@ -39,7 +39,7 @@ class ProjectCustomFieldsController < ::Admin::SettingsController # rubocop:disable Rails/LexicallyScopedActionFilter before_action :set_sections, only: %i[show index edit update move drop] before_action :find_custom_field, - only: %i(show edit project_mappings unlink update destroy delete_option reorder_alphabetical move drop) + only: %i(show edit project_mappings link unlink update destroy delete_option reorder_alphabetical move drop) before_action :prepare_custom_option_position, only: %i(update create) before_action :find_custom_option, only: :delete_option before_action :project_custom_field_mappings_query, only: %i[project_mappings unlink] @@ -73,11 +73,14 @@ def project_mappings end def link - @project_mapping = ProjectCustomFieldProjectMapping.new(permitted_params.project_custom_field_project_mapping) + @project_mapping = ProjectCustomFieldProjectMapping.new( + project_id: permitted_params.project_custom_field_project_mapping["project_id"], + custom_field_id: @custom_field.id + ) create_service = ProjectCustomFieldProjectMappings::CreateService - .new(user: current_user, model: @project_mapping) - .call + .new(user: current_user) + .call(custom_field_id: @project_mapping.custom_field_id, project_id: @project_mapping.project_id) create_service.on_success { render_unlink_response(project: @project_mapping.project) } diff --git a/app/services/project_custom_field_project_mappings/create_service.rb b/app/services/project_custom_field_project_mappings/create_service.rb new file mode 100644 index 000000000000..16d8d20e0a00 --- /dev/null +++ b/app/services/project_custom_field_project_mappings/create_service.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2012-2024 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +module ProjectCustomFieldProjectMappings + class CreateService < ::BaseServices::Create + def default_contract_class + ProjectCustomFieldProjectMappings::UpdateContract + end + end +end From a836ca6e5215f9461c32af132b16d10beab0a6cc Mon Sep 17 00:00:00 2001 From: Eric Schubert Date: Fri, 31 May 2024 10:01:15 +0200 Subject: [PATCH 053/176] [#55033] harmonized github and gitlab tab headers - used op-tab-content styles - similar to files tab - removed custom style for headers - added op-tab-content--text-box style (spacing top) for empty state --- .../content/work_packages/tabs/_tab_content.sass | 3 +++ .../frontend/module/tab-header/styles/tab-header.sass | 9 --------- .../frontend/module/tab-header/tab-header.template.html | 2 +- .../frontend/module/tab-prs/tab-prs.component.html | 5 ++++- .../module/tab-header-issue/styles/tab-header-issue.sass | 7 ------- .../tab-header-issue/tab-header-issue.template.html | 2 +- .../module/tab-header-mr/styles/tab-header-mr.sass | 7 ------- .../module/tab-header-mr/tab-header-mr.template.html | 2 +- .../frontend/module/tab-issue/tab-issue.template.html | 5 ++++- .../frontend/module/tab-mrs/tab-mrs.template.html | 5 ++++- 10 files changed, 18 insertions(+), 29 deletions(-) diff --git a/frontend/src/global_styles/content/work_packages/tabs/_tab_content.sass b/frontend/src/global_styles/content/work_packages/tabs/_tab_content.sass index 36dbee861df2..483cd8af9bdd 100644 --- a/frontend/src/global_styles/content/work_packages/tabs/_tab_content.sass +++ b/frontend/src/global_styles/content/work_packages/tabs/_tab_content.sass @@ -37,6 +37,9 @@ .op-files-tab--storage-info-box:not(:last-child) margin-bottom: $spot-spacing-1 + &--text-box + margin-top: $spot-spacing-0_5 + &--header border-bottom: 1px solid #ddd padding-bottom: $spot-spacing-0_75 diff --git a/modules/github_integration/frontend/module/tab-header/styles/tab-header.sass b/modules/github_integration/frontend/module/tab-header/styles/tab-header.sass index 1f118e3a5089..3f87eb6aec16 100644 --- a/modules/github_integration/frontend/module/tab-header/styles/tab-header.sass +++ b/modules/github_integration/frontend/module/tab-header/styles/tab-header.sass @@ -27,15 +27,6 @@ */ .github-pr-header - display: flex - flex-wrap: wrap-reverse - justify-content: flex-end - - padding-bottom: 4px - border-bottom: 1px solid #ddd - - margin: 0 0 0.8rem 0 - .title flex: 1 1 auto border-bottom: 0 diff --git a/modules/github_integration/frontend/module/tab-header/tab-header.template.html b/modules/github_integration/frontend/module/tab-header/tab-header.template.html index 82a240172f72..a26ea6faee58 100644 --- a/modules/github_integration/frontend/module/tab-header/tab-header.template.html +++ b/modules/github_integration/frontend/module/tab-header/tab-header.template.html @@ -1,4 +1,4 @@ -
+

{{text.title}} diff --git a/modules/github_integration/frontend/module/tab-prs/tab-prs.component.html b/modules/github_integration/frontend/module/tab-prs/tab-prs.component.html index 1ad3aa9b9cd6..e8c9e37e551a 100644 --- a/modules/github_integration/frontend/module/tab-prs/tab-prs.component.html +++ b/modules/github_integration/frontend/module/tab-prs/tab-prs.component.html @@ -1,5 +1,8 @@ -

+

+

{{text.title}} diff --git a/modules/gitlab_integration/frontend/module/tab-header-mr/styles/tab-header-mr.sass b/modules/gitlab_integration/frontend/module/tab-header-mr/styles/tab-header-mr.sass index 1613363e759d..70a7556232e4 100644 --- a/modules/gitlab_integration/frontend/module/tab-header-mr/styles/tab-header-mr.sass +++ b/modules/gitlab_integration/frontend/module/tab-header-mr/styles/tab-header-mr.sass @@ -28,13 +28,6 @@ //++ .gitlab-mr-header - display: flex - flex-wrap: wrap-reverse - justify-content: flex-end - - border-bottom: 1px solid #ddd - background-color: var(--body-background) - .title flex: 1 1 auto border-bottom: 0 diff --git a/modules/gitlab_integration/frontend/module/tab-header-mr/tab-header-mr.template.html b/modules/gitlab_integration/frontend/module/tab-header-mr/tab-header-mr.template.html index 031b3c52a576..7ace2a84b125 100644 --- a/modules/gitlab_integration/frontend/module/tab-header-mr/tab-header-mr.template.html +++ b/modules/gitlab_integration/frontend/module/tab-header-mr/tab-header-mr.template.html @@ -1,4 +1,4 @@ -
+

{{text.title}} diff --git a/modules/gitlab_integration/frontend/module/tab-issue/tab-issue.template.html b/modules/gitlab_integration/frontend/module/tab-issue/tab-issue.template.html index ce4a51d334e8..66a824dd67df 100644 --- a/modules/gitlab_integration/frontend/module/tab-issue/tab-issue.template.html +++ b/modules/gitlab_integration/frontend/module/tab-issue/tab-issue.template.html @@ -1,5 +1,8 @@ -

+

diff --git a/modules/gitlab_integration/frontend/module/tab-mrs/tab-mrs.template.html b/modules/gitlab_integration/frontend/module/tab-mrs/tab-mrs.template.html index 43ab49c22624..8405dc814b58 100644 --- a/modules/gitlab_integration/frontend/module/tab-mrs/tab-mrs.template.html +++ b/modules/gitlab_integration/frontend/module/tab-mrs/tab-mrs.template.html @@ -1,5 +1,8 @@ -

+

From a813456589c16b669340bbe964076bb1c5f4419c Mon Sep 17 00:00:00 2001 From: Andreas Pfohl Date: Fri, 31 May 2024 14:02:15 +0200 Subject: [PATCH 054/176] WIP[Op#54749]: Fixed attribute project table rendering --- .../admin/settings/project_custom_fields_controller.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/admin/settings/project_custom_fields_controller.rb b/app/controllers/admin/settings/project_custom_fields_controller.rb index 49c34e3ccba5..67c478130c93 100644 --- a/app/controllers/admin/settings/project_custom_fields_controller.rb +++ b/app/controllers/admin/settings/project_custom_fields_controller.rb @@ -82,7 +82,7 @@ def link .new(user: current_user) .call(custom_field_id: @project_mapping.custom_field_id, project_id: @project_mapping.project_id) - create_service.on_success { render_unlink_response(project: @project_mapping.project) } + create_service.on_success { render_project_list } create_service.on_failure do update_flash_message_via_turbo_stream( @@ -99,7 +99,7 @@ def unlink .new(user: current_user, model: @project_custom_field_mapping) .call - delete_service.on_success { render_unlink_response } + delete_service.on_success { render_project_list } delete_service.on_failure do update_flash_message_via_turbo_stream( @@ -150,7 +150,7 @@ def destroy private - def render_unlink_response + def render_project_list update_via_turbo_stream( component: Settings::ProjectCustomFields::ProjectCustomFieldMapping::TableComponent.new( query: @project_custom_field_mappings_query, From 25917115cad9790e5acfd952e83c8af065813f86 Mon Sep 17 00:00:00 2001 From: Henriette Darge Date: Fri, 31 May 2024 14:17:48 +0200 Subject: [PATCH 055/176] Extract FilterButton from FilterComponent to be able to use them separately in the subheader --- app/components/_index.sass | 2 +- .../filter/filter_button_component.html.erb | 8 + .../filter/filter_button_component.rb | 41 +++++ .../filter/filter_component.html.erb | 127 +++++++++++++++ app/components/filter/filter_component.rb | 83 ++++++++++ .../{ => filter}/filters_component.sass | 9 +- app/components/filters_component.html.erb | 153 ------------------ app/components/filters_component.rb | 90 ----------- .../projects/projects_filters_component.rb | 4 +- .../common/filters_component_preview.rb | 23 --- .../filter/filter_button_component_preview.rb | 20 +++ .../filter_section_toggle.html.erb | 7 + .../filter/filters_component_preview.rb | 11 ++ .../meetings/meeting_filters_component.rb | 4 +- 14 files changed, 306 insertions(+), 276 deletions(-) create mode 100644 app/components/filter/filter_button_component.html.erb create mode 100644 app/components/filter/filter_button_component.rb create mode 100644 app/components/filter/filter_component.html.erb create mode 100644 app/components/filter/filter_component.rb rename app/components/{ => filter}/filters_component.sass (88%) delete mode 100644 app/components/filters_component.html.erb delete mode 100644 app/components/filters_component.rb delete mode 100644 lookbook/previews/open_project/common/filters_component_preview.rb create mode 100644 lookbook/previews/open_project/filter/filter_button_component_preview.rb create mode 100644 lookbook/previews/open_project/filter/filter_button_component_preview/filter_section_toggle.html.erb create mode 100644 lookbook/previews/open_project/filter/filters_component_preview.rb diff --git a/app/components/_index.sass b/app/components/_index.sass index df5d51df72f6..b4e2a24b82f4 100644 --- a/app/components/_index.sass +++ b/app/components/_index.sass @@ -2,6 +2,6 @@ @import "work_packages/share/invite_user_form_component" @import "work_packages/progress/modal_body_component" @import "open_project/common/attribute_component" -@import "filters_component" +@import "filter/filters_component" @import "projects/settings/project_custom_field_sections/index_component" @import "projects/row_component" diff --git a/app/components/filter/filter_button_component.html.erb b/app/components/filter/filter_button_component.html.erb new file mode 100644 index 000000000000..adb27dba4aa5 --- /dev/null +++ b/app/components/filter/filter_button_component.html.erb @@ -0,0 +1,8 @@ +<%= render(Primer::Beta::Button.new(scheme: :secondary, + disabled:, + data: { "filters-target": "filterFormToggle", + action: "filters#toggleDisplayFilters" }, + test_selector: "filter-component-toggle")) do |button| %> + <% button.with_trailing_visual_counter(count: filters_count) %> + <%= t(:label_filter) %> +<% end %> diff --git a/app/components/filter/filter_button_component.rb b/app/components/filter/filter_button_component.rb new file mode 100644 index 000000000000..e884b254dcb9 --- /dev/null +++ b/app/components/filter/filter_button_component.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +# -- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2010-2023 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +# ++ +module Filter + # rubocop:disable OpenProject/AddPreviewForViewComponent + class FilterButtonComponent < ApplicationComponent + # rubocop:enable OpenProject/AddPreviewForViewComponent + options :query + options :disabled + + def filters_count + @filters_count ||= query.filters.count + end + end +end diff --git a/app/components/filter/filter_component.html.erb b/app/components/filter/filter_component.html.erb new file mode 100644 index 000000000000..5507942ea86c --- /dev/null +++ b/app/components/filter/filter_component.html.erb @@ -0,0 +1,127 @@ +<%= form_tag({}, + method: :get, + class: "op-filters-form op-filters-form_top-margin #{show_filters_section? ? "-expanded" : ""}", + data: { + 'filters-target': 'filterForm', + action: 'submit->filters#sendForm:prevent' + }) do %> + <% operators_without_values = %w[* !* t w] %> +
+ + <%= t(:label_filter_plural) %> + + <% unless EnterpriseToken.allows_to?(:custom_fields_in_projects_list)%> + <%= + helpers.angular_component_tag 'op-enterprise-banner', + inputs: { + collapsible: true, + textMessage: t('ee.upsale.project_filters.description_html'), + moreInfoLink: OpenProject::Static::Links.links[:enterprise_docs][:custom_field_projects][:href], + } + %> + <% end %> +
+<% end %> diff --git a/app/components/filter/filter_component.rb b/app/components/filter/filter_component.rb new file mode 100644 index 000000000000..077f3b54dd85 --- /dev/null +++ b/app/components/filter/filter_component.rb @@ -0,0 +1,83 @@ +# frozen_string_literal: true + +# -- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2010-2023 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +# ++ +module Filter + # rubocop:disable OpenProject/AddPreviewForViewComponent + class FilterComponent < ApplicationComponent + # rubocop:enable OpenProject/AddPreviewForViewComponent + options :query + options hide_initially: false + + def show_filters_section? + !hide_initially || (params[:filters].present? && !params.key?(:hide_filters_section)) + end + + # Returns filters, active and inactive. + # In case a filter is active, the active one will be preferred over the inactive one. + def each_filter + allowed_filters.each do |filter| + active_filter = query.find_active_filter(filter.name) + additional_attributes = additional_filter_attributes(filter) + + yield active_filter.presence || filter, active_filter.present?, additional_attributes + end + end + + def allowed_filters + query + .available_filters + end + + protected + + # With this method we can pass additional options for each type of filter into the frontend. This is especially + # useful when we want to pass options for the autocompleter components. + # + # When the method is overwritten in a subclass, the subclass should call super(filter) to get the default attributes. + # + # @param filter [QueryFilter] the filter for which we want to pass additional attributes + # @return [Hash] the additional attributes for the filter, that will be yielded in the each_filter method + def additional_filter_attributes(filter) + case filter + when Queries::Filters::Shared::ProjectFilter + { + autocomplete_options: { + component: "opce-project-autocompleter", + resource: "projects", + filters: [ + { name: "active", operator: "=", values: ["t"] } + ] + } + } + else + {} + end + end + end +end diff --git a/app/components/filters_component.sass b/app/components/filter/filters_component.sass similarity index 88% rename from app/components/filters_component.sass rename to app/components/filter/filters_component.sass index b2d7bf64a8b0..6e7856e6301f 100644 --- a/app/components/filters_component.sass +++ b/app/components/filter/filters_component.sass @@ -43,10 +43,5 @@ .advanced-filters--controls margin-top: 1rem - &-header - display: flex - justify-content: space-between - margin-bottom: 1rem - - &-actions - display: flex \ No newline at end of file + &_top-margin + margin-top: 1rem diff --git a/app/components/filters_component.html.erb b/app/components/filters_component.html.erb deleted file mode 100644 index 58b2547b1357..000000000000 --- a/app/components/filters_component.html.erb +++ /dev/null @@ -1,153 +0,0 @@ -
- -
- <%= render(Primer::Beta::Button.new( - scheme: :secondary, - disabled:, - data: { 'filters-target': 'filterFormToggle', - 'action': 'filters#toggleDisplayFilters', - 'test-selector': 'filter-component-toggle' })) do %> - <%= t(:label_filter) %> - <%= render(Primer::Beta::Counter.new(count: filters_count, - round: true, - hide_if_zero: false, - scheme: :default, - test_selector: "filters-button-counter" )) %> - <% end %> -
- <% buttons.each do |button| %> - <%= button %> - <% end %> -
-
- <%= form_tag({}, - method: :get, - class: "op-filters-form", - data: { - 'filters-target': 'filterForm', - action: 'submit->filters#sendForm:prevent' - }) do %> - <% operators_without_values = %w[* !* t w] %> -
- - <%= t(:label_filter_plural) %> -
    - <% each_filter do |filter, filter_active, additional_options| %> - <% filter_boolean = filter.is_a?(Queries::Filters::Shared::BooleanFilter) %> - <% autocomplete_filter = additional_options.key?(:autocomplete_options) %> - -
  • - - <% selected_operator = filter.operator || filter.default_operator.symbol %> - <%= content_tag :div, class: "advanced-filters--filter-operator", style: filter_boolean ? 'display:none' : '' do %> - <%= select_tag :operator, - options_from_collection_for_select( - filter.available_operators, - :symbol, - :human_name, - selected_operator), - class: 'advanced-filters--select', - data: { - action: 'change->filters#setValueVisibility', - 'filters-filter-name-param': filter.name, - 'filters-target': 'operator', - 'filter-name': filter.name - } %> - <% end %> - <% value_visibility = operators_without_values.include?(selected_operator) ? 'hidden' : '' %> - <% if autocomplete_filter %> - <%= render partial: 'filters/autocomplete', - locals: { value_visibility: value_visibility, - filter: filter, - autocomplete_options: additional_options[:autocomplete_options] } %> - <% elsif filter_boolean %> - <%= render partial: 'filters/boolean', - locals: { value_visibility: value_visibility, - filter: filter } %> - <% elsif %i(list list_optional list_all).include? filter.type %> - <%= render partial: 'filters/list/input_options', - locals: { value_visibility: value_visibility, - filter: filter } %> - <% elsif [:datetime_past, :date].include? filter.type %> - <%= render partial: 'filters/date/input_options', - locals: { value_visibility: value_visibility, - filter: filter, - selected_operator: selected_operator } %> - <% else %> - <%# All other simple types %> - <%= render partial: 'filters/text', - locals: { value_visibility: value_visibility, - filter: filter } %> - <% end %> - - -
  • - <% end %> - -
  • - -
  • - - - - -
    - <%= select_tag 'add_filter_select', - options_from_collection_for_select( - allowed_filters, - :name, - :human_name, - disabled: query.filters.map(&:name) - ), - prompt: t(:actionview_instancetag_blank_option), - class: 'advanced-filters--select', - focus: "false", - 'aria-invalid': "false", - data: { - 'filters-target': 'addFilterSelect', - action: 'change->filters#addFilter:prevent' - } %> -
    -
  • -
  • - <%= submit_tag t('button_apply'), class: 'button -small -primary', name: nil %> -
  • -
- <% unless EnterpriseToken.allows_to?(:custom_fields_in_projects_list)%> - <%= - helpers.angular_component_tag 'op-enterprise-banner', - inputs: { - collapsible: true, - textMessage: t('ee.upsale.project_filters.description_html'), - moreInfoLink: OpenProject::Static::Links.links[:enterprise_docs][:custom_field_projects][:href], - } - %> - <% end %> -
- <% end %> -
diff --git a/app/components/filters_component.rb b/app/components/filters_component.rb deleted file mode 100644 index c4e4404cb8a2..000000000000 --- a/app/components/filters_component.rb +++ /dev/null @@ -1,90 +0,0 @@ -# frozen_string_literal: true - -# -- copyright -# OpenProject is an open source project management software. -# Copyright (C) 2010-2023 the OpenProject GmbH -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License version 3. -# -# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -# Copyright (C) 2006-2013 Jean-Philippe Lang -# Copyright (C) 2010-2013 the ChiliProject Team -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# 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 General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# See COPYRIGHT and LICENSE files for more details. -# ++ - -class FiltersComponent < ApplicationComponent - options :query - options :disabled - options output_format: "params" - - renders_many :buttons, lambda { |**system_arguments| - system_arguments[:ml] ||= 2 - Primer::Beta::Button.new(**system_arguments) - } - - def show_filters_section? - params[:filters].present? && !params.key?(:hide_filters_section) - end - - # Returns filters, active and inactive. - # In case a filter is active, the active one will be preferred over the inactive one. - def each_filter - allowed_filters.each do |filter| - active_filter = query.find_active_filter(filter.name) - additional_attributes = additional_filter_attributes(filter) - - yield active_filter.presence || filter, active_filter.present?, additional_attributes - end - end - - def allowed_filters - query - .available_filters - end - - def filters_count - @filters_count ||= query.filters.count - end - - protected - - # With this method we can pass additional options for each type of filter into the frontend. This is especially - # useful when we want to pass options for the autocompleter components. - # - # When the method is overwritten in a subclass, the subclass should call super(filter) to get the default attributes. - # - # @param filter [QueryFilter] the filter for which we want to pass additional attributes - # @return [Hash] the additional attributes for the filter, that will be yielded in the each_filter method - def additional_filter_attributes(filter) - case filter - when Queries::Filters::Shared::ProjectFilter - { - autocomplete_options: { - component: "opce-project-autocompleter", - resource: "projects", - filters: [ - { name: "active", operator: "=", values: ["t"] } - ] - } - } - else - {} - end - end -end diff --git a/app/components/projects/projects_filters_component.rb b/app/components/projects/projects_filters_component.rb index 450e2545aa77..e467c186dd1f 100644 --- a/app/components/projects/projects_filters_component.rb +++ b/app/components/projects/projects_filters_component.rb @@ -28,7 +28,9 @@ # See COPYRIGHT and LICENSE files for more details. # ++ -class Projects::ProjectsFiltersComponent < FiltersComponent +# rubocop:disable OpenProject/AddPreviewForViewComponent +class Projects::ProjectsFiltersComponent < Filter::FilterComponent + # rubocop:enable OpenProject/AddPreviewForViewComponent def allowed_filters super .select { |f| allowed_filter?(f) } diff --git a/lookbook/previews/open_project/common/filters_component_preview.rb b/lookbook/previews/open_project/common/filters_component_preview.rb deleted file mode 100644 index 2050984ab684..000000000000 --- a/lookbook/previews/open_project/common/filters_component_preview.rb +++ /dev/null @@ -1,23 +0,0 @@ -module OpenProject - module Common - # @logical_path OpenProject/Common - class FiltersComponentPreview < Lookbook::Preview - def default - @query = Queries::Projects::ProjectQuery.new - render(Projects::ProjectsFiltersComponent.new(query: @query)) do |component| - component.with_button( - tag: :a, - href: "", - scheme: :primary, - size: :medium, - aria: { label: I18n.t(:label_project_new) }, - data: { "test-selector": "project-new-button" } - ) do |button| - button.with_leading_visual_icon(icon: :plus) - Project.model_name.human - end - end - end - end - end -end diff --git a/lookbook/previews/open_project/filter/filter_button_component_preview.rb b/lookbook/previews/open_project/filter/filter_button_component_preview.rb new file mode 100644 index 000000000000..b16455531d6b --- /dev/null +++ b/lookbook/previews/open_project/filter/filter_button_component_preview.rb @@ -0,0 +1,20 @@ +module OpenProject + module Filter + # @logical_path OpenProject/Filter + class FilterButtonComponentPreview < Lookbook::Preview + def default + @query = Queries::Projects::ProjectQuery.new + render(::Filter::FilterButtonComponent.new(query: @query)) + end + + # @label With toggable filter section + # There is a stimulus controller, which can toggle the visibility of an FilterComponent with the help of a FilterButton. + # Just register the controller in a container around both elements. + # Unfortunately, stimulus controllers do not work in our lookbook as of now, so you will see no effect. + def filter_section_toggle + @query = Queries::Projects::ProjectQuery.new + render_with_template(locals: { query: @query }) + end + end + end +end diff --git a/lookbook/previews/open_project/filter/filter_button_component_preview/filter_section_toggle.html.erb b/lookbook/previews/open_project/filter/filter_button_component_preview/filter_section_toggle.html.erb new file mode 100644 index 000000000000..96432346e2e1 --- /dev/null +++ b/lookbook/previews/open_project/filter/filter_button_component_preview/filter_section_toggle.html.erb @@ -0,0 +1,7 @@ +
+ <%= render ::Filter::FilterButtonComponent.new(query: query) %> + <%= render Projects::ProjectsFiltersComponent.new(query: query) %> +
diff --git a/lookbook/previews/open_project/filter/filters_component_preview.rb b/lookbook/previews/open_project/filter/filters_component_preview.rb new file mode 100644 index 000000000000..13646dc4fcb7 --- /dev/null +++ b/lookbook/previews/open_project/filter/filters_component_preview.rb @@ -0,0 +1,11 @@ +module OpenProject + module Filter + # @logical_path OpenProject/Filter + class FiltersComponentPreview < Lookbook::Preview + def default + @query = Queries::Projects::ProjectQuery.new + render(Projects::ProjectsFiltersComponent.new(query: @query)) + end + end + end +end diff --git a/modules/meeting/app/components/meetings/meeting_filters_component.rb b/modules/meeting/app/components/meetings/meeting_filters_component.rb index 987425ad05db..03cef4079320 100644 --- a/modules/meeting/app/components/meetings/meeting_filters_component.rb +++ b/modules/meeting/app/components/meetings/meeting_filters_component.rb @@ -28,7 +28,9 @@ # See COPYRIGHT and LICENSE files for more details. # ++ module Meetings - class MeetingFiltersComponent < FiltersComponent + # rubocop:disable OpenProject/AddPreviewForViewComponent + class MeetingFiltersComponent < Filter::FilterComponent + # rubocop:enable OpenProject/AddPreviewForViewComponent options :project def allowed_filters From bbfd40025e796d33748a3020fcf24ad3e6e5906f Mon Sep 17 00:00:00 2001 From: Henriette Darge Date: Fri, 31 May 2024 14:20:52 +0200 Subject: [PATCH 056/176] Use new Primer::OpenProject::SubHeader component in Meetings and ProjectList and replace the outdated FilterComponent with that --- app/views/projects/index.html.erb | 37 +++++----- .../index_page_header_component.html.erb | 14 ---- .../meetings/index_page_header_component.rb | 25 ------- .../index_sub_header_component.html.erb | 27 ++++++++ .../meetings/index_sub_header_component.rb | 67 +++++++++++++++++++ .../meeting_filter_button_component.rb | 44 ++++++++++++ .../meetings/meeting_filters_component.rb | 9 --- .../meeting/app/views/meetings/index.html.erb | 3 +- 8 files changed, 161 insertions(+), 65 deletions(-) create mode 100644 modules/meeting/app/components/meetings/index_sub_header_component.html.erb create mode 100644 modules/meeting/app/components/meetings/index_sub_header_component.rb create mode 100644 modules/meeting/app/components/meetings/meeting_filter_button_component.rb diff --git a/app/views/projects/index.html.erb b/app/views/projects/index.html.erb index 37faffb8beec..2bc845af85b0 100644 --- a/app/views/projects/index.html.erb +++ b/app/views/projects/index.html.erb @@ -38,28 +38,35 @@ See COPYRIGHT and LICENSE files for more details. ) ) %> - <%= disable_extra_controls = state == :rename - render(Projects::ProjectsFiltersComponent.new(query:, disabled: disable_extra_controls)) do |component| - if current_user.allowed_globally?(:add_project) - component.with_button( - tag: :a, - href: new_project_path, - scheme: :primary, - disabled: disable_extra_controls, - size: :medium, - aria: { label: I18n.t(:label_project_new) }, - data: { 'test-selector': 'project-new-button' }) do |button| - button.with_leading_visual_icon(icon: :plus) - Project.model_name.human - end + render(Primer::OpenProject::SubHeader.new(data: { + controller: "filters", + "application-target": "dynamic", + "filters-display-filters-value": true, # TODO: show_filters_section?, + })) do |subheader| + subheader.with_filter_component do + render(Filter::FilterButtonComponent.new(query:)) + end + + subheader.with_action_button(tag: :a, + href: new_project_path, + scheme: :primary, + disabled: disable_extra_controls, + size: :medium, + aria: { label: I18n.t(:label_project_new) }, + data: { 'test-selector': 'project-new-button' }) do |button| + button.with_leading_visual_icon(icon: :plus) + Project.model_name.human + end if current_user.allowed_globally?(:add_project) + + subheader.with_bottom_pane_component(mt: 0) do + render(Projects::ProjectsFiltersComponent.new(query:, disabled: disable_extra_controls)) end end %> - <%= render Projects::TableComponent.new( query:, current_user: current_user, diff --git a/modules/meeting/app/components/meetings/index_page_header_component.html.erb b/modules/meeting/app/components/meetings/index_page_header_component.html.erb index 7c1db02b469d..9b6787bd6726 100644 --- a/modules/meeting/app/components/meetings/index_page_header_component.html.erb +++ b/modules/meeting/app/components/meetings/index_page_header_component.html.erb @@ -1,18 +1,4 @@ <%= render(Primer::OpenProject::PageHeader.new) do |header| header.with_title { page_title } header.with_breadcrumbs(breadcrumb_items) - if render_create_button? - header.with_action_button(tag: :a, - href: dynamic_path, - scheme: :primary, - mobile_icon: :plus, - mobile_label: label_text, - aria: { label: accessibility_label_text }, - title: accessibility_label_text, - id: id, - test_selector: "add-meeting-button") do |button| - button.with_leading_visual_icon(icon: :plus) - label_text - end - end end %> diff --git a/modules/meeting/app/components/meetings/index_page_header_component.rb b/modules/meeting/app/components/meetings/index_page_header_component.rb index e17a3ca8f370..6cd8a338a6f4 100644 --- a/modules/meeting/app/components/meetings/index_page_header_component.rb +++ b/modules/meeting/app/components/meetings/index_page_header_component.rb @@ -30,7 +30,6 @@ module Meetings class IndexPageHeaderComponent < ApplicationComponent - include OpPrimer::ComponentHelpers include ApplicationHelper def initialize(project: nil) @@ -38,30 +37,6 @@ def initialize(project: nil) @project = project end - def render_create_button? - if @project - User.current.allowed_in_project?(:create_meetings, @project) - else - User.current.allowed_in_any_project?(:create_meetings) - end - end - - def dynamic_path - polymorphic_path([:new, @project, :meeting]) - end - - def id - "add-meeting-button" - end - - def accessibility_label_text - I18n.t(:label_meeting_new) - end - - def label_text - I18n.t(:label_meeting) - end - def page_title I18n.t(:label_meeting_plural) end diff --git a/modules/meeting/app/components/meetings/index_sub_header_component.html.erb b/modules/meeting/app/components/meetings/index_sub_header_component.html.erb new file mode 100644 index 000000000000..2f8a63a3c773 --- /dev/null +++ b/modules/meeting/app/components/meetings/index_sub_header_component.html.erb @@ -0,0 +1,27 @@ +<%= render(Primer::OpenProject::SubHeader.new(data: { + controller: "filters", + "application-target": "dynamic", + "filters-display-filters-value": false, # TODO: show_filters_section?, + "filters-output-format-value": "json", +})) do |subheader| + subheader.with_filter_component do + render(Meetings::MeetingFilterButtonComponent.new(query: @query, project: @project)) + end + + subheader.with_action_button(tag: :a, + href: dynamic_path, + scheme: :primary, + mobile_icon: :plus, + mobile_label: label_text, + aria: { label: accessibility_label_text }, + title: accessibility_label_text, + id: id, + test_selector: "add-meeting-button") do |button| + button.with_leading_visual_icon(icon: :plus) + label_text + end if render_create_button? + + subheader.with_bottom_pane_component(mt: 0) do + render(Meetings::MeetingFiltersComponent.new(query: @query, project: @project)) + end +end %> diff --git a/modules/meeting/app/components/meetings/index_sub_header_component.rb b/modules/meeting/app/components/meetings/index_sub_header_component.rb new file mode 100644 index 000000000000..21c17659f10f --- /dev/null +++ b/modules/meeting/app/components/meetings/index_sub_header_component.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +# -- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2010-2024 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +# ++ + +module Meetings + # rubocop:disable OpenProject/AddPreviewForViewComponent + class IndexSubHeaderComponent < ApplicationComponent + # rubocop:enable OpenProject/AddPreviewForViewComponent + include ApplicationHelper + + def initialize(query:, project: nil) + super + @query = query + @project = project + end + + def render_create_button? + if @project + User.current.allowed_in_project?(:create_meetings, @project) + else + User.current.allowed_in_any_project?(:create_meetings) + end + end + + def dynamic_path + polymorphic_path([:new, @project, :meeting]) + end + + def id + "add-meeting-button" + end + + def accessibility_label_text + I18n.t(:label_meeting_new) + end + + def label_text + I18n.t(:label_meeting) + end + end +end diff --git a/modules/meeting/app/components/meetings/meeting_filter_button_component.rb b/modules/meeting/app/components/meetings/meeting_filter_button_component.rb new file mode 100644 index 000000000000..954d482d97e7 --- /dev/null +++ b/modules/meeting/app/components/meetings/meeting_filter_button_component.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +# -- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2010-2023 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +# ++ +module Meetings + # rubocop:disable OpenProject/AddPreviewForViewComponent + class MeetingFilterButtonComponent < Filter::FilterButtonComponent + # rubocop:enable OpenProject/AddPreviewForViewComponent + options :project + def filters_count + @filters_count ||= begin + count = super + count -= 1 if project.present? + + count + end + end + end +end diff --git a/modules/meeting/app/components/meetings/meeting_filters_component.rb b/modules/meeting/app/components/meetings/meeting_filters_component.rb index 03cef4079320..8c333aa7cb53 100644 --- a/modules/meeting/app/components/meetings/meeting_filters_component.rb +++ b/modules/meeting/app/components/meetings/meeting_filters_component.rb @@ -39,15 +39,6 @@ def allowed_filters .sort_by(&:human_name) end - def filters_count - @filters_count ||= begin - count = super - count -= 1 if project.present? - - count - end - end - protected def additional_filter_attributes(filter) diff --git a/modules/meeting/app/views/meetings/index.html.erb b/modules/meeting/app/views/meetings/index.html.erb index cde9cfb053f9..1f1e9233458b 100644 --- a/modules/meeting/app/views/meetings/index.html.erb +++ b/modules/meeting/app/views/meetings/index.html.erb @@ -29,8 +29,7 @@ See COPYRIGHT and LICENSE files for more details. <% html_title t(:label_meeting_plural) %> <%= render(Meetings::IndexPageHeaderComponent.new(project: @project)) %> - -<%= render(Meetings::MeetingFiltersComponent.new(query: @query, project: @project, output_format: 'json')) %> +<%= render(Meetings::IndexSubHeaderComponent.new(query: @query, project: @project)) %> <% if @meetings.empty? -%> <%= no_results_box %> From a5ce819dce8f106e1acf0e5dedd4156001f0c2c7 Mon Sep 17 00:00:00 2001 From: Christophe Bliard Date: Fri, 31 May 2024 16:23:07 +0200 Subject: [PATCH 057/176] [55318] Convert pt to pt-BR in packaged installations https://community.openproject.org/wp/55318 If the value "pt" (Portuguese) was selected in the installation wizard, the value is saved in `/etc/openproject/installer.dat`. This value is then used in the postinstall script to set `OPENPROJECT_DEFAULT_LANGUAGE`. But since work package #53374, pt has been split into pt-BR and pt-PT and the app will refuse to start with value pt. Changing the saved value to pt-BR when it's pt fixes the issue. --- packaging/addons/openproject/bin/postinstall | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packaging/addons/openproject/bin/postinstall b/packaging/addons/openproject/bin/postinstall index 403f26a16ac2..7192cf54dc93 100755 --- a/packaging/addons/openproject/bin/postinstall +++ b/packaging/addons/openproject/bin/postinstall @@ -10,6 +10,11 @@ CLI="${APP_NAME}" ${CLI} config:set OPENPROJECT_SEED_ADMIN_USER_MAIL="$(wiz_get "openproject/admin_email" || wiz_get "smtp/admin_email")" ${CLI} config:set RECOMPILE_RAILS_ASSETS="true" +# Convert language pt to pt-BR (work packages #53374 and #55318) +if [ "$(wiz_get "openproject/default_language")" = "pt" ]; then + wiz_set "openproject/default_language" "pt-BR" +fi + # Set the configured default language # Will be unset at installation postinstall before restart to ensure the setting is writable ${CLI} config:set OPENPROJECT_DEFAULT_LANGUAGE="$(wiz_get "openproject/default_language" || echo "en")" From a37eb72a40940a2a941987160be3a98c86ae421e Mon Sep 17 00:00:00 2001 From: Aaron Contreras Date: Fri, 31 May 2024 10:31:52 -0500 Subject: [PATCH 058/176] Assume next logical unit when parsing a string --- app/services/duration_converter.rb | 62 +++++++++++++++++++++++- spec/services/duration_converter_spec.rb | 10 +++- 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/app/services/duration_converter.rb b/app/services/duration_converter.rb index 921a4784c44d..6e632812a1bc 100644 --- a/app/services/duration_converter.rb +++ b/app/services/duration_converter.rb @@ -34,11 +34,71 @@ require "bigdecimal" class DurationConverter + UNIT_ABBREVIATION_MAP = { + "seconds" => "seconds", + "second" => "seconds", + "secs" => "seconds", + "sec" => "seconds", + "s" => "seconds", + "minutes" => "minutes", + "minute" => "minutes", + "mins" => "minutes", + "min" => "minutes", + "m" => "minutes", + "hours" => "hours", + "hour" => "hours", + "hrs" => "hours", + "hr" => "hours", + "h" => "hours", + "days" => "days", + "day" => "days", + "dy" => "days", + "d" => "days", + "weeks" => "weeks", + "week" => "weeks", + "wks" => "weeks", + "wk" => "weeks", + "w" => "weeks", + "months" => "months", + "mo" => "months", + "mos" => "months", + "month" => "months", + "years" => "years", + "year" => "years", + "yrs" => "years", + "yr" => "years", + "y" => "years" + }.freeze + + NEXT_UNIT_MAP = { + "years" => "months", + "months" => "weeks", + "weeks" => "days", + "days" => "hours", + "hours" => "minutes", + "minutes" => "seconds" + }.freeze + class << self def parse(duration_string) # Keep 0 values and convert the extracted duration to hours # by dividing by 3600. - ChronicDuration.parse(duration_string, keep_zero: true, default_unit: "hours", **duration_length_options) / 3600.to_f + + last_unit_in_string = duration_string.scan(/[a-zA-Z]+/) + .last + + default_unit = if last_unit_in_string + last_unit_in_string + .then { |last_unit| UNIT_ABBREVIATION_MAP[last_unit.downcase] } + .then { |last_unit| NEXT_UNIT_MAP[last_unit] } + else + "hours" + end + + ChronicDuration.parse(duration_string, + keep_zero: true, + default_unit:, + **duration_length_options) / 3600.to_f end def output(duration_in_hours) diff --git a/spec/services/duration_converter_spec.rb b/spec/services/duration_converter_spec.rb index e2346afac081..0ca04115c25a 100644 --- a/spec/services/duration_converter_spec.rb +++ b/spec/services/duration_converter_spec.rb @@ -40,9 +40,17 @@ expect(described_class.parse("5 hrs 30 mins")).to eq(5.5) end - it "assumes hours as the default unit for input" do + it "assumes hours as the default unit for input if no other units given" do expect(described_class.parse("5.75")).to eq(5.75) end + + it "assumes the next logical unit if at least one unit is given" do + expect(described_class.parse("2h 15")).to eq(2.25) + expect(described_class.parse("1d 24")).to eq(32) + expect(described_class.parse("1w 1")).to eq(48) + expect(described_class.parse("1mo 1")).to eq(200) + expect(described_class.parse("1mo 1w 1d 1h 30")).to eq(209.5) + end end describe ".output" do From deb542e30b2f99e0a6aa86a685138a04a80a43e4 Mon Sep 17 00:00:00 2001 From: Aaron Contreras Date: Fri, 31 May 2024 10:48:06 -0500 Subject: [PATCH 059/176] Remove seconds from output to prevent rounding errors --- app/services/duration_converter.rb | 21 ++++++++++++------- .../src/app/core/datetime/timezone.service.ts | 11 +++++++++- spec/services/duration_converter_spec.rb | 6 ++++-- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/app/services/duration_converter.rb b/app/services/duration_converter.rb index 6e632812a1bc..8d8a00e48936 100644 --- a/app/services/duration_converter.rb +++ b/app/services/duration_converter.rb @@ -81,12 +81,10 @@ class DurationConverter class << self def parse(duration_string) - # Keep 0 values and convert the extracted duration to hours - # by dividing by 3600. - + # Assume the next logical unit to allow users to write + # durations such as "2h 1" assuming "1" is "1 minute" last_unit_in_string = duration_string.scan(/[a-zA-Z]+/) .last - default_unit = if last_unit_in_string last_unit_in_string .then { |last_unit| UNIT_ABBREVIATION_MAP[last_unit.downcase] } @@ -104,7 +102,11 @@ def parse(duration_string) def output(duration_in_hours) return duration_in_hours if duration_in_hours.nil? - duration_in_seconds = convert_duration_to_seconds(duration_in_hours) + # Prevents rounding errors when including seconds by chopping + # off the overflow seconds and keeping the nearest minute. + seconds = ((duration_in_hours * 3600) + 30).to_i + seconds_overflow = seconds % 60 + seconds_to_the_nearest_minute = seconds - seconds_overflow # return "0 h" if parsing 0. # ChronicDuration returns nil when parsing 0. @@ -112,10 +114,15 @@ def output(duration_in_hours) # keeping zeroes, we'd format this as "0 secs". # # We want to override this behavior. - if ChronicDuration.output(duration_in_seconds, default_unit: "hours", **duration_length_options).nil? + if ChronicDuration.output(seconds_to_the_nearest_minute, + default_unit: "hours", + **duration_length_options).nil? "0h" else - ChronicDuration.output(duration_in_seconds, default_unit: "hours", format: :short, **duration_length_options) + ChronicDuration.output(seconds_to_the_nearest_minute, + default_unit: "hours", + format: :short, + **duration_length_options) end end diff --git a/frontend/src/app/core/datetime/timezone.service.ts b/frontend/src/app/core/datetime/timezone.service.ts index 64c49f5386d6..8900b7e9edc6 100644 --- a/frontend/src/app/core/datetime/timezone.service.ts +++ b/frontend/src/app/core/datetime/timezone.service.ts @@ -116,6 +116,10 @@ export class TimezoneService { ]; } + public toSeconds(durationString:string):number { + return Number(moment.duration(durationString).asSeconds().toFixed(2)); + } + public toHours(durationString:string):number { return Number(moment.duration(durationString).asHours().toFixed(2)); } @@ -153,7 +157,12 @@ export class TimezoneService { daysPerMonth: this.configurationService.daysPerMonth(), weeks: true, }):string { - return outputChronicDuration(this.toHours(durationString) * 3600, opts) || '0h'; + // Keep in sync with app/services/duration_converter#output + const seconds = this.toSeconds(durationString) + 30; + const secondsOverflow = seconds % 60; + const secondsToTheNearestMinute = seconds - secondsOverflow; + + return outputChronicDuration(secondsToTheNearestMinute, opts) || '0h'; } public formattedISODate(date:any):string { diff --git a/spec/services/duration_converter_spec.rb b/spec/services/duration_converter_spec.rb index 0ca04115c25a..ae41cc833a2f 100644 --- a/spec/services/duration_converter_spec.rb +++ b/spec/services/duration_converter_spec.rb @@ -67,9 +67,11 @@ .to eq("5h 45m") end - it "handles floating point numbers gracefully" do + it "ignores seconds and keep the nearest minute" do expect(described_class.output(0.28)) - .to eq("16m 48s") + .to eq("17m") + expect(described_class.output(2.23)) + .to eq("2h 14m") end end end From 47755d0066fbabda57da3780e3e8ea30250f122b Mon Sep 17 00:00:00 2001 From: Aaron Contreras Date: Fri, 31 May 2024 10:59:28 -0500 Subject: [PATCH 060/176] Ensure durations are properly validated --- .../working_days_and_hours_params_contract.rb | 7 +++++++ config/locales/en.yml | 3 +++ ...ing_days_and_hours_params_contract_spec.rb | 20 +++++++++++++++++++ 3 files changed, 30 insertions(+) diff --git a/app/contracts/settings/working_days_and_hours_params_contract.rb b/app/contracts/settings/working_days_and_hours_params_contract.rb index 4a347f4c9884..c6dbd9864c48 100644 --- a/app/contracts/settings/working_days_and_hours_params_contract.rb +++ b/app/contracts/settings/working_days_and_hours_params_contract.rb @@ -35,6 +35,7 @@ class WorkingDaysAndHoursParamsContract < ::ParamsContract validate :days_per_week_are_present validate :days_per_month_are_present validate :durations_are_positive_values + validate :durations_are_within_bounds validate :days_per_week_and_days_per_month_are_consistent validate :unique_job @@ -73,6 +74,12 @@ def durations_are_positive_values end end + def durations_are_within_bounds + errors.add :base, :hours_per_day_is_out_of_bounds if hours_per_day.to_i > 24 + errors.add :base, :days_per_week_is_out_of_bounds if days_per_week.to_i > 7 + errors.add :base, :days_per_month_is_out_of_bounds if days_per_month.to_i > 31 + end + def any_duration_is_negative_or_zero? !hours_per_day.to_i.positive? || !days_per_week.to_i.positive? || diff --git a/config/locales/en.yml b/config/locales/en.yml index 67418d0c2b77..d165c770e565 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1035,6 +1035,9 @@ Project attributes and sections are defined in the Date: Fri, 31 May 2024 18:41:08 +0200 Subject: [PATCH 061/176] simplify spec for unsent_reminders_before --- .../scopes/unsent_reminders_before_spec.rb | 24 ++++++------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/spec/models/notifications/scopes/unsent_reminders_before_spec.rb b/spec/models/notifications/scopes/unsent_reminders_before_spec.rb index c739b814ec49..6d72d260542d 100644 --- a/spec/models/notifications/scopes/unsent_reminders_before_spec.rb +++ b/spec/models/notifications/scopes/unsent_reminders_before_spec.rb @@ -39,7 +39,7 @@ Time.current end - let(:notification) do + let!(:notification) do create(:notification, recipient: notification_recipient, read_ian: notification_read_ian, @@ -51,50 +51,40 @@ let(:notification_created_at) { 10.minutes.ago } let(:notification_recipient) { recipient } - let!(:notifications) { notification } - - shared_examples_for "is empty" do - it "is empty" do - expect(scope) - .to be_empty - end - end - context "with a unread and not reminded notification that was created before the time and for the user" do it "returns the notification" do - expect(scope) - .to contain_exactly(notification) + expect(scope).to contain_exactly(notification) end end context "with a unread and not reminded notification that was created after the time and for the user" do let(:notification_created_at) { 10.minutes.from_now } - it_behaves_like "is empty" + it { is_expected.to be_empty } end context "with a unread and not reminded notification that was created before the time and for different user" do let(:notification_recipient) { create(:user) } - it_behaves_like "is empty" + it { is_expected.to be_empty } end context "with a unread and not reminded notification created before the time and for the user" do let(:notification_mail_reminder_sent) { nil } - it_behaves_like "is empty" + it { is_expected.to be_empty } end context "with a unread but reminded notification created before the time and for the user" do let(:notification_mail_reminder_sent) { true } - it_behaves_like "is empty" + it { is_expected.to be_empty } end context "with a read notification that was created before the time" do let(:notification_read_ian) { true } - it_behaves_like "is empty" + it { is_expected.to be_empty } end end end From 262ce01bf17b4794cfe46db409e58e7366f407db Mon Sep 17 00:00:00 2001 From: Ivan Kuchin Date: Fri, 31 May 2024 18:47:49 +0200 Subject: [PATCH 062/176] reword spec descriptions for unsent_reminders_before --- .../scopes/unsent_reminders_before_spec.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/models/notifications/scopes/unsent_reminders_before_spec.rb b/spec/models/notifications/scopes/unsent_reminders_before_spec.rb index 6d72d260542d..0c0bb450822a 100644 --- a/spec/models/notifications/scopes/unsent_reminders_before_spec.rb +++ b/spec/models/notifications/scopes/unsent_reminders_before_spec.rb @@ -51,37 +51,37 @@ let(:notification_created_at) { 10.minutes.ago } let(:notification_recipient) { recipient } - context "with a unread and not reminded notification that was created before the time and for the user" do + context "with an unread and not reminded notification that was created before the time and for the user" do it "returns the notification" do expect(scope).to contain_exactly(notification) end end - context "with a unread and not reminded notification that was created after the time and for the user" do + context "with a notification that was created after the time" do let(:notification_created_at) { 10.minutes.from_now } it { is_expected.to be_empty } end - context "with a unread and not reminded notification that was created before the time and for different user" do + context "with a notification that was created for different user" do let(:notification_recipient) { create(:user) } it { is_expected.to be_empty } end - context "with a unread and not reminded notification created before the time and for the user" do + context "with a notification reminded mark set to nil" do let(:notification_mail_reminder_sent) { nil } it { is_expected.to be_empty } end - context "with a unread but reminded notification created before the time and for the user" do + context "with a reminded notification" do let(:notification_mail_reminder_sent) { true } it { is_expected.to be_empty } end - context "with a read notification that was created before the time" do + context "with a read notification" do let(:notification_read_ian) { true } it { is_expected.to be_empty } From d7cc239a0993f663d9c48ce4aac84df08b475f4c Mon Sep 17 00:00:00 2001 From: Ivan Kuchin Date: Fri, 31 May 2024 19:09:06 +0200 Subject: [PATCH 063/176] add a test for read_ian nil in unsent_reminders_before --- .../notifications/scopes/unsent_reminders_before_spec.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/spec/models/notifications/scopes/unsent_reminders_before_spec.rb b/spec/models/notifications/scopes/unsent_reminders_before_spec.rb index 0c0bb450822a..6a9149cdb01a 100644 --- a/spec/models/notifications/scopes/unsent_reminders_before_spec.rb +++ b/spec/models/notifications/scopes/unsent_reminders_before_spec.rb @@ -81,6 +81,14 @@ it { is_expected.to be_empty } end + context "with a notification read mark set to nil" do + let(:notification_read_ian) { nil } + + it "returns the notification" do + expect(scope).to contain_exactly(notification) + end + end + context "with a read notification" do let(:notification_read_ian) { true } From fcfc97f9c42619162fba36590d86c75a0d601e6b Mon Sep 17 00:00:00 2001 From: Ivan Kuchin Date: Fri, 31 May 2024 19:10:24 +0200 Subject: [PATCH 064/176] construct read_ian condition in unsent_reminders_before not as an SQL fragment --- app/models/notifications/scopes/unsent_reminders_before.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/notifications/scopes/unsent_reminders_before.rb b/app/models/notifications/scopes/unsent_reminders_before.rb index 7fb881482109..75654bc6a456 100644 --- a/app/models/notifications/scopes/unsent_reminders_before.rb +++ b/app/models/notifications/scopes/unsent_reminders_before.rb @@ -36,7 +36,7 @@ module UnsentRemindersBefore def unsent_reminders_before(recipient:, time:) where(Notification.arel_table[:created_at].lteq(time)) .where(recipient:) - .where("read_ian IS NULL OR read_ian IS FALSE") + .where(read_ian: [false, nil]) .where(mail_reminder_sent: false) end end From bd791ee443202ea1b0b061f6d420b553c1bf89d8 Mon Sep 17 00:00:00 2001 From: Ivan Kuchin Date: Fri, 31 May 2024 19:17:37 +0200 Subject: [PATCH 065/176] exclude notifications about which user was already alerted from unsent_reminders_before --- .../scopes/unsent_reminders_before.rb | 1 + .../scopes/unsent_reminders_before_spec.rb | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/app/models/notifications/scopes/unsent_reminders_before.rb b/app/models/notifications/scopes/unsent_reminders_before.rb index 75654bc6a456..4434f0b5032a 100644 --- a/app/models/notifications/scopes/unsent_reminders_before.rb +++ b/app/models/notifications/scopes/unsent_reminders_before.rb @@ -38,6 +38,7 @@ def unsent_reminders_before(recipient:, time:) .where(recipient:) .where(read_ian: [false, nil]) .where(mail_reminder_sent: false) + .where(mail_alert_sent: [false, nil]) end end end diff --git a/spec/models/notifications/scopes/unsent_reminders_before_spec.rb b/spec/models/notifications/scopes/unsent_reminders_before_spec.rb index 6a9149cdb01a..9d84b3ab0175 100644 --- a/spec/models/notifications/scopes/unsent_reminders_before_spec.rb +++ b/spec/models/notifications/scopes/unsent_reminders_before_spec.rb @@ -44,14 +44,16 @@ recipient: notification_recipient, read_ian: notification_read_ian, mail_reminder_sent: notification_mail_reminder_sent, + mail_alert_sent: notification_mail_alert_sent, created_at: notification_created_at) end let(:notification_mail_reminder_sent) { false } + let(:notification_mail_alert_sent) { false } let(:notification_read_ian) { false } let(:notification_created_at) { 10.minutes.ago } let(:notification_recipient) { recipient } - context "with an unread and not reminded notification that was created before the time and for the user" do + context "with an unread, not alerted about and not reminded notification that was created before the time and for the user" do it "returns the notification" do expect(scope).to contain_exactly(notification) end @@ -94,5 +96,19 @@ it { is_expected.to be_empty } end + + context "with a notification alert mark set to nil" do + let(:notification_mail_alert_sent) { nil } + + it "returns the notification" do + expect(scope).to contain_exactly(notification) + end + end + + context "with a notification about which user was already alerted" do + let(:notification_mail_alert_sent) { true } + + it { is_expected.to be_empty } + end end end From 5199301dfdab7a916309cd0dd9f3cabe1df2af0a Mon Sep 17 00:00:00 2001 From: OpenProject Actions CI Date: Mon, 3 Jun 2024 03:05:19 +0000 Subject: [PATCH 066/176] update locales from crowdin [ci skip] --- config/locales/crowdin/ar.yml | 50 +++++++++---------- modules/boards/config/locales/crowdin/ar.yml | 14 +++--- .../calendar/config/locales/crowdin/ar.yml | 10 ++-- .../gantt/config/locales/crowdin/js-ar.yml | 6 +-- .../config/locales/crowdin/ar.yml | 2 +- .../config/locales/crowdin/js-ar.yml | 14 +++--- .../config/locales/crowdin/ar.yml | 28 +++++------ 7 files changed, 62 insertions(+), 62 deletions(-) diff --git a/config/locales/crowdin/ar.yml b/config/locales/crowdin/ar.yml index 8d96903520c7..cc2ae1eb7372 100644 --- a/config/locales/crowdin/ar.yml +++ b/config/locales/crowdin/ar.yml @@ -2546,7 +2546,7 @@ ar: few: "There are %{count} more work packages with notifications." many: "There are %{count} more work packages with notifications." other: "There are %{count} more work packages with notifications." - open_in_browser: "Open in browser" + open_in_browser: "فتح في المتصفح" reason: watched: "Watched" assigned: "Assigned" @@ -2613,8 +2613,8 @@ ar: mail_body_lost_password: "لتغيير كلمة المرور الخاصة بك، انقر فوق الارتباط التالي:" mail_password_change_not_possible: title: "Password change not possible" - body: "Your account at %{app_title} is connected to an external authentication provider (%{name})." - subtext: "Passwords for external account cannot be changed in the application. Please use the lost password functionality of your authentication provider." + body: "حسابك في %{app_title} متصل بمزود مصادقة خارجي (%{name})." + subtext: "لا يمكن تغيير كلمات المرور للحساب الخارجي في التطبيق. يرجى استخدام وظيفة فقدان كلمة المرور الخاصة بموفر المصادقة لديك." mail_body_register: "Welcome to %{app_title}. Please activate your account by clicking on this link:" mail_body_register_header_title: "Project member invitation email" mail_body_register_user: "Dear %{name}, " @@ -2770,7 +2770,7 @@ ar: permission_add_work_package_notes: "إضافة ملاحظات" permission_add_work_packages: "إضافة مجموعات عمل" permission_add_messages: "نشر الرسائل" - permission_add_project: "Create projects" + permission_add_project: "أنشئ مشروعات" permission_add_work_package_attachments: "إضافة مرفقات" permission_add_work_package_attachments_explanation: "Allows adding attachments without Edit work packages permission" permission_archive_project: "Archive project" @@ -2788,7 +2788,7 @@ ar: permission_commit_access: "الوصول للقراءة/الكتابة إلى المستودع (الالتزام)" permission_copy_projects: "نسخ المشاريع" permission_copy_work_packages: "انسخ مجموعات العمل" - permission_create_backup: "Create backups" + permission_create_backup: "انشيئ نسخ احتياطية" permission_delete_work_package_watchers: "حذف مراقبات" permission_delete_work_packages: "حذف مجموعات العمل" permission_delete_messages: "حذف الرسائل" @@ -2805,14 +2805,14 @@ ar: permission_edit_own_time_entries: "تحرير سجلات الوقت الخاصة" permission_edit_project: "تحرير المشروع" permission_edit_reportings: "تحرير التقرير" - permission_edit_time_entries: "Edit time logs for other users" + permission_edit_time_entries: "تحرير سجلات الوقت للمستخدمين الآخرين" permission_edit_timelines: "تحرير الجداول الزمنية" permission_edit_wiki_pages: "تحرير صفحات wiki" permission_export_work_packages: "تصدير مجموعات العمل" permission_export_wiki_pages: "تصدير صفحات wiki" permission_list_attachments: "قائمة المرفقات" - permission_log_own_time: "Log own time" - permission_log_time: "Log time for other users" + permission_log_own_time: "تسجيل الوقت الخاص بك" + permission_log_time: "تسجيل الوقت للمستخدمين الآخرين" permission_manage_forums: "إدارة منتديات" permission_manage_categories: "إدارة فئات مجموعة العمل" permission_manage_dashboards: "Manage dashboards" @@ -2892,7 +2892,7 @@ ar: project_module_news: "الأخبار" project_module_repository: "مستودع البيانات" project_module_wiki: "Wiki" - permission_header_for_project_module_work_package_tracking: "Work packages and Gantt charts" + permission_header_for_project_module_work_package_tracking: "حزم العمل ومخططات Gantt" query: attribute_and_direction: "%{attribute} (%{direction})" #possible query parameters (e.g. issue queries), @@ -2904,7 +2904,7 @@ ar: member_of_group: "مجموعة الموكل إليه" name_or_identifier: "Name or identifier" only_subproject_id: "Only subproject" - shared_with_user: "Shared with users" + shared_with_user: "مشترك مع المستخدمين" shared_with_me: "Shared with me" subproject_id: "Including subproject" repositories: @@ -2994,7 +2994,7 @@ ar: oauth_application_details_link_text: "Go to settings page" setup_documentation_details: "If you need help configuring a new file storage please check the documentation: " setup_documentation_details_link_text: "File Storages setup" - show_warning_details: "To use this file storage remember to activate the module and the specific storage in the project settings of each desired project." + show_warning_details: "لاستخدام هذا التخزين للملفات، تذكر تفعيل الوحدة والتخزين المحدد في إعدادات المشروع لكل مشروع مرغوب." subversion: existing_title: "مستودع التخريب موجود" existing_introduction: "إذا كان لديك مستودع بوابة محلية القائمة، يمكنك ربطه مع open project للوصول إليها من داخل التطبيق." @@ -3094,7 +3094,7 @@ ar: In work-based mode, % Complete is calculated from how much work is done in relation to total work. In status-based mode, each status has a % Complete value associated with it. Changing status will change % Complete. setting_work_package_properties: "خصائص مجموعة العمل" setting_work_package_startdate_is_adddate: "استخدام التاريخ الحالي كتاريخ البدء لمجموعات العمل الجديدة" - setting_work_packages_projects_export_limit: "Work packages / Projects export limit" + setting_work_packages_projects_export_limit: "حد تصدير حزم العمل / المشاريع" setting_journal_aggregation_time_minutes: "User actions aggregated within" setting_log_requesting_user: "تسجيل الدخول تسجيل دخول المستخدم واسم وعنوان البريد لجميع الطلبات" setting_login_required: "مطلوب مصادقة" @@ -3191,7 +3191,7 @@ ar: type: "Entire row by Type" priority: "Entire row by Priority" icalendar: - enable_subscriptions_text_html: Allows users with the necessary permissions to subscribe to OpenProject calendars and access work package information via an external calendar client. Note: Please read about iCalendar subscriptions to understand potential security risks before enabling this. + enable_subscriptions_text_html: يتيح للمستخدمين الذين لديهم الأذونات اللازمة الاشتراك في تقاويم OpenProject والوصول إلى معلومات حزم العمل عبر عميل تقويم خارجي. ملاحظة: يرجى قراءة اشتراكات iCalendar لفهم المخاطر الأمنية المحتملة قبل تفعيل هذه الميزة. language_name_being_default: "%{language_name} (default)" notifications: events_explanation: "Governs for which event an email is sent out. Work packages are excluded from this list as the notifications for them can be configured specifically for every user." @@ -3259,9 +3259,9 @@ ar: text_custom_field_hint_activate_per_project_and_type: > Custom fields need to be activated per work package type and per project. text_wp_status_read_only_html: > - The Enterprise edition will add these additional add-ons for work packages' statuses fields:
  • Allow to mark work packages to read-only for specific statuses
+ ستضيف النسخة المؤسسية هذه الإضافات الإضافية لحقول حالات حزم العمل:
  • السماح بوضع حزم العمل في وضع القراءة فقط لحالات محددة
text_project_custom_field_html: > - The Enterprise edition will add these additional add-ons for projects' custom fields:
  • Add custom fields for projects to your Project list to create a project portfolio view
+ ستضيف النسخة المؤسسية هذه الإضافات الإضافية للحقول المخصصة للمشاريع:
  • إضافة حقول مخصصة للمشاريع إلى قائمة مشروعك لإنشاء عرض محفظة المشاريع
text_custom_logo_instructions: > A white logo on transparent background is recommended. For best results on both, conventional and retina displays, make sure your image's dimensions are 460px by 60px. text_custom_export_logo_instructions: > @@ -3449,14 +3449,14 @@ ar: warning_user_limit_reached_admin: > Adding additional users will exceed the current limit. Please upgrade your plan to be able to ensure external users are able to access this instance. warning_user_limit_reached_instructions: > - You reached your user limit (%{current}/%{max} active users). Please contact sales@openproject.com to upgrade your Enterprise edition plan and add additional users. + لقد وصلت إلى حد المستخدمين الخاص بك (%{current}/%{max} مستخدمين نشطين). يرجى الاتصال بـ sales@openproject.com لترقية خطة النسخة المؤسسية الخاصة بك وإضافة مستخدمين إضافيين. warning_protocol_mismatch_html: > warning_bar: https_mismatch: - title: "HTTPS mode setup mismatch" + title: "عدم تطابق إعداد وضع HTTPS\n" text_html: > - Your application is running with HTTPS mode set to %{set_protocol}, but the request is an %{actual_protocol} request. This will result in errors! You will need to set the following configuration value: %{setting_value}. Please see the installation documentation on how to set this configuration. + تطبيقك يعمل بوضع HTTPS مضبوط إلى %{set_protocol}، ولكن الطلب هو طلب %{actual_protocol}. سيؤدي ذلك إلى حدوث أخطاء! ستحتاج إلى تعيين قيمة الإعداد التالية: %{setting_value}. يرجى الاطلاع على وثائق التثبيت لمعرفة كيفية تعيين هذا الإعداد. hostname_mismatch: title: "Hostname setting mismatch" text_html: > @@ -3506,8 +3506,8 @@ ar: view_description: "Can view this work package." remove: "إزالة" share: "شارك" - text_empty_search_description: "There are no users with the current filter criteria." - text_empty_search_header: "We couldn't find any matching results." + text_empty_search_description: "لا يوجد مستخدمون بالمعايير الحالية للتصفية." + text_empty_search_header: "لم نتمكن من العثور على أي نتائج مطابقة." text_empty_state_description: "The work package has not been shared with anyone yet." text_empty_state_header: "غير مشترك" text_user_limit_reached: "Adding additional users will exceed the current limit. Please contact an administrator to increase the user limit to ensure external users are able to access this work package." @@ -3517,7 +3517,7 @@ ar: warning_user_limit_reached_admin: > Adding additional users will exceed the current limit. Please upgrade your plan to be able to ensure external users are able to access this work package. warning_no_selected_user: "Please select users to share this work package with" - warning_locked_user: "The user %{user} is locked and cannot be shared with" + warning_locked_user: "المستخدم %{user} مقفل ولا يمكن مشاركته" user_details: locked: "Locked user" invited: "Invite sent. " @@ -3560,7 +3560,7 @@ ar: code_429: "Too many requests. Please try again later." code_500: "حدث خطأ داخلي." code_500_outbound_request_failure: "An outbound request to another resource has failed with status code %{status_code}." - code_500_missing_enterprise_token: "The request can not be handled due to invalid or missing Enterprise token." + code_500_missing_enterprise_token: "لا يمكن معالجة الطلب بسبب أن رمز المؤسسة غير صالح أو مفقود." not_found: work_package: "The work package you are looking for cannot be found or has been deleted." expected: @@ -3745,8 +3745,8 @@ ar: you: you link: link plugin_openproject_auth_plugins: - name: "OpenProject Auth Plugins" + name: "إضافات OpenProject Auth" description: "Integration of OmniAuth strategy providers for authentication in OpenProject." plugin_openproject_auth_saml: - name: "OmniAuth SAML / Single-Sign On" - description: "Adds the OmniAuth SAML provider to OpenProject" + name: "OmniAuth SAML / تسجيل الدخول الموحد" + description: "يضيف مزود OmniAuth SAML إلى OpenProject" diff --git a/modules/boards/config/locales/crowdin/ar.yml b/modules/boards/config/locales/crowdin/ar.yml index 85cb3a8ca23b..21ed45cdd902 100644 --- a/modules/boards/config/locales/crowdin/ar.yml +++ b/modules/boards/config/locales/crowdin/ar.yml @@ -23,17 +23,17 @@ ar: basic: Basic board_type_descriptions: basic: > - Start from scratch with a blank board. Manually add cards and columns to this board. + ابدأ من الصفر بلوحة فارغة. قم بإضافة البطاقات والأعمدة إلى هذه اللوحة يدويًا. status: > - Basic kanban style board with columns for status such as To Do, In Progress, Done. + لوحة أساسية بنمط كانبان مع أعمدة للحالة مثل: المهام، قيد التنفيذ، تم الإنجاز. assignee: > - Board with automated columns based on assigned users. Ideal for dispatching work packages. + لوحة بأعمدة تلقائية بناءً على المستخدمين المعينين. وتعتبر لوحة مثالية لتوزيع حزم العمل. version: > - Board with automated columns based on the version attribute. Ideal for planning product development. + لوحة بأعمدة تلقائية بناءً على الإصدار. و هي مثالية لتخطيط تطوير المنتجات. subproject: > - Board with automated columns for subprojects. Dragging work packages to other lists updates the (sub-)project accordingly. + لوحة بأعمدة تلقائية للمشاريع الفرعية. يؤدي سحب حزم العمل إلى قوائم أخرى إلى تحديث المشروع (أو المشروع الفرعي) وفقًا لذلك. subtasks: > - Board with automated columns for sub-elements. Dragging work packages to other lists updates the parent accordingly. + لوحة بأعمدة تلقائية للعناصر الفرعية. يؤدي سحب حزم العمل إلى قوائم أخرى إلى تحديث العنصر الرئيسي وفقًا لذلك. upsale: - teaser_text: 'Would you like to automate your workflows with Boards? Advanced boards are an Enterprise add-on. Please upgrade to a paid plan.' + teaser_text: 'هل ترغب في أتمتة سير العمل الخاص بك باستخدام اللوحات؟ اللوحات المتقدمة هي إضافة خاصة بالمؤسسات. يرجى الترقية إلى خطة مدفوعة.' upgrade: 'الترقية الآن' diff --git a/modules/calendar/config/locales/crowdin/ar.yml b/modules/calendar/config/locales/crowdin/ar.yml index ba85841ad341..2fc8832c8138 100644 --- a/modules/calendar/config/locales/crowdin/ar.yml +++ b/modules/calendar/config/locales/crowdin/ar.yml @@ -4,9 +4,9 @@ ar: name: "OpenProject Calendar" description: "Provides calendar views." label_calendar: "التقويم" - label_calendar_plural: "Calendars" - label_new_calendar: "New calendar" + label_calendar_plural: "التقويمات" + label_new_calendar: "تقويم جديد" permission_view_calendar: "View calendars" - permission_manage_calendars: "Manage calendars" - permission_share_calendars: "Subscribe to iCalendars" - project_module_calendar_view: "Calendars" + permission_manage_calendars: "إدارة التقويمات" + permission_share_calendars: "الاشتراك في iCalendar" + project_module_calendar_view: "التقويمات" diff --git a/modules/gantt/config/locales/crowdin/js-ar.yml b/modules/gantt/config/locales/crowdin/js-ar.yml index abdce33ccb58..656b1c08ba97 100644 --- a/modules/gantt/config/locales/crowdin/js-ar.yml +++ b/modules/gantt/config/locales/crowdin/js-ar.yml @@ -1,6 +1,6 @@ ar: js: queries: - all_open: 'All open' - timeline: 'Timeline' - milestones: 'Milestones' + all_open: 'كل المفتوح' + timeline: 'الخط الزمني' + milestones: 'الأحداث الرئيسية' diff --git a/modules/github_integration/config/locales/crowdin/ar.yml b/modules/github_integration/config/locales/crowdin/ar.yml index 1d9a37fda1ff..b2cf04719abd 100644 --- a/modules/github_integration/config/locales/crowdin/ar.yml +++ b/modules/github_integration/config/locales/crowdin/ar.yml @@ -24,4 +24,4 @@ ar: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" - permission_show_github_content: "Show GitHub content" + permission_show_github_content: "عرض محتوى GitHub" diff --git a/modules/github_integration/config/locales/crowdin/js-ar.yml b/modules/github_integration/config/locales/crowdin/js-ar.yml index ab342782a5a7..c1c99c6b5a24 100644 --- a/modules/github_integration/config/locales/crowdin/js-ar.yml +++ b/modules/github_integration/config/locales/crowdin/js-ar.yml @@ -40,12 +40,12 @@ ar: empty: 'There are no pull requests linked yet. Link an existing PR by using the code OP#%{wp_id} in the PR description or create a new PR.' github_actions: Actions pull_requests: - message: "Pull request #%{pr_number} %{pr_link} for %{repository_link} authored by %{github_user_link} has been %{pr_state}." - merged_message: "Pull request #%{pr_number} %{pr_link} for %{repository_link} has been %{pr_state} by %{github_user_link}." - referenced_message: "Pull request #%{pr_number} %{pr_link} for %{repository_link} authored by %{github_user_link} referenced this work package." + message: "طلب السحب #%{pr_number} %{pr_link} لمستودع %{repository_link} الذي أنشأه %{github_user_link} تم %{pr_state}." + merged_message: "طلب السحب #%{pr_number} %{pr_link} لمستودع %{repository_link} تم %{pr_state} من قبل %{github_user_link}." + referenced_message: "طلب السحب #%{pr_number} %{pr_link} لمستودع %{repository_link} الذي أنشأه %{github_user_link} أشار إلى حزمة العمل هذه." states: - opened: 'opened' + opened: 'مفتوح' closed: 'مغلق' - draft: 'drafted' - merged: 'merged' - ready_for_review: 'marked ready for review' + draft: 'تمت صياغته' + merged: 'مدمج' + ready_for_review: 'تم وضع علامة جاهز للمراجعة' diff --git a/modules/openid_connect/config/locales/crowdin/ar.yml b/modules/openid_connect/config/locales/crowdin/ar.yml index 7ad37fa0866f..f6f2f5313745 100644 --- a/modules/openid_connect/config/locales/crowdin/ar.yml +++ b/modules/openid_connect/config/locales/crowdin/ar.yml @@ -1,32 +1,32 @@ ar: plugin_openproject_openid_connect: name: "OpenProject OpenID Connect" - description: "Adds OmniAuth OpenID Connect strategy providers to OpenProject." + description: "يضيف مزودي استراتيجية OmniAuth OpenID Connect إلى OpenProject." logout_warning: > - You have been logged out. The contents of any form you submit may be lost. Please [log in]. + لقد تم تسجيل خروجك. قد يتم فقدان محتويات أي نموذج تقوم بإرساله. يرجى [تسجيل الدخول]. activemodel: attributes: openid_connect/provider: name: الاسم - display_name: Display name + display_name: اسم العرض identifier: المعرّف - secret: Secret - scope: Scope + secret: السر + scope: النطاق limit_self_registration: Limit self registration openid_connect: - menu_title: OpenID providers + menu_title: مزودو OpenID providers: - label_add_new: Add a new OpenID provider - label_edit: Edit OpenID provider %{name} - no_results_table: No providers have been defined yet. - plural: OpenID providers - singular: OpenID provider + label_add_new: إضافة مزود OpenID جديد + label_edit: تعديل موفر OpenID %{name} + no_results_table: لم يتم تعريف أى مزودين حتى الآن + plural: مزودو OpenID + singular: مزود OpenID setting_instructions: azure_deprecation_warning: > - The configured Azure app points to a deprecated API from Azure. Please create a new Azure app to ensure the functionality in future. + تطبيق Azure الذي تم إعدادة يشير إلى واجهة برمجة تطبيقات غير معتمدة من Azure. يرجي انشاء تطبيق Azure جديد لضمان عمله مستقبلا. azure_graph_api: > - Use the graph.microsoft.com userinfo endpoint to request userdata. This should be the default unless you have an older azure application. + استخدم نقطة النهاية graph.microsoft.com userinfo لطلب بيانات المستخدم. يجب أن يكون هذا هو الإختيار الافتراضي إلا إذا كان لديك تطبيق Azure قديم. azure_tenant_html: > - Set the tenant of your Azure endpoint. This will control who gets access to the OpenProject instance. For more information, please see our user guide on Azure OpenID connect. + قم بإعداد Azure Tenant الخاص بك. حيث سيتم التحكم في من بإمكانه الوصول الى نسخة OpenProject. gl. لمزيد من المعلومات يرجي الإطلاع على دليل المستخدم الخاص بنا على Azure OpenID connect. limit_self_registration: > If enabled users can only register using this provider if the self registration setting allows for it. From 6846e9674f83c6249903e9e4da63152f7d9ef4f7 Mon Sep 17 00:00:00 2001 From: OpenProject Actions CI Date: Mon, 3 Jun 2024 03:07:19 +0000 Subject: [PATCH 067/176] update locales from crowdin [ci skip] --- config/locales/crowdin/ar.yml | 50 +++++++++---------- modules/boards/config/locales/crowdin/ar.yml | 14 +++--- .../calendar/config/locales/crowdin/ar.yml | 10 ++-- .../gantt/config/locales/crowdin/js-ar.yml | 6 +-- .../config/locales/crowdin/ar.yml | 2 +- .../config/locales/crowdin/js-ar.yml | 14 +++--- .../config/locales/crowdin/ar.yml | 28 +++++------ 7 files changed, 62 insertions(+), 62 deletions(-) diff --git a/config/locales/crowdin/ar.yml b/config/locales/crowdin/ar.yml index 3d1f03a27a24..180cf188d44b 100644 --- a/config/locales/crowdin/ar.yml +++ b/config/locales/crowdin/ar.yml @@ -2530,7 +2530,7 @@ ar: few: "There are %{count} more work packages with notifications." many: "There are %{count} more work packages with notifications." other: "There are %{count} more work packages with notifications." - open_in_browser: "Open in browser" + open_in_browser: "فتح في المتصفح" reason: watched: "Watched" assigned: "Assigned" @@ -2597,8 +2597,8 @@ ar: mail_body_lost_password: "لتغيير كلمة المرور الخاصة بك، انقر فوق الارتباط التالي:" mail_password_change_not_possible: title: "Password change not possible" - body: "Your account at %{app_title} is connected to an external authentication provider (%{name})." - subtext: "Passwords for external account cannot be changed in the application. Please use the lost password functionality of your authentication provider." + body: "حسابك في %{app_title} متصل بمزود مصادقة خارجي (%{name})." + subtext: "لا يمكن تغيير كلمات المرور للحساب الخارجي في التطبيق. يرجى استخدام وظيفة فقدان كلمة المرور الخاصة بموفر المصادقة لديك." mail_body_register: "Welcome to %{app_title}. Please activate your account by clicking on this link:" mail_body_register_header_title: "Project member invitation email" mail_body_register_user: "Dear %{name}, " @@ -2754,7 +2754,7 @@ ar: permission_add_work_package_notes: "إضافة ملاحظات" permission_add_work_packages: "إضافة مجموعات عمل" permission_add_messages: "نشر الرسائل" - permission_add_project: "Create projects" + permission_add_project: "أنشئ مشروعات" permission_add_work_package_attachments: "إضافة مرفقات" permission_add_work_package_attachments_explanation: "Allows adding attachments without Edit work packages permission" permission_archive_project: "Archive project" @@ -2772,7 +2772,7 @@ ar: permission_commit_access: "الوصول للقراءة/الكتابة إلى المستودع (الالتزام)" permission_copy_projects: "نسخ المشاريع" permission_copy_work_packages: "انسخ مجموعات العمل" - permission_create_backup: "Create backups" + permission_create_backup: "انشيئ نسخ احتياطية" permission_delete_work_package_watchers: "حذف مراقبات" permission_delete_work_packages: "حذف مجموعات العمل" permission_delete_messages: "حذف الرسائل" @@ -2789,14 +2789,14 @@ ar: permission_edit_own_time_entries: "تحرير سجلات الوقت الخاصة" permission_edit_project: "تحرير المشروع" permission_edit_reportings: "تحرير التقرير" - permission_edit_time_entries: "Edit time logs for other users" + permission_edit_time_entries: "تحرير سجلات الوقت للمستخدمين الآخرين" permission_edit_timelines: "تحرير الجداول الزمنية" permission_edit_wiki_pages: "تحرير صفحات wiki" permission_export_work_packages: "تصدير مجموعات العمل" permission_export_wiki_pages: "تصدير صفحات wiki" permission_list_attachments: "قائمة المرفقات" - permission_log_own_time: "Log own time" - permission_log_time: "Log time for other users" + permission_log_own_time: "تسجيل الوقت الخاص بك" + permission_log_time: "تسجيل الوقت للمستخدمين الآخرين" permission_manage_forums: "إدارة منتديات" permission_manage_categories: "إدارة فئات مجموعة العمل" permission_manage_dashboards: "Manage dashboards" @@ -2875,7 +2875,7 @@ ar: project_module_news: "الأخبار" project_module_repository: "مستودع البيانات" project_module_wiki: "Wiki" - permission_header_for_project_module_work_package_tracking: "Work packages and Gantt charts" + permission_header_for_project_module_work_package_tracking: "حزم العمل ومخططات Gantt" query: attribute_and_direction: "%{attribute} (%{direction})" #possible query parameters (e.g. issue queries), @@ -2887,7 +2887,7 @@ ar: member_of_group: "مجموعة الموكل إليه" name_or_identifier: "Name or identifier" only_subproject_id: "Only subproject" - shared_with_user: "Shared with users" + shared_with_user: "مشترك مع المستخدمين" shared_with_me: "Shared with me" subproject_id: "Including subproject" repositories: @@ -2977,7 +2977,7 @@ ar: oauth_application_details_link_text: "Go to settings page" setup_documentation_details: "If you need help configuring a new file storage please check the documentation: " setup_documentation_details_link_text: "File Storages setup" - show_warning_details: "To use this file storage remember to activate the module and the specific storage in the project settings of each desired project." + show_warning_details: "لاستخدام هذا التخزين للملفات، تذكر تفعيل الوحدة والتخزين المحدد في إعدادات المشروع لكل مشروع مرغوب." subversion: existing_title: "مستودع التخريب موجود" existing_introduction: "إذا كان لديك مستودع بوابة محلية القائمة، يمكنك ربطه مع open project للوصول إليها من داخل التطبيق." @@ -3077,7 +3077,7 @@ ar: In work-based mode, % Complete is calculated from how much work is done in relation to total work. In status-based mode, each status has a % Complete value associated with it. Changing status will change % Complete. setting_work_package_properties: "خصائص مجموعة العمل" setting_work_package_startdate_is_adddate: "استخدام التاريخ الحالي كتاريخ البدء لمجموعات العمل الجديدة" - setting_work_packages_projects_export_limit: "Work packages / Projects export limit" + setting_work_packages_projects_export_limit: "حد تصدير حزم العمل / المشاريع" setting_journal_aggregation_time_minutes: "User actions aggregated within" setting_log_requesting_user: "تسجيل الدخول تسجيل دخول المستخدم واسم وعنوان البريد لجميع الطلبات" setting_login_required: "مطلوب مصادقة" @@ -3174,7 +3174,7 @@ ar: type: "Entire row by Type" priority: "Entire row by Priority" icalendar: - enable_subscriptions_text_html: Allows users with the necessary permissions to subscribe to OpenProject calendars and access work package information via an external calendar client. Note: Please read about iCalendar subscriptions to understand potential security risks before enabling this. + enable_subscriptions_text_html: يتيح للمستخدمين الذين لديهم الأذونات اللازمة الاشتراك في تقاويم OpenProject والوصول إلى معلومات حزم العمل عبر عميل تقويم خارجي. ملاحظة: يرجى قراءة اشتراكات iCalendar لفهم المخاطر الأمنية المحتملة قبل تفعيل هذه الميزة. language_name_being_default: "%{language_name} (default)" notifications: events_explanation: "Governs for which event an email is sent out. Work packages are excluded from this list as the notifications for them can be configured specifically for every user." @@ -3242,9 +3242,9 @@ ar: text_custom_field_hint_activate_per_project_and_type: > Custom fields need to be activated per work package type and per project. text_wp_status_read_only_html: > - The Enterprise edition will add these additional add-ons for work packages' statuses fields:
  • Allow to mark work packages to read-only for specific statuses
+ ستضيف النسخة المؤسسية هذه الإضافات الإضافية لحقول حالات حزم العمل:
  • السماح بوضع حزم العمل في وضع القراءة فقط لحالات محددة
text_project_custom_field_html: > - The Enterprise edition will add these additional add-ons for projects' custom fields:
  • Add custom fields for projects to your Project list to create a project portfolio view
+ ستضيف النسخة المؤسسية هذه الإضافات الإضافية للحقول المخصصة للمشاريع:
  • إضافة حقول مخصصة للمشاريع إلى قائمة مشروعك لإنشاء عرض محفظة المشاريع
text_custom_logo_instructions: > A white logo on transparent background is recommended. For best results on both, conventional and retina displays, make sure your image's dimensions are 460px by 60px. text_custom_export_logo_instructions: > @@ -3432,14 +3432,14 @@ ar: warning_user_limit_reached_admin: > Adding additional users will exceed the current limit. Please upgrade your plan to be able to ensure external users are able to access this instance. warning_user_limit_reached_instructions: > - You reached your user limit (%{current}/%{max} active users). Please contact sales@openproject.com to upgrade your Enterprise edition plan and add additional users. + لقد وصلت إلى حد المستخدمين الخاص بك (%{current}/%{max} مستخدمين نشطين). يرجى الاتصال بـ sales@openproject.com لترقية خطة النسخة المؤسسية الخاصة بك وإضافة مستخدمين إضافيين. warning_protocol_mismatch_html: > warning_bar: https_mismatch: - title: "HTTPS mode setup mismatch" + title: "عدم تطابق إعداد وضع HTTPS\n" text_html: > - Your application is running with HTTPS mode set to %{set_protocol}, but the request is an %{actual_protocol} request. This will result in errors! You will need to set the following configuration value: %{setting_value}. Please see the installation documentation on how to set this configuration. + تطبيقك يعمل بوضع HTTPS مضبوط إلى %{set_protocol}، ولكن الطلب هو طلب %{actual_protocol}. سيؤدي ذلك إلى حدوث أخطاء! ستحتاج إلى تعيين قيمة الإعداد التالية: %{setting_value}. يرجى الاطلاع على وثائق التثبيت لمعرفة كيفية تعيين هذا الإعداد. hostname_mismatch: title: "Hostname setting mismatch" text_html: > @@ -3489,8 +3489,8 @@ ar: view_description: "Can view this work package." remove: "إزالة" share: "شارك" - text_empty_search_description: "There are no users with the current filter criteria." - text_empty_search_header: "We couldn't find any matching results." + text_empty_search_description: "لا يوجد مستخدمون بالمعايير الحالية للتصفية." + text_empty_search_header: "لم نتمكن من العثور على أي نتائج مطابقة." text_empty_state_description: "The work package has not been shared with anyone yet." text_empty_state_header: "غير مشترك" text_user_limit_reached: "Adding additional users will exceed the current limit. Please contact an administrator to increase the user limit to ensure external users are able to access this work package." @@ -3500,7 +3500,7 @@ ar: warning_user_limit_reached_admin: > Adding additional users will exceed the current limit. Please upgrade your plan to be able to ensure external users are able to access this work package. warning_no_selected_user: "Please select users to share this work package with" - warning_locked_user: "The user %{user} is locked and cannot be shared with" + warning_locked_user: "المستخدم %{user} مقفل ولا يمكن مشاركته" user_details: locked: "Locked user" invited: "Invite sent. " @@ -3543,7 +3543,7 @@ ar: code_429: "Too many requests. Please try again later." code_500: "حدث خطأ داخلي." code_500_outbound_request_failure: "An outbound request to another resource has failed with status code %{status_code}." - code_500_missing_enterprise_token: "The request can not be handled due to invalid or missing Enterprise token." + code_500_missing_enterprise_token: "لا يمكن معالجة الطلب بسبب أن رمز المؤسسة غير صالح أو مفقود." not_found: work_package: "The work package you are looking for cannot be found or has been deleted." expected: @@ -3728,8 +3728,8 @@ ar: you: you link: link plugin_openproject_auth_plugins: - name: "OpenProject Auth Plugins" + name: "إضافات OpenProject Auth" description: "Integration of OmniAuth strategy providers for authentication in OpenProject." plugin_openproject_auth_saml: - name: "OmniAuth SAML / Single-Sign On" - description: "Adds the OmniAuth SAML provider to OpenProject" + name: "OmniAuth SAML / تسجيل الدخول الموحد" + description: "يضيف مزود OmniAuth SAML إلى OpenProject" diff --git a/modules/boards/config/locales/crowdin/ar.yml b/modules/boards/config/locales/crowdin/ar.yml index 85cb3a8ca23b..21ed45cdd902 100644 --- a/modules/boards/config/locales/crowdin/ar.yml +++ b/modules/boards/config/locales/crowdin/ar.yml @@ -23,17 +23,17 @@ ar: basic: Basic board_type_descriptions: basic: > - Start from scratch with a blank board. Manually add cards and columns to this board. + ابدأ من الصفر بلوحة فارغة. قم بإضافة البطاقات والأعمدة إلى هذه اللوحة يدويًا. status: > - Basic kanban style board with columns for status such as To Do, In Progress, Done. + لوحة أساسية بنمط كانبان مع أعمدة للحالة مثل: المهام، قيد التنفيذ، تم الإنجاز. assignee: > - Board with automated columns based on assigned users. Ideal for dispatching work packages. + لوحة بأعمدة تلقائية بناءً على المستخدمين المعينين. وتعتبر لوحة مثالية لتوزيع حزم العمل. version: > - Board with automated columns based on the version attribute. Ideal for planning product development. + لوحة بأعمدة تلقائية بناءً على الإصدار. و هي مثالية لتخطيط تطوير المنتجات. subproject: > - Board with automated columns for subprojects. Dragging work packages to other lists updates the (sub-)project accordingly. + لوحة بأعمدة تلقائية للمشاريع الفرعية. يؤدي سحب حزم العمل إلى قوائم أخرى إلى تحديث المشروع (أو المشروع الفرعي) وفقًا لذلك. subtasks: > - Board with automated columns for sub-elements. Dragging work packages to other lists updates the parent accordingly. + لوحة بأعمدة تلقائية للعناصر الفرعية. يؤدي سحب حزم العمل إلى قوائم أخرى إلى تحديث العنصر الرئيسي وفقًا لذلك. upsale: - teaser_text: 'Would you like to automate your workflows with Boards? Advanced boards are an Enterprise add-on. Please upgrade to a paid plan.' + teaser_text: 'هل ترغب في أتمتة سير العمل الخاص بك باستخدام اللوحات؟ اللوحات المتقدمة هي إضافة خاصة بالمؤسسات. يرجى الترقية إلى خطة مدفوعة.' upgrade: 'الترقية الآن' diff --git a/modules/calendar/config/locales/crowdin/ar.yml b/modules/calendar/config/locales/crowdin/ar.yml index ba85841ad341..2fc8832c8138 100644 --- a/modules/calendar/config/locales/crowdin/ar.yml +++ b/modules/calendar/config/locales/crowdin/ar.yml @@ -4,9 +4,9 @@ ar: name: "OpenProject Calendar" description: "Provides calendar views." label_calendar: "التقويم" - label_calendar_plural: "Calendars" - label_new_calendar: "New calendar" + label_calendar_plural: "التقويمات" + label_new_calendar: "تقويم جديد" permission_view_calendar: "View calendars" - permission_manage_calendars: "Manage calendars" - permission_share_calendars: "Subscribe to iCalendars" - project_module_calendar_view: "Calendars" + permission_manage_calendars: "إدارة التقويمات" + permission_share_calendars: "الاشتراك في iCalendar" + project_module_calendar_view: "التقويمات" diff --git a/modules/gantt/config/locales/crowdin/js-ar.yml b/modules/gantt/config/locales/crowdin/js-ar.yml index abdce33ccb58..656b1c08ba97 100644 --- a/modules/gantt/config/locales/crowdin/js-ar.yml +++ b/modules/gantt/config/locales/crowdin/js-ar.yml @@ -1,6 +1,6 @@ ar: js: queries: - all_open: 'All open' - timeline: 'Timeline' - milestones: 'Milestones' + all_open: 'كل المفتوح' + timeline: 'الخط الزمني' + milestones: 'الأحداث الرئيسية' diff --git a/modules/github_integration/config/locales/crowdin/ar.yml b/modules/github_integration/config/locales/crowdin/ar.yml index 1d9a37fda1ff..b2cf04719abd 100644 --- a/modules/github_integration/config/locales/crowdin/ar.yml +++ b/modules/github_integration/config/locales/crowdin/ar.yml @@ -24,4 +24,4 @@ ar: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" - permission_show_github_content: "Show GitHub content" + permission_show_github_content: "عرض محتوى GitHub" diff --git a/modules/github_integration/config/locales/crowdin/js-ar.yml b/modules/github_integration/config/locales/crowdin/js-ar.yml index ab342782a5a7..c1c99c6b5a24 100644 --- a/modules/github_integration/config/locales/crowdin/js-ar.yml +++ b/modules/github_integration/config/locales/crowdin/js-ar.yml @@ -40,12 +40,12 @@ ar: empty: 'There are no pull requests linked yet. Link an existing PR by using the code OP#%{wp_id} in the PR description or create a new PR.' github_actions: Actions pull_requests: - message: "Pull request #%{pr_number} %{pr_link} for %{repository_link} authored by %{github_user_link} has been %{pr_state}." - merged_message: "Pull request #%{pr_number} %{pr_link} for %{repository_link} has been %{pr_state} by %{github_user_link}." - referenced_message: "Pull request #%{pr_number} %{pr_link} for %{repository_link} authored by %{github_user_link} referenced this work package." + message: "طلب السحب #%{pr_number} %{pr_link} لمستودع %{repository_link} الذي أنشأه %{github_user_link} تم %{pr_state}." + merged_message: "طلب السحب #%{pr_number} %{pr_link} لمستودع %{repository_link} تم %{pr_state} من قبل %{github_user_link}." + referenced_message: "طلب السحب #%{pr_number} %{pr_link} لمستودع %{repository_link} الذي أنشأه %{github_user_link} أشار إلى حزمة العمل هذه." states: - opened: 'opened' + opened: 'مفتوح' closed: 'مغلق' - draft: 'drafted' - merged: 'merged' - ready_for_review: 'marked ready for review' + draft: 'تمت صياغته' + merged: 'مدمج' + ready_for_review: 'تم وضع علامة جاهز للمراجعة' diff --git a/modules/openid_connect/config/locales/crowdin/ar.yml b/modules/openid_connect/config/locales/crowdin/ar.yml index 7ad37fa0866f..f6f2f5313745 100644 --- a/modules/openid_connect/config/locales/crowdin/ar.yml +++ b/modules/openid_connect/config/locales/crowdin/ar.yml @@ -1,32 +1,32 @@ ar: plugin_openproject_openid_connect: name: "OpenProject OpenID Connect" - description: "Adds OmniAuth OpenID Connect strategy providers to OpenProject." + description: "يضيف مزودي استراتيجية OmniAuth OpenID Connect إلى OpenProject." logout_warning: > - You have been logged out. The contents of any form you submit may be lost. Please [log in]. + لقد تم تسجيل خروجك. قد يتم فقدان محتويات أي نموذج تقوم بإرساله. يرجى [تسجيل الدخول]. activemodel: attributes: openid_connect/provider: name: الاسم - display_name: Display name + display_name: اسم العرض identifier: المعرّف - secret: Secret - scope: Scope + secret: السر + scope: النطاق limit_self_registration: Limit self registration openid_connect: - menu_title: OpenID providers + menu_title: مزودو OpenID providers: - label_add_new: Add a new OpenID provider - label_edit: Edit OpenID provider %{name} - no_results_table: No providers have been defined yet. - plural: OpenID providers - singular: OpenID provider + label_add_new: إضافة مزود OpenID جديد + label_edit: تعديل موفر OpenID %{name} + no_results_table: لم يتم تعريف أى مزودين حتى الآن + plural: مزودو OpenID + singular: مزود OpenID setting_instructions: azure_deprecation_warning: > - The configured Azure app points to a deprecated API from Azure. Please create a new Azure app to ensure the functionality in future. + تطبيق Azure الذي تم إعدادة يشير إلى واجهة برمجة تطبيقات غير معتمدة من Azure. يرجي انشاء تطبيق Azure جديد لضمان عمله مستقبلا. azure_graph_api: > - Use the graph.microsoft.com userinfo endpoint to request userdata. This should be the default unless you have an older azure application. + استخدم نقطة النهاية graph.microsoft.com userinfo لطلب بيانات المستخدم. يجب أن يكون هذا هو الإختيار الافتراضي إلا إذا كان لديك تطبيق Azure قديم. azure_tenant_html: > - Set the tenant of your Azure endpoint. This will control who gets access to the OpenProject instance. For more information, please see our user guide on Azure OpenID connect. + قم بإعداد Azure Tenant الخاص بك. حيث سيتم التحكم في من بإمكانه الوصول الى نسخة OpenProject. gl. لمزيد من المعلومات يرجي الإطلاع على دليل المستخدم الخاص بنا على Azure OpenID connect. limit_self_registration: > If enabled users can only register using this provider if the self registration setting allows for it. From 71aa95f155f0c7b7e8edf2c7dd5641f687e88b6e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 05:28:17 +0000 Subject: [PATCH 068/176] Bump timecop from 0.9.8 to 0.9.9 Bumps [timecop](https://github.com/travisjeffery/timecop) from 0.9.8 to 0.9.9. - [Changelog](https://github.com/travisjeffery/timecop/blob/master/History.md) - [Commits](https://github.com/travisjeffery/timecop/compare/v0.9.8...v0.9.9) --- updated-dependencies: - dependency-name: timecop dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index d2e977a1d98f..7dbcd238bcbb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1081,7 +1081,7 @@ GEM text-hyphen (1.5.0) thor (1.3.1) thread_safe (0.3.6) - timecop (0.9.8) + timecop (0.9.9) timeout (0.4.1) tpm-key_attestation (0.12.0) bindata (~> 2.4) From 44fcfe9fc455310c0b138e530d6fe77c0112a662 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 05:32:29 +0000 Subject: [PATCH 069/176] Bump ffi from 1.16.3 to 1.17.0 Bumps [ffi](https://github.com/ffi/ffi) from 1.16.3 to 1.17.0. - [Changelog](https://github.com/ffi/ffi/blob/master/CHANGELOG.md) - [Commits](https://github.com/ffi/ffi/compare/v1.16.3...v1.17.0) --- updated-dependencies: - dependency-name: ffi dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index d2e977a1d98f..3d86085970b1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -529,7 +529,7 @@ GEM concurrent-ruby (~> 1.1) webrick (~> 1.7) websocket-driver (>= 0.6, < 0.8) - ffi (1.16.3) + ffi (1.17.0) flamegraph (0.9.5) fog-aws (3.22.0) fog-core (~> 2.1) From 7793ff1adb2c242379a22bb6553853249c52f1b4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 05:53:18 +0000 Subject: [PATCH 070/176] Bump @ngx-formly/core from 6.3.2 to 6.3.3 in /frontend Bumps [@ngx-formly/core](https://github.com/ngx-formly/ngx-formly) from 6.3.2 to 6.3.3. - [Release notes](https://github.com/ngx-formly/ngx-formly/releases) - [Changelog](https://github.com/ngx-formly/ngx-formly/blob/main/CHANGELOG.md) - [Commits](https://github.com/ngx-formly/ngx-formly/compare/v6.3.2...v6.3.3) --- updated-dependencies: - dependency-name: "@ngx-formly/core" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- frontend/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 607f0787cdf1..333b00af7abb 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -4079,9 +4079,9 @@ } }, "node_modules/@ngx-formly/core": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/@ngx-formly/core/-/core-6.3.2.tgz", - "integrity": "sha512-rPnPDkZp+ns6FxpFBGOJLw3p2JYbIZlM+azNlsmDly4E/WlzX4YOPJNh87nNBINH4OqU99yLURkJFIcGGa9Qcg==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@ngx-formly/core/-/core-6.3.3.tgz", + "integrity": "sha512-Dlbxzxrq5J9oNghwJnljtt/rvIeyfqwPQcCkLfsIc04yyztHl8M5cfkQtqqj2VjyEOqQb/XGjt0eQhAXz3xnNg==", "dependencies": { "tslib": "^2.0.0" }, @@ -25275,9 +25275,9 @@ "integrity": "sha512-CjSVVa/9fzMpEDQP01SC4colKCbZwj7vUq0H2bivp8jVsmd21x9Fu0gDBH0Y9NdfAIm4eGZvmiZKMII3vIOaYQ==" }, "@ngx-formly/core": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/@ngx-formly/core/-/core-6.3.2.tgz", - "integrity": "sha512-rPnPDkZp+ns6FxpFBGOJLw3p2JYbIZlM+azNlsmDly4E/WlzX4YOPJNh87nNBINH4OqU99yLURkJFIcGGa9Qcg==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@ngx-formly/core/-/core-6.3.3.tgz", + "integrity": "sha512-Dlbxzxrq5J9oNghwJnljtt/rvIeyfqwPQcCkLfsIc04yyztHl8M5cfkQtqqj2VjyEOqQb/XGjt0eQhAXz3xnNg==", "requires": { "tslib": "^2.0.0" } From 13241549fe59c494434db77f39599fd406c5f575 Mon Sep 17 00:00:00 2001 From: Henriette Darge Date: Mon, 3 Jun 2024 08:25:37 +0200 Subject: [PATCH 071/176] Remove user icon from share modal box header --- .../work_packages/share/share_counter_component.html.erb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/components/work_packages/share/share_counter_component.html.erb b/app/components/work_packages/share/share_counter_component.html.erb index 3b5b5c6f2ce4..855f37330382 100644 --- a/app/components/work_packages/share/share_counter_component.html.erb +++ b/app/components/work_packages/share/share_counter_component.html.erb @@ -1,5 +1,3 @@ <% - concat(render(Primer::Beta::Octicon.new(icon: 'person'))) - - concat(render(Primer::Beta::Text.new(ml: 2)) { I18n.t('work_package.sharing.count', count:) }) + concat(render(Primer::Beta::Text.new) { I18n.t('work_package.sharing.count', count:) }) %> From 3570301eb4df0ef90ea7732e1019873019e28363 Mon Sep 17 00:00:00 2001 From: Klaus Zanders Date: Mon, 3 Jun 2024 08:30:46 +0200 Subject: [PATCH 072/176] Fix typo in migration --- ...30731153909_add_file_link_journals_to_existing_containers.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/migrate/20230731153909_add_file_link_journals_to_existing_containers.rb b/db/migrate/20230731153909_add_file_link_journals_to_existing_containers.rb index 50c7d72dbe08..5e3ff87fd18b 100644 --- a/db/migrate/20230731153909_add_file_link_journals_to_existing_containers.rb +++ b/db/migrate/20230731153909_add_file_link_journals_to_existing_containers.rb @@ -37,7 +37,7 @@ def up next unless container.class.journaled? Journals::CreateService.new(container, system_user) - .call(cause: Jounal::CausedBySystemUpdate.new(feature: "file_links_journal")) + .call(cause: Journal::CausedBySystemUpdate.new(feature: "file_links_journal")) end end From a0bc1e93c85a4ce022fd29b95fea8e070e651d5c Mon Sep 17 00:00:00 2001 From: Klaus Zanders Date: Mon, 3 Jun 2024 08:30:46 +0200 Subject: [PATCH 073/176] Fix typo in migration --- ...30731153909_add_file_link_journals_to_existing_containers.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/migrate/20230731153909_add_file_link_journals_to_existing_containers.rb b/db/migrate/20230731153909_add_file_link_journals_to_existing_containers.rb index 50c7d72dbe08..5e3ff87fd18b 100644 --- a/db/migrate/20230731153909_add_file_link_journals_to_existing_containers.rb +++ b/db/migrate/20230731153909_add_file_link_journals_to_existing_containers.rb @@ -37,7 +37,7 @@ def up next unless container.class.journaled? Journals::CreateService.new(container, system_user) - .call(cause: Jounal::CausedBySystemUpdate.new(feature: "file_links_journal")) + .call(cause: Journal::CausedBySystemUpdate.new(feature: "file_links_journal")) end end From 95e4a2aaa6cd6562aa4a890f0f8a8507a2b9a558 Mon Sep 17 00:00:00 2001 From: Andreas Pfohl Date: Mon, 3 Jun 2024 10:32:02 +0200 Subject: [PATCH 074/176] WIP[Op#54749]: Removed id from permitted params for project custom field mappings --- app/models/permitted_params.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/models/permitted_params.rb b/app/models/permitted_params.rb index 37f61a33e889..09730a5b2579 100644 --- a/app/models/permitted_params.rb +++ b/app/models/permitted_params.rb @@ -560,7 +560,6 @@ def self.permitted_attributes { type_ids: [] } ], project_custom_field_project_mapping: %i( - id project_id custom_field_id custom_field_section_id From 0bf9a335923189e22b68ad635b40177127110fb3 Mon Sep 17 00:00:00 2001 From: Kabiru Mwenja Date: Mon, 3 Jun 2024 11:40:18 +0300 Subject: [PATCH 075/176] fix[Op#54749]: do not show new project mapping button for required custom fields --- .../project_custom_fields/project_mappings.html.erb | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/views/admin/settings/project_custom_fields/project_mappings.html.erb b/app/views/admin/settings/project_custom_fields/project_mappings.html.erb index 09193be00a59..4b34a40450e0 100644 --- a/app/views/admin/settings/project_custom_fields/project_mappings.html.erb +++ b/app/views/admin/settings/project_custom_fields/project_mappings.html.erb @@ -35,10 +35,12 @@ See COPYRIGHT and LICENSE files for more details. %> <%= - render(Settings::ProjectCustomFields::ProjectCustomFieldMapping::NewProjectMappingComponent.new( - project_mapping: @project_mapping, - project_custom_field: @custom_field - )) + unless @custom_field.required? + render(Settings::ProjectCustomFields::ProjectCustomFieldMapping::NewProjectMappingComponent.new( + project_mapping: @project_mapping, + project_custom_field: @custom_field + )) + end %> <%= From f44fd765f8d62d9643ddd4ab2ccd38dbf28d48da Mon Sep 17 00:00:00 2001 From: Kabiru Mwenja Date: Mon, 3 Jun 2024 11:53:12 +0300 Subject: [PATCH 076/176] fix[Op#54749]: disabled reason doesn't need a label right now --- .../new_project_mapping_component.html.erb | 6 +----- config/locales/en.yml | 4 ++-- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb index d6d7f4c13ab1..d8154803fb87 100644 --- a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb +++ b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb @@ -32,11 +32,7 @@ ProjectCustomFieldProjectMapping .where(project_custom_field: @project_custom_field) .pluck(:project_id) - .to_h { |id| [id, project_disabled_reason] } - end - - def project_disabled_reason - I18n.t("projects.settings.project_custom_fields.new_project_mapping_form.autocompleter_disabled_reason") + .to_h { |id| [id, id] } end end %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 845f868a6402..51cf2a69dcfa 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -334,8 +334,8 @@ Project attributes and sections are defined in the Date: Mon, 3 Jun 2024 12:02:29 +0300 Subject: [PATCH 077/176] fix[Op#54749]: reinitialize the query --- .../admin/settings/project_custom_fields_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/admin/settings/project_custom_fields_controller.rb b/app/controllers/admin/settings/project_custom_fields_controller.rb index 67c478130c93..32ecfa837cd3 100644 --- a/app/controllers/admin/settings/project_custom_fields_controller.rb +++ b/app/controllers/admin/settings/project_custom_fields_controller.rb @@ -153,7 +153,7 @@ def destroy def render_project_list update_via_turbo_stream( component: Settings::ProjectCustomFields::ProjectCustomFieldMapping::TableComponent.new( - query: @project_custom_field_mappings_query, + query: project_custom_field_mappings_query, params: { custom_field: @custom_field } ), status: :ok From 09c721a035b534f6090c37cac1aee6182a9f68a4 Mon Sep 17 00:00:00 2001 From: Kabiru Mwenja Date: Mon, 3 Jun 2024 12:10:52 +0300 Subject: [PATCH 078/176] fix[Op#54749]: enable turbo for the add project modal --- .../new_project_mapping_component.html.erb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb index d8154803fb87..6e885f207afc 100644 --- a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb +++ b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb @@ -57,6 +57,7 @@ primer_form_with( model: @project_mapping, url: link_admin_settings_project_custom_field_path(@project_custom_field), + data: { turbo: true }, method: :post ) do |form| concat(render(Primer::Alpha::Dialog::Body.new( From 2b038f43d76313efc93835a99ebccc71e073ee00 Mon Sep 17 00:00:00 2001 From: Kabiru Mwenja Date: Mon, 3 Jun 2024 12:13:14 +0300 Subject: [PATCH 079/176] chore[Op#54749]: have the component control it's own rendering state --- .../new_project_mapping_component.rb | 4 ++++ .../project_custom_fields/project_mappings.html.erb | 10 ++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.rb b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.rb index 765e1b769388..d2d86332e3fe 100644 --- a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.rb +++ b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.rb @@ -39,6 +39,10 @@ def initialize(project_mapping:, project_custom_field:, **) super(@project_mapping, **) end + def render? + !@project_custom_field.required? + end + private def title diff --git a/app/views/admin/settings/project_custom_fields/project_mappings.html.erb b/app/views/admin/settings/project_custom_fields/project_mappings.html.erb index 4b34a40450e0..09193be00a59 100644 --- a/app/views/admin/settings/project_custom_fields/project_mappings.html.erb +++ b/app/views/admin/settings/project_custom_fields/project_mappings.html.erb @@ -35,12 +35,10 @@ See COPYRIGHT and LICENSE files for more details. %> <%= - unless @custom_field.required? - render(Settings::ProjectCustomFields::ProjectCustomFieldMapping::NewProjectMappingComponent.new( - project_mapping: @project_mapping, - project_custom_field: @custom_field - )) - end + render(Settings::ProjectCustomFields::ProjectCustomFieldMapping::NewProjectMappingComponent.new( + project_mapping: @project_mapping, + project_custom_field: @custom_field + )) %> <%= From e0a3c30e4da389288a37f192eea8109d24cdbb83 Mon Sep 17 00:00:00 2001 From: Kabiru Mwenja Date: Mon, 3 Jun 2024 12:22:44 +0300 Subject: [PATCH 080/176] fix[Op#54749]: update auto complete on link/unlink so data is up to date --- .../new_project_mapping_component.html.erb | 126 +++++++++--------- .../new_project_mapping_component.rb | 2 + .../project_custom_fields_controller.rb | 9 +- 3 files changed, 72 insertions(+), 65 deletions(-) diff --git a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb index 6e885f207afc..063c90b728f4 100644 --- a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb +++ b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb @@ -1,75 +1,75 @@ -<% - new_project_mapping_form = Class.new(ApplicationForm) do - form do |f| - f.project_autocompleter( - name: :id, - label: Project.model_name.human, - visually_hide_label: true, - autocomplete_options: { - openDirectly: false, - focusDirectly: false, - dropdownPosition: 'bottom', - disabledProjects: projects_with_custom_field_mapping, - inputName: 'project_custom_field_project_mapping[project_id]' - } - ) +<%= + component_wrapper do + new_project_mapping_form = Class.new(ApplicationForm) do + form do |f| + f.project_autocompleter( + name: :id, + label: Project.model_name.human, + visually_hide_label: true, + autocomplete_options: { + openDirectly: false, + focusDirectly: false, + dropdownPosition: 'bottom', + disabledProjects: projects_with_custom_field_mapping, + inputName: 'project_custom_field_project_mapping[project_id]' + } + ) - f.check_box( - name: :include_sub_projects, - label: I18n.t("projects.settings.project_custom_fields.new_project_mapping_form.include_sub_projects"), - checked: false - ) - end + f.check_box( + name: :include_sub_projects, + label: I18n.t("projects.settings.project_custom_fields.new_project_mapping_form.include_sub_projects"), + checked: false + ) + end - def initialize(project_custom_field:) - super() - @project_custom_field = project_custom_field - end + def initialize(project_custom_field:) + super() + @project_custom_field = project_custom_field + end - private + private - def projects_with_custom_field_mapping - ProjectCustomFieldProjectMapping - .where(project_custom_field: @project_custom_field) - .pluck(:project_id) - .to_h { |id| [id, id] } + def projects_with_custom_field_mapping + ProjectCustomFieldProjectMapping + .where(project_custom_field: @project_custom_field) + .pluck(:project_id) + .to_h { |id| [id, id] } + end end - end -%> -<%= - render( - Primer::Alpha::Dialog.new( - id: dialog_id, - title:, - test_selector: dialog_id, - size: :large - ) - ) do |dialog| - dialog.with_show_button(scheme: :primary) { show_button_text } + render( + Primer::Alpha::Dialog.new( + id: dialog_id, + title:, + test_selector: dialog_id, + size: :large + ) + ) do |dialog| + dialog.with_show_button(scheme: :primary) { show_button_text } - dialog.with_header( - show_divider: false, - visually_hide_title: false - ) + dialog.with_header( + show_divider: false, + visually_hide_title: false + ) - render(Primer::Beta::Text.new(tag: :div)) do - primer_form_with( - model: @project_mapping, - url: link_admin_settings_project_custom_field_path(@project_custom_field), - data: { turbo: true }, - method: :post - ) do |form| - concat(render(Primer::Alpha::Dialog::Body.new( - id: dialog_body_id, test_selector: dialog_body_id, aria: { label: title } - )) do - render(new_project_mapping_form.new(form, project_custom_field: @project_custom_field)) - end) + render(Primer::Beta::Text.new(tag: :div)) do + primer_form_with( + model: @project_mapping, + url: link_admin_settings_project_custom_field_path(@project_custom_field), + data: { turbo: true }, + method: :post + ) do |form| + concat(render(Primer::Alpha::Dialog::Body.new( + id: dialog_body_id, test_selector: dialog_body_id, aria: { label: title } + )) do + render(new_project_mapping_form.new(form, project_custom_field: @project_custom_field)) + end) - concat(render(Primer::Alpha::Dialog::Footer.new(show_divider: false)) do - concat(render(Primer::ButtonComponent.new(data: { 'close-dialog-id': dialog_id })) { cancel_button_text }) - concat(render(Primer::ButtonComponent.new(scheme: :primary, type: :submit)) { submit_button_text }) - end) + concat(render(Primer::Alpha::Dialog::Footer.new(show_divider: false)) do + concat(render(Primer::ButtonComponent.new(data: { 'close-dialog-id': dialog_id })) { cancel_button_text }) + concat(render(Primer::ButtonComponent.new(scheme: :primary, type: :submit)) { submit_button_text }) + end) + end end end end diff --git a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.rb b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.rb index d2d86332e3fe..b6b8e71b9bb8 100644 --- a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.rb +++ b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.rb @@ -30,6 +30,8 @@ module Settings module ProjectCustomFields module ProjectCustomFieldMapping class NewProjectMappingComponent < ApplicationComponent # rubocop:disable OpenProject/AddPreviewForViewComponent + include OpTurbo::Streamable + options dialog_id: "settings--new-project-custom-field-mapping-component", dialog_body_id: "settings--new-project-custom-field-mapping-body-component" diff --git a/app/controllers/admin/settings/project_custom_fields_controller.rb b/app/controllers/admin/settings/project_custom_fields_controller.rb index 32ecfa837cd3..99f36ea05b0c 100644 --- a/app/controllers/admin/settings/project_custom_fields_controller.rb +++ b/app/controllers/admin/settings/project_custom_fields_controller.rb @@ -151,12 +151,17 @@ def destroy private def render_project_list + update_via_turbo_stream( + component: Settings::ProjectCustomFields::ProjectCustomFieldMapping::NewProjectMappingComponent.new( + project_mapping: ProjectCustomFieldProjectMapping.new(project_custom_field: @custom_field), + project_custom_field: @custom_field + ) + ) update_via_turbo_stream( component: Settings::ProjectCustomFields::ProjectCustomFieldMapping::TableComponent.new( query: project_custom_field_mappings_query, params: { custom_field: @custom_field } - ), - status: :ok + ) ) end From f1340e9897d03e30a9952ae50fc876e503260962 Mon Sep 17 00:00:00 2001 From: Markus Kahl Date: Thu, 2 May 2024 16:24:29 +0100 Subject: [PATCH 081/176] implement deploy status checks for github integration --- config/constants/settings/definition.rb | 4 + config/initializers/permissions.rb | 8 + lib/api/v3/root_representer.rb | 7 +- lib/open_project/version.rb | 2 +- .../deploy_targets/row_component.rb | 54 ++++++ .../deploy_targets/table_component.rb | 50 +++++ .../controllers/deploy_targets_controller.rb | 68 +++++++ .../app/models/deploy_status_check.rb | 40 ++++ .../app/models/deploy_target.rb | 40 ++++ .../app/models/github_pull_request.rb | 4 +- .../app/views/deploy_targets/_form.html.erb | 58 ++++++ .../app/views/deploy_targets/index.html.erb | 40 ++++ .../app/views/deploy_targets/new.html.erb | 40 ++++ .../workers/cron/check_deploy_status_job.rb | 183 ++++++++++++++++++ .../github_integration/config/locales/en.yml | 13 ++ modules/github_integration/config/routes.rb | 31 +++ .../20240501083852_create_deploy_targets.rb | 13 ++ ...40501093751_create_deploy_status_checks.rb | 12 ++ ...erge_commit_sha_to_github_pull_requests.rb | 5 + .../pull-request-state.component.sass | 3 + .../pull-request-state.component.ts | 2 +- .../pull-request/pull-request.component.ts | 3 + .../open_project/github_integration/engine.rb | 42 +++- .../services/upsert_pull_request.rb | 1 + .../factories/deploy_status_check_factory.rb | 34 ++++ .../spec/factories/deploy_target_factory.rb | 35 ++++ .../cron/check_deploy_status_job_spec.rb | 45 +++++ 27 files changed, 829 insertions(+), 8 deletions(-) create mode 100644 modules/github_integration/app/components/deploy_targets/row_component.rb create mode 100644 modules/github_integration/app/components/deploy_targets/table_component.rb create mode 100644 modules/github_integration/app/controllers/deploy_targets_controller.rb create mode 100644 modules/github_integration/app/models/deploy_status_check.rb create mode 100644 modules/github_integration/app/models/deploy_target.rb create mode 100644 modules/github_integration/app/views/deploy_targets/_form.html.erb create mode 100644 modules/github_integration/app/views/deploy_targets/index.html.erb create mode 100644 modules/github_integration/app/views/deploy_targets/new.html.erb create mode 100644 modules/github_integration/app/workers/cron/check_deploy_status_job.rb create mode 100644 modules/github_integration/config/routes.rb create mode 100644 modules/github_integration/db/migrate/20240501083852_create_deploy_targets.rb create mode 100644 modules/github_integration/db/migrate/20240501093751_create_deploy_status_checks.rb create mode 100644 modules/github_integration/db/migrate/20240502081436_add_merge_commit_sha_to_github_pull_requests.rb create mode 100644 modules/github_integration/spec/factories/deploy_status_check_factory.rb create mode 100644 modules/github_integration/spec/factories/deploy_target_factory.rb create mode 100644 modules/github_integration/spec/workers/cron/check_deploy_status_job_spec.rb diff --git a/config/constants/settings/definition.rb b/config/constants/settings/definition.rb index 8fef00702ad9..af40b15e9e4e 100644 --- a/config/constants/settings/definition.rb +++ b/config/constants/settings/definition.rb @@ -567,6 +567,10 @@ class Definition description: "Require password confirmations for certain administrative actions", default: true }, + introspection_enabled: { + description: "If enabled, expose detailed information the running OpenProject environment to users with the necessary permissions.", + default: true + }, invitation_expiration_days: { default: 7 }, diff --git a/config/initializers/permissions.rb b/config/initializers/permissions.rb index c92ee82c1f11..0f2b2dfcdfb5 100644 --- a/config/initializers/permissions.rb +++ b/config/initializers/permissions.rb @@ -61,6 +61,14 @@ require: :loggedin, contract_actions: { users: %i[read create] } + map.permission :introspection, + { + admin: %i[info] + }, + permissible_on: :global, + require: :loggedin, + enabled: -> { Setting.introspection_enabled? } + map.permission :manage_user, { users: %i[index show edit update change_status change_status_info], diff --git a/lib/api/v3/root_representer.rb b/lib/api/v3/root_representer.rb index ed6e8ddedfab..4c8179ed3d51 100644 --- a/lib/api/v3/root_representer.rb +++ b/lib/api/v3/root_representer.rb @@ -109,7 +109,12 @@ class RootRepresenter < ::API::Decorators::Single property :core_version, exec_context: :decorator, getter: ->(*) { OpenProject::VERSION.to_semver }, - if: ->(*) { current_user.admin? } + if: ->(*) { current_user.admin? || current_user.allowed_globally?(:introspection) } + + property :core_sha, + exec_context: :decorator, + getter: ->(*) { OpenProject::VERSION.core_sha }, + if: ->(*) { current_user.admin? || current_user.allowed_globally?(:introspection) } def _type "Root" diff --git a/lib/open_project/version.rb b/lib/open_project/version.rb index efc9bec9f5ee..898a286f6fef 100644 --- a/lib/open_project/version.rb +++ b/lib/open_project/version.rb @@ -138,7 +138,7 @@ def revision_from_git def read_optional(file) path = Rails.root.join(file) if File.exist? path - File.read(path) + String(File.read(path)).strip end end diff --git a/modules/github_integration/app/components/deploy_targets/row_component.rb b/modules/github_integration/app/components/deploy_targets/row_component.rb new file mode 100644 index 000000000000..b17462f09476 --- /dev/null +++ b/modules/github_integration/app/components/deploy_targets/row_component.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2012-2024 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +module DeployTargets + class RowComponent < ::RowComponent + property :host, :type + + def deploy_target + model + end + + def created_at + helpers.format_time deploy_target.created_at + end + + def button_links + [delete_link] + end + + def delete_link + link_to "Delete", + deploy_target_path(deploy_target, back_url: request.fullpath), + method: :delete, + class: "icon icon-delete" + end + end +end diff --git a/modules/github_integration/app/components/deploy_targets/table_component.rb b/modules/github_integration/app/components/deploy_targets/table_component.rb new file mode 100644 index 000000000000..a1f49cad49b7 --- /dev/null +++ b/modules/github_integration/app/components/deploy_targets/table_component.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2012-2024 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +module DeployTargets + class TableComponent < ::TableComponent + columns :host, :type, :created_at + options :current_user + + def initial_sort + %i[id asc] + end + + def headers + columns.map do |name| + [name.to_s, header_options(name)] + end + end + + def header_options(name) + { caption: User.human_attribute_name(name) } + end + end +end diff --git a/modules/github_integration/app/controllers/deploy_targets_controller.rb b/modules/github_integration/app/controllers/deploy_targets_controller.rb new file mode 100644 index 000000000000..32599b702607 --- /dev/null +++ b/modules/github_integration/app/controllers/deploy_targets_controller.rb @@ -0,0 +1,68 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2012-2024 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +class DeployTargetsController < ApplicationController + layout "admin" + + before_action :require_admin + + def index + @deploy_targets = DeployTarget.all + end + + def new + @deploy_target = DeployTarget.new type: "OpenProject" + end + + def create + args = params + .permit("deploy_target" => ["host", "type", "api_key"])[:deploy_target] + .to_h + .merge(type: "OpenProject") + + @deploy_target = DeployTarget.create **args + + if @deploy_target.persisted? + flash[:success] = "Deploy target created" + + redirect_to deploy_targets_path + else + render 'new' + end + end + + def destroy + deploy_target = DeployTarget.find params[:id] + + deploy_target.destroy! + + flash[:success] = "Deploy target deleted" + + redirect_to deploy_targets_path + end +end diff --git a/modules/github_integration/app/models/deploy_status_check.rb b/modules/github_integration/app/models/deploy_status_check.rb new file mode 100644 index 000000000000..670bfb321ad5 --- /dev/null +++ b/modules/github_integration/app/models/deploy_status_check.rb @@ -0,0 +1,40 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2012-2024 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +class DeployStatusCheck < ApplicationRecord + belongs_to :github_pull_request + belongs_to :deploy_target + + validates_presence_of :core_sha + + delegate :merge_commit_sha, to: :github_pull_request + + def pull_request + github_pull_request + end +end diff --git a/modules/github_integration/app/models/deploy_target.rb b/modules/github_integration/app/models/deploy_target.rb new file mode 100644 index 000000000000..decbcf0b11e6 --- /dev/null +++ b/modules/github_integration/app/models/deploy_target.rb @@ -0,0 +1,40 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2012-2024 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +class DeployTarget < ApplicationRecord + self.inheritance_column = nil + + store_accessor :options, :api_key + + has_many :deploy_status_checks, dependent: :destroy + + validates_presence_of :host + + # this is very much specific to the only type of target we support for now, OpenProject + validates_presence_of :api_key +end diff --git a/modules/github_integration/app/models/github_pull_request.rb b/modules/github_integration/app/models/github_pull_request.rb index 4b53509d7ba1..5cef02b4dfbd 100644 --- a/modules/github_integration/app/models/github_pull_request.rb +++ b/modules/github_integration/app/models/github_pull_request.rb @@ -31,12 +31,14 @@ class GithubPullRequest < ApplicationRecord has_and_belongs_to_many :work_packages has_many :github_check_runs, dependent: :destroy + has_many :deploy_status_checks, dependent: :destroy belongs_to :github_user, optional: true belongs_to :merged_by, optional: true, class_name: "GithubUser" enum state: { open: "open", - closed: "closed" + closed: "closed", + deployed: "deployed" } validates_presence_of :github_html_url, diff --git a/modules/github_integration/app/views/deploy_targets/_form.html.erb b/modules/github_integration/app/views/deploy_targets/_form.html.erb new file mode 100644 index 000000000000..34c7efcf5744 --- /dev/null +++ b/modules/github_integration/app/views/deploy_targets/_form.html.erb @@ -0,0 +1,58 @@ +<%#-- copyright +OpenProject is an open source project management software. +Copyright (C) 2012-2024 the OpenProject GmbH + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 3. + +OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +Copyright (C) 2006-2013 Jean-Philippe Lang +Copyright (C) 2010-2013 the ChiliProject Team + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +See COPYRIGHT and LICENSE files for more details. + +++#%> +
+
+ <%= f.text_field :host, required: true, container_class: '-middle' %> +
+ +
+ <%= f.select :type, + ['OpenProject'], + { container_class: '-slim' }, + disabled: true, + required: true + %> + + <%= t(:text_deploy_target_type_info) %> + +
+ + <%# This field is specific to the only type of DeployTarget we support for now, which is OpenProject. %> +
+ <%= f.text_field "api_key", container_class: '-wide' %> + + <%= link_translate( + :text_deploy_target_api_key_info, + links: { + docs_url: "https://www.openproject.org/docs/api/introduction/#api-key-through-basic-auth" + } + ) %> + +
+
diff --git a/modules/github_integration/app/views/deploy_targets/index.html.erb b/modules/github_integration/app/views/deploy_targets/index.html.erb new file mode 100644 index 000000000000..1b564473e841 --- /dev/null +++ b/modules/github_integration/app/views/deploy_targets/index.html.erb @@ -0,0 +1,40 @@ +<%#-- copyright +OpenProject is an open source project management software. +Copyright (C) 2012-2024 the OpenProject GmbH + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 3. + +OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +Copyright (C) 2006-2013 Jean-Philippe Lang +Copyright (C) 2010-2013 the ChiliProject Team + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +See COPYRIGHT and LICENSE files for more details. + +++#%> + +<% html_title t(:label_administration), t(:label_github_integration) %> +<%= toolbar title: t(:label_deploy_target_plural) do %> +
  • + + <%= op_icon('button--icon icon-add') %> + <%= t(:label_deploy_target) %> + +
  • +<% end %> + +<%= render DeployTargets::TableComponent.new(rows: @deploy_targets, current_user: ) %> diff --git a/modules/github_integration/app/views/deploy_targets/new.html.erb b/modules/github_integration/app/views/deploy_targets/new.html.erb new file mode 100644 index 000000000000..f47dcca016da --- /dev/null +++ b/modules/github_integration/app/views/deploy_targets/new.html.erb @@ -0,0 +1,40 @@ +<%#-- copyright +OpenProject is an open source project management software. +Copyright (C) 2012-2024 the OpenProject GmbH + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 3. + +OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +Copyright (C) 2006-2013 Jean-Philippe Lang +Copyright (C) 2010-2013 the ChiliProject Team + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +See COPYRIGHT and LICENSE files for more details. + +++#%> + +<% html_title t(:label_administration), t("label_deploy_target_new") %> +<% local_assigns[:additional_breadcrumb] = t(:label_deploy_target_new) %> + +<%= toolbar title: t(:label_deploy_target_new) %> + +<%= error_messages_for @deploy_target %> + +<%= labelled_tabular_form_for @deploy_target, url: deploy_targets_path do |f| %> + <%= render partial: 'deploy_targets/form', locals: { f: f, deploy_target: @deploy_target } %> + <%= styled_button_tag t(:button_save), class: '-highlight -with-icon icon-checkmark' %> +<% end %> diff --git a/modules/github_integration/app/workers/cron/check_deploy_status_job.rb b/modules/github_integration/app/workers/cron/check_deploy_status_job.rb new file mode 100644 index 000000000000..b1ed86d3e32e --- /dev/null +++ b/modules/github_integration/app/workers/cron/check_deploy_status_job.rb @@ -0,0 +1,183 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2012-2024 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +module Cron + class CheckDeployStatusJob < ApplicationJob + include OpenProject::GithubIntegration::NotificationHandler::Helper + + priority_number :low + + def perform + deploy_targets.find_each do |deploy_target| + sha = openproject_core_sha deploy_target.host, deploy_target.api_key + + if sha.present? + pull_requests.find_each do |pull_request| + check_deploy_status deploy_target, pull_request, sha + end + else + OpenProject.logger.error "Failed to retrieve core SHA for deploy target #{deploy_target.host}" + end + end + end + + def deploy_targets + DeployTarget.all + end + + def pull_requests + GithubPullRequest + .closed + .where.not(merge_commit_sha: nil) + end + + def check_deploy_status(deploy_target, pull_request, core_sha) + status_check = deploy_status_check deploy_target, pull_request + + # we already checked this PR against the given core SHA, so no need to check again + return if status_check.core_sha == core_sha + + # if the commit is contained, it has been deployed + if commit_contains? core_sha, pull_request.merge_commit_sha + update_deploy_status pull_request, deploy_target + else + status_check.update core_sha: # remember last checked SHA to not check twice + end + end + + ## + # Marks the given PR as deployed and removes the last status check + # as it won't be needed anymore. This is because only closed (not yet deployed) + # PRs are ever checked for their deployment status. + def update_deploy_status(pull_request, deploy_target) + host = deploy_target.host + + ActiveRecord::Base.transaction do + delete_status_check pull_request, deploy_target + pull_request.update! state: "deployed" + + comment_on_referenced_work_packages( + pull_request.work_packages, + comment_user, + "[#{pull_request.repository}##{pull_request.number}](#{pull_request.github_html_url}) deployed to [#{host}](https://#{host})" + ) + end + end + + def delete_status_check(pull_request, deploy_target) + # we use `find` and delete it this way to also cover + # not-yet-persisted records + check = pull_request + .deploy_status_checks + .find { |c| c.deploy_target == deploy_target } + + pull_request.deploy_status_checks.delete(check) + end + + ## + # Ideally this would be the github user, but we don't really have a way + # to identify it outside of the webhook request cycle. + def comment_user + User.system + end + + def deploy_status_check(deploy_target, pull_request) + pull_request + .deploy_status_checks + .find_or_initialize_by( + deploy_target:, + github_pull_request: pull_request + ) + end + + def openproject_core_sha(host, api_token) + res = introspection_request(host, api_token) + + return nil if handle_request_error res, "Could not get OpenProject core SHA" + + info = JSON.parse res.body.to_s + + info["coreSha"].presence + end + + def introspection_request(host, api_token) + OpenProject.httpx.basic_auth("apikey", api_token).get("http://#{host}/api/v3") + end + + ## + # Uses the GitHub APIs compare endpoint to compare the currently deployed base commit + # and a merge commit from a PR. + # + # If the latter is included in the former, there will be 'ahead_by' and 'behind_by' + # in the response. 'aheady_by' will be 0, 'behind_by' greater than 0. + # + # If the commits are not included in the same branch, these fields + # will not be present at all. + def commit_contains?(base_commit_sha, merge_commit_sha) + data = compare_commits base_commit_sha, merge_commit_sha + + return false if data.nil? + + status = data["status"].presence + ahead_by = data["ahead_by"].presence + behind_by = data["behind_by"].presence + + status == "behind" && ahead_by == 0 && (behind_by.present? && behind_by > 0) + end + + def compare_commits(sha_a, sha_b) + res = compare_commits_request sha_a, sha_b + + return nil if handle_request_error res, "Failed to compare commits" + + JSON.parse res.body.read + end + + def handle_request_error(res, error_prefix) + if res.is_a? HTTPX::ErrorResponse + OpenProject.logger.error "#{error_prefix}: #{res.error}" + elsif res.status == 404 + OpenProject.logger.error "#{error_prefix}: not found" + elsif res.status != 200 + OpenProject.logger.error "#{error_prefix}: #{res.body}" + else + return false + end + + true + end + + def compare_commits_request(sha_a, sha_b) + OpenProject.httpx.get(compare_commits_url(sha_a, sha_b)) + end + + def compare_commits_url(sha_a, sha_b) + "https://api.github.com/repos/opf/openproject/compare/#{sha_a}...#{sha_b}" + end + end +end diff --git a/modules/github_integration/config/locales/en.yml b/modules/github_integration/config/locales/en.yml index 8b5a2e3e6dcf..182110277b56 100644 --- a/modules/github_integration/config/locales/en.yml +++ b/modules/github_integration/config/locales/en.yml @@ -27,9 +27,22 @@ #++ en: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Show GitHub content" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) + belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/routes.rb b/modules/github_integration/config/routes.rb new file mode 100644 index 000000000000..7fe0aaba47a2 --- /dev/null +++ b/modules/github_integration/config/routes.rb @@ -0,0 +1,31 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2012-2024 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +Rails.application.routes.draw do + resources :deploy_targets, only: %i[index new edit update create destroy] +end diff --git a/modules/github_integration/db/migrate/20240501083852_create_deploy_targets.rb b/modules/github_integration/db/migrate/20240501083852_create_deploy_targets.rb new file mode 100644 index 000000000000..782e976724bb --- /dev/null +++ b/modules/github_integration/db/migrate/20240501083852_create_deploy_targets.rb @@ -0,0 +1,13 @@ +class CreateDeployTargets < ActiveRecord::Migration[7.1] + def change + create_table :deploy_targets do |t| + t.text :type, null: false + t.text :host, null: false + t.jsonb :options, null: false, default: {} + + t.timestamps + end + + add_index :deploy_targets, :host, unique: true + end +end diff --git a/modules/github_integration/db/migrate/20240501093751_create_deploy_status_checks.rb b/modules/github_integration/db/migrate/20240501093751_create_deploy_status_checks.rb new file mode 100644 index 000000000000..2881a758cdeb --- /dev/null +++ b/modules/github_integration/db/migrate/20240501093751_create_deploy_status_checks.rb @@ -0,0 +1,12 @@ +class CreateDeployStatusChecks < ActiveRecord::Migration[7.1] + def change + create_table :deploy_status_checks do |t| + t.references :deploy_target + t.references :github_pull_request + + t.text :core_sha, null: false + + t.timestamps + end + end +end diff --git a/modules/github_integration/db/migrate/20240502081436_add_merge_commit_sha_to_github_pull_requests.rb b/modules/github_integration/db/migrate/20240502081436_add_merge_commit_sha_to_github_pull_requests.rb new file mode 100644 index 000000000000..5ae78152b886 --- /dev/null +++ b/modules/github_integration/db/migrate/20240502081436_add_merge_commit_sha_to_github_pull_requests.rb @@ -0,0 +1,5 @@ +class AddMergeCommitShaToGithubPullRequests < ActiveRecord::Migration[7.1] + def change + add_column :github_pull_requests, :merge_commit_sha, :text + end +end diff --git a/modules/github_integration/frontend/module/pull-request/pull-request-state.component.sass b/modules/github_integration/frontend/module/pull-request/pull-request-state.component.sass index 80af28bde1dd..dc0c8a9933b3 100644 --- a/modules/github_integration/frontend/module/pull-request/pull-request-state.component.sass +++ b/modules/github_integration/frontend/module/pull-request/pull-request-state.component.sass @@ -49,3 +49,6 @@ &_closed background-color: #d73a49 + + &_deployed + background-color: #d73af9 diff --git a/modules/github_integration/frontend/module/pull-request/pull-request-state.component.ts b/modules/github_integration/frontend/module/pull-request/pull-request-state.component.ts index 387a2dc378d1..33bbec81afca 100644 --- a/modules/github_integration/frontend/module/pull-request/pull-request-state.component.ts +++ b/modules/github_integration/frontend/module/pull-request/pull-request-state.component.ts @@ -35,7 +35,7 @@ import { import { PathHelperService } from 'core-app/core/path-helper/path-helper.service'; import { I18nService } from 'core-app/core/i18n/i18n.service'; -export type PullRequestState = 'opened'|'closed'|'referenced'|'ready_for_review'|'merged'|'draft'; +export type PullRequestState = 'opened'|'closed'|'referenced'|'ready_for_review'|'merged'|'draft'|'deployed'; @Component({ selector: 'op-github-pull-request-state', diff --git a/modules/github_integration/frontend/module/pull-request/pull-request.component.ts b/modules/github_integration/frontend/module/pull-request/pull-request.component.ts index ecc70c8ec87a..5b81b1e8e202 100644 --- a/modules/github_integration/frontend/module/pull-request/pull-request.component.ts +++ b/modules/github_integration/frontend/module/pull-request/pull-request.component.ts @@ -71,6 +71,9 @@ export class PullRequestComponent { if (this.pullRequest.state === 'open') { return (this.pullRequest.draft ? 'draft' : 'open'); } + if (this.pullRequest.state === 'deployed') { + return 'deployed'; + } return (this.pullRequest.merged ? 'merged' : 'closed'); } diff --git a/modules/github_integration/lib/open_project/github_integration/engine.rb b/modules/github_integration/lib/open_project/github_integration/engine.rb index 75950c7d335a..81ecb138c88d 100644 --- a/modules/github_integration/lib/open_project/github_integration/engine.rb +++ b/modules/github_integration/lib/open_project/github_integration/engine.rb @@ -35,14 +35,36 @@ class Engine < ::Rails::Engine include OpenProject::Plugins::ActsAsOpEngine - register "openproject-github_integration", - author_url: "https://www.openproject.org/", - bundled: true do + initializer "github.feature_decisions" do + OpenProject::FeatureDecisions.add :deploy_targets + end + + register( + "openproject-github_integration", + author_url: "https://www.openproject.org/", + bundled: true + ) do + ::Redmine::MenuManager.map(:admin_menu) do |menu| + menu.push :admin_github_integration, + { controller: "/deploy_targets", action: "index" }, + if: Proc.new { Setting.feature_deploy_targets_active? && User.current.admin? }, + caption: :label_github_integration, + icon: "github_logo" + end + project_module(:github, dependencies: :work_package_tracking) do permission(:show_github_content, {}, permissible_on: %i[work_package project]) end + + menu :admin_menu, + :deploy_targets, + { controller: "/deploy_targets", action: "index" }, + if: ->(*) { Setting.feature_deploy_targets_active? && User.current.admin? }, + parent: :admin_github_integration, + caption: :label_deploy_target_plural, + icon: "hosting" end initializer "github.register_hook" do @@ -86,12 +108,24 @@ class Engine < ::Rails::Engine end add_cron_jobs do - { + jobs = { "Cron::ClearOldPullRequestsJob": { cron: "25 1 * * *", # runs at 1:25 nightly class: ::Cron::ClearOldPullRequestsJob.name } } + + # Enabling the feature flag at runtime won't enable + # the cron job. So if you want this feature, enable it + # at start-time. + if Setting.feature_deploy_targets_active? + jobs["Cron::CheckDeployStatusJob"] = { + cron: "15,45 * * * *", # runs every half hour + class: ::Cron::CheckDeployStatusJob.name + } + end + + jobs end end end diff --git a/modules/github_integration/lib/open_project/github_integration/services/upsert_pull_request.rb b/modules/github_integration/lib/open_project/github_integration/services/upsert_pull_request.rb index 2ed0ea027f78..19000c1eb6f7 100644 --- a/modules/github_integration/lib/open_project/github_integration/services/upsert_pull_request.rb +++ b/modules/github_integration/lib/open_project/github_integration/services/upsert_pull_request.rb @@ -70,6 +70,7 @@ def extract_params(payload) .fetch("repo") .fetch("html_url"), draft: payload.fetch("draft"), + merge_commit_sha: payload.fetch("merge_commit_sha"), merged: payload.fetch("merged"), merged_by: github_user_id(payload["merged_by"]), merged_at: payload["merged_at"], diff --git a/modules/github_integration/spec/factories/deploy_status_check_factory.rb b/modules/github_integration/spec/factories/deploy_status_check_factory.rb new file mode 100644 index 000000000000..2bc91787f426 --- /dev/null +++ b/modules/github_integration/spec/factories/deploy_status_check_factory.rb @@ -0,0 +1,34 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2012-2024 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +FactoryBot.define do + factory :deploy_status_check do + deploy_target + github_pull_request + end +end diff --git a/modules/github_integration/spec/factories/deploy_target_factory.rb b/modules/github_integration/spec/factories/deploy_target_factory.rb new file mode 100644 index 000000000000..ac3cd2ecdea8 --- /dev/null +++ b/modules/github_integration/spec/factories/deploy_target_factory.rb @@ -0,0 +1,35 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2012-2024 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +FactoryBot.define do + factory :deploy_target do + type { "OpenProject" } + + sequence(:host) { |n| "https://qa-#{n}.openproject-edge.com" } + end +end diff --git a/modules/github_integration/spec/workers/cron/check_deploy_status_job_spec.rb b/modules/github_integration/spec/workers/cron/check_deploy_status_job_spec.rb new file mode 100644 index 000000000000..6e4d2c69c6e3 --- /dev/null +++ b/modules/github_integration/spec/workers/cron/check_deploy_status_job_spec.rb @@ -0,0 +1,45 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2012-2024 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +require "spec_helper" + +RSpec.describe Cron::CheckDeployStatusJob, type: :job, with_flags { deploy_targets: true } do + let!(:deploy_target) { create(:deploy_target) } + + let(:deploy_status_check) { create(:deploy_status_check, deploy_target:, pull_request:) } + let(:pull_request) { create(:github_pull_request, work_packages: [work_package]) } + let(:work_package) { create(:work_package) } + + let(:job) { described_class.new } + + context "with no prior checks" do + before do + job.run + end + end +end From dffb638f8ae7a853cd90d1d2c3833091575c2247 Mon Sep 17 00:00:00 2001 From: Markus Kahl Date: Fri, 31 May 2024 15:06:43 +0100 Subject: [PATCH 082/176] fix icons on admin overview page --- app/views/admin/index.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/index.html.erb b/app/views/admin/index.html.erb index d318b2fb6be9..9f67f397c8da 100644 --- a/app/views/admin/index.html.erb +++ b/app/views/admin/index.html.erb @@ -34,7 +34,7 @@ See COPYRIGHT and LICENSE files for more details. From 62681c282e7f5064bc1daafcc1d71f04c786d8c9 Mon Sep 17 00:00:00 2001 From: Eric Guo Date: Tue, 4 Jun 2024 16:28:10 +0800 Subject: [PATCH 124/176] typo week, but it should be month as setting days per month. --- config/constants/settings/definition.rb | 2 +- config/locales/en.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/constants/settings/definition.rb b/config/constants/settings/definition.rb index 97fc81710e56..038088dc084f 100644 --- a/config/constants/settings/definition.rb +++ b/config/constants/settings/definition.rb @@ -304,7 +304,7 @@ class Definition ].freeze }, days_per_month: { - description: "This will define what is considered a “week” when displaying duration in a more natural way " \ + description: "This will define what is considered a “month” when displaying duration in a more natural way " \ "(for example, if a month is 20 days, 60 days would be 3 months.", default: 20, format: :integer diff --git a/config/locales/en.yml b/config/locales/en.yml index f07246232642..aab99aca27dd 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -3111,7 +3111,7 @@ Project attributes and sections are defined in the - - This will define what is considered a "week" when displaying duration in a more natural + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Default language" setting_default_projects_modules: "Default enabled modules for new projects" From ccebbe4c51464cb3385dda957c6ef1f6bd41029b Mon Sep 17 00:00:00 2001 From: Andreas Pfohl Date: Tue, 4 Jun 2024 11:02:28 +0200 Subject: [PATCH 125/176] feat[Op#54749]: Added search icon to placholder --- app/components/_index.sass | 1 + .../new_project_mapping_component.html.erb | 1 + .../new_project_mapping_component.sass | 8 ++++++++ 3 files changed, 10 insertions(+) create mode 100644 app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.sass diff --git a/app/components/_index.sass b/app/components/_index.sass index df5d51df72f6..a5968c92de5c 100644 --- a/app/components/_index.sass +++ b/app/components/_index.sass @@ -5,3 +5,4 @@ @import "filters_component" @import "projects/settings/project_custom_field_sections/index_component" @import "projects/row_component" +@import "settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component" diff --git a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb index f1d487eaa36f..7fc6a633f969 100644 --- a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb +++ b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb @@ -55,6 +55,7 @@ ) primer_form_with( + class: "op-new-project-mapping-form", model: @project_mapping, url: link_admin_settings_project_custom_field_path(@project_custom_field), data: { turbo: true }, diff --git a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.sass b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.sass new file mode 100644 index 000000000000..76511b9c5b3e --- /dev/null +++ b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.sass @@ -0,0 +1,8 @@ +@import 'helpers' + +.op-new-project-mapping-form + .ng-placeholder + @extend .icon-search + &:before + @include icon-font-common + margin-right: 10px From 6ccb9ba2aa77fd947a60167ee8f7fecee56faf92 Mon Sep 17 00:00:00 2001 From: Henriette Darge Date: Tue, 4 Jun 2024 12:14:56 +0200 Subject: [PATCH 126/176] Use SubHeader component in admin/settings/project_custom_fields --- .../header_component.html.erb | 48 ++++++++++--------- .../project_custom_fields/index.html.erb | 2 +- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/app/components/settings/project_custom_fields/header_component.html.erb b/app/components/settings/project_custom_fields/header_component.html.erb index d256f4bbed2d..a9fe5181caff 100644 --- a/app/components/settings/project_custom_fields/header_component.html.erb +++ b/app/components/settings/project_custom_fields/header_component.html.erb @@ -1,32 +1,34 @@ -<% button_block = lambda do |button| - button.with_leading_visual_icon(icon: :plus) - t('settings.project_attributes.label_new_section') -end %> - <%= - component_wrapper do - render Primer::OpenProject::PageHeader.new do |header| - header.with_title(variant: :default) { t("settings.project_attributes.heading") } - header.with_description { t("settings.project_attributes.heading_description") } - header.with_breadcrumbs(breadcrumbs_items) - header.with_action_button(tag: :a, - href: new_admin_settings_project_custom_field_path(type: "ProjectCustomField"), - scheme: :primary, - data: { turbo: "false", test_selector: "new-project-custom-field-button" }, - mobile_icon: :plus, - mobile_label: t("settings.project_attributes.label_new_attribute")) do |button| - button.with_leading_visual_icon(icon: :plus) - t("settings.project_attributes.label_new_attribute") - end + render Primer::OpenProject::PageHeader.new do |header| + header.with_title(variant: :default) { t("settings.project_attributes.heading") } + header.with_description { t("settings.project_attributes.heading_description") } + header.with_breadcrumbs(breadcrumbs_items) + end +%> - header.with_action_dialog(mobile_icon: :plus, - mobile_label: t('settings.project_attributes.label_new_section'), - dialog_arguments: {id: "project-custom-field-section-dialog", title: t('settings.project_attributes.label_new_section', size: :medium_portrait), size: :medium_portrait}, - button_arguments: {'aria-label': t('settings.project_attributes.label_new_section'), button_block: button_block}) do |dialog| +<%= + render Primer::OpenProject::SubHeader.new do |subheader| + subheader.with_action_component do + render(Primer::Alpha::Dialog.new(id: "project-custom-field-section-dialog", title: t('settings.project_attributes.label_new_section'), size: :medium_portrait)) do |dialog| + dialog.with_show_button('aria-label': t('settings.project_attributes.label_new_section')) do |button| + button.with_leading_visual_icon(icon: :plus) + t('settings.project_attributes.label_new_section') + end dialog.with_body do render(Settings::ProjectCustomFieldSections::DialogBodyFormComponent.new) end end end + + subheader.with_action_button(tag: :a, + href: new_admin_settings_project_custom_field_path(type: "ProjectCustomField"), + scheme: :primary, + data: { turbo: "false", test_selector: "new-project-custom-field-button" }, + mobile_icon: :plus, + mobile_label: t("settings.project_attributes.label_new_attribute")) do |button| + button.with_leading_visual_icon(icon: :plus) + t("settings.project_attributes.label_new_attribute") + end + end %> diff --git a/app/views/admin/settings/project_custom_fields/index.html.erb b/app/views/admin/settings/project_custom_fields/index.html.erb index 71c74dbe15b5..28a58287d6c1 100644 --- a/app/views/admin/settings/project_custom_fields/index.html.erb +++ b/app/views/admin/settings/project_custom_fields/index.html.erb @@ -29,7 +29,7 @@ See COPYRIGHT and LICENSE files for more details. <% html_title t(:label_administration), t("settings.project_attributes.heading") %>
    - <%= render(Settings::ProjectCustomFields::HeaderComponent.new()) %> + <%= render(Settings::ProjectCustomFields::HeaderComponent.new) %> <%= render(Settings::ProjectCustomFieldSections::IndexComponent.new( project_custom_field_sections: @project_custom_field_sections )) %> From 62a53c49c5b1f312ab76c9e0b25f83a003f4fbc5 Mon Sep 17 00:00:00 2001 From: Henriette Darge Date: Tue, 4 Jun 2024 12:15:29 +0200 Subject: [PATCH 127/176] Use SubHeader component in admin/settings/storages --- .../storages/admin/storages/index.html.erb | 44 +++++++++++-------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/modules/storages/app/views/storages/admin/storages/index.html.erb b/modules/storages/app/views/storages/admin/storages/index.html.erb index b2c6cd63a985..4dfc4ffa26a9 100644 --- a/modules/storages/app/views/storages/admin/storages/index.html.erb +++ b/modules/storages/app/views/storages/admin/storages/index.html.erb @@ -6,32 +6,40 @@ I18n.t("storages.label_storage") end %> -<%= render(Primer::OpenProject::PageHeader.new(border_bottom: 0)) do |header| %> +<%= render(Primer::OpenProject::PageHeader.new) do |header| %> <% header.with_title { t("external_file_storages") } %> <% header.with_description { t("storages.page_titles.file_storages.subtitle") } %> <% header.with_breadcrumbs([{ href: admin_index_path, text: t("label_administration") }, { href: admin_settings_storages_path, text: t("project_module_storages") }, t("external_file_storages")]) %> +<% end %> + +<%= render(Primer::OpenProject::SubHeader.new) do |subheader| + subheader.with_action_component do + render(Primer::Alpha::ActionMenu.new(test_selector: 'storages-select-provider-action-menu', + anchor_align: :end)) do |menu| + menu.with_show_button(scheme: :primary, + aria: { label: I18n.t("storages.label_add_new_storage") }) do |button| + button.with_leading_visual_icon(icon: :plus) + button.with_trailing_action_icon(icon: :"triangle-down") + I18n.t("storages.label_storage") + end - <%= header.with_action_menu(menu_arguments: { test_selector: 'storages-select-provider-action-menu', - anchor_align: :end }, - button_arguments: { scheme: :primary, - aria: { label: I18n.t("storages.label_add_new_storage") }, - button_block: button_block }) do |menu| - ::Storages::Storage::PROVIDER_TYPES.each do |provider_type| - short_provider_type = ::Storages::Storage.shorten_provider_type(provider_type) + ::Storages::Storage::PROVIDER_TYPES.each do |provider_type| + short_provider_type = ::Storages::Storage.shorten_provider_type(provider_type) - menu.with_item( - label: I18n.t("storages.provider_types.#{short_provider_type}.name"), - href: url_helpers.select_provider_admin_settings_storages_path(provider: short_provider_type) - ) do |item| - item.with_trailing_visual_icon( - icon: "op-enterprise-addons", - classes: "upsale-colored" - ) if ::Storages::Storage::one_drive_without_ee_token?(provider_type) + menu.with_item( + label: I18n.t("storages.provider_types.#{short_provider_type}.name"), + href: url_helpers.select_provider_admin_settings_storages_path(provider: short_provider_type) + ) do |item| + item.with_trailing_visual_icon( + icon: "op-enterprise-addons", + classes: "upsale-colored" + ) if ::Storages::Storage::one_drive_without_ee_token?(provider_type) + end end end - end %> -<% end %> + end +end %> <%= render(::Storages::Admin::StorageListComponent.new(@storages)) %> From 6ba2f34e092d22c4946568499d7514263bfb6c17 Mon Sep 17 00:00:00 2001 From: Henriette Darge Date: Tue, 4 Jun 2024 12:16:37 +0200 Subject: [PATCH 128/176] Correctly check for filter params to decide whether the filter section should be opened --- app/components/filter/filter_button_component.html.erb | 2 +- app/components/filter/filter_component.rb | 4 ++-- app/views/projects/index.html.erb | 1 - .../stimulus/controllers/dynamic/filters.controller.ts | 9 +++++++-- .../meetings/index_sub_header_component.html.erb | 1 - 5 files changed, 10 insertions(+), 7 deletions(-) diff --git a/app/components/filter/filter_button_component.html.erb b/app/components/filter/filter_button_component.html.erb index adb27dba4aa5..9f36eb0ba0ee 100644 --- a/app/components/filter/filter_button_component.html.erb +++ b/app/components/filter/filter_button_component.html.erb @@ -3,6 +3,6 @@ data: { "filters-target": "filterFormToggle", action: "filters#toggleDisplayFilters" }, test_selector: "filter-component-toggle")) do |button| %> - <% button.with_trailing_visual_counter(count: filters_count) %> + <% button.with_trailing_visual_counter(count: filters_count, test_selector: "filters-button-counter") %> <%= t(:label_filter) %> <% end %> diff --git a/app/components/filter/filter_component.rb b/app/components/filter/filter_component.rb index 077f3b54dd85..ea313e4d1975 100644 --- a/app/components/filter/filter_component.rb +++ b/app/components/filter/filter_component.rb @@ -32,10 +32,10 @@ module Filter class FilterComponent < ApplicationComponent # rubocop:enable OpenProject/AddPreviewForViewComponent options :query - options hide_initially: false + options always_visible: false def show_filters_section? - !hide_initially || (params[:filters].present? && !params.key?(:hide_filters_section)) + always_visible || params[:filters].present? end # Returns filters, active and inactive. diff --git a/app/views/projects/index.html.erb b/app/views/projects/index.html.erb index 2bc845af85b0..88c3662c188b 100644 --- a/app/views/projects/index.html.erb +++ b/app/views/projects/index.html.erb @@ -44,7 +44,6 @@ See COPYRIGHT and LICENSE files for more details. render(Primer::OpenProject::SubHeader.new(data: { controller: "filters", "application-target": "dynamic", - "filters-display-filters-value": true, # TODO: show_filters_section?, })) do |subheader| subheader.with_filter_component do render(Filter::FilterButtonComponent.new(query:)) diff --git a/frontend/src/stimulus/controllers/dynamic/filters.controller.ts b/frontend/src/stimulus/controllers/dynamic/filters.controller.ts index 50650a77a291..e6893ac77333 100644 --- a/frontend/src/stimulus/controllers/dynamic/filters.controller.ts +++ b/frontend/src/stimulus/controllers/dynamic/filters.controller.ts @@ -72,6 +72,11 @@ export default class FiltersController extends Controller { declare displayFiltersValue:boolean; declare outputFormatValue:string; + connect() { + const urlParams = new URLSearchParams(window.location.search); + this.displayFiltersValue = urlParams.has('filters'); + } + toggleDisplayFilters() { this.displayFiltersValue = !this.displayFiltersValue; } @@ -83,9 +88,9 @@ export default class FiltersController extends Controller { toggleButtonActive() { if (this.displayFiltersValue) { - this.filterFormToggleTarget.setAttribute('aria-disabled', 'true'); + this.filterFormToggleTarget.setAttribute('aria-pressed', 'true'); } else { - this.filterFormToggleTarget.removeAttribute('aria-disabled'); + this.filterFormToggleTarget.removeAttribute('aria-pressed'); } } diff --git a/modules/meeting/app/components/meetings/index_sub_header_component.html.erb b/modules/meeting/app/components/meetings/index_sub_header_component.html.erb index 2f8a63a3c773..5f8c67601e1a 100644 --- a/modules/meeting/app/components/meetings/index_sub_header_component.html.erb +++ b/modules/meeting/app/components/meetings/index_sub_header_component.html.erb @@ -1,7 +1,6 @@ <%= render(Primer::OpenProject::SubHeader.new(data: { controller: "filters", "application-target": "dynamic", - "filters-display-filters-value": false, # TODO: show_filters_section?, "filters-output-format-value": "json", })) do |subheader| subheader.with_filter_component do From 6c356b111131726e7453c76f7ff2c2a8df4ef0d5 Mon Sep 17 00:00:00 2001 From: as-op Date: Tue, 4 Jun 2024 12:28:08 +0200 Subject: [PATCH 129/176] test for permissions on attribute embeds --- .../work_package/exports/macros/attributes.rb | 6 +- config/locales/en.yml | 10 +- .../pdf_export/work_package_to_pdf_spec.rb | 207 +++++++++++++----- 3 files changed, 159 insertions(+), 64 deletions(-) diff --git a/app/models/work_package/exports/macros/attributes.rb b/app/models/work_package/exports/macros/attributes.rb index 2fcc46d4be1d..659e5db19562 100644 --- a/app/models/work_package/exports/macros/attributes.rb +++ b/app/models/work_package/exports/macros/attributes.rb @@ -102,7 +102,8 @@ def self.resolve_work_package_match(id, type, attribute, user) return msg_macro_error(I18n.t('export.macro.model_not_found', model: type)) unless type == "value" work_package = WorkPackage.find_by(id:) - if work_package.nil? || !user.allowed_in_project?(:view_work_packages, work_package.project) + if work_package.nil? || + !user.allowed_in_work_package?(:view_work_packages, work_package) return msg_macro_error(I18n.t('export.macro.resource_not_found', resource: "#{WorkPackage.name} #{id}")) end @@ -114,7 +115,8 @@ def self.resolve_project_match(id, type, attribute, user) return msg_macro_error(I18n.t("export.macro.model_not_found", model: type)) unless type == "value" project = Project.find_by(id:) - if project.nil? || !user.allowed_in_project?(:view_project, project) + if project.nil? || + !user.allowed_in_project?(:view_project, project) return msg_macro_error(I18n.t("export.macro.resource_not_found", resource: "#{Project.name} #{id}")) end diff --git a/config/locales/en.yml b/config/locales/en.yml index 5b079c47a579..802636d26d12 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1706,11 +1706,11 @@ Project attributes and sections are defined in the %w[view_work_packages export_work_packages] }) end + let(:another_user) do + create(:user, firstname: "Secret User") + end let(:category) { create(:category, project:, name: "Demo") } let(:version) { create(:version, project:) } let(:export_time) { DateTime.new(2023, 6, 30, 23, 59) } @@ -62,8 +77,9 @@ let(:priority) { create(:priority_normal) } let(:image_attachment) { Attachment.new author: user, file: File.open(image_path) } let(:attachments) { [image_attachment] } - let(:cf_long_text_description) { "foo" } - let(:cf_long_text) { create(:issue_custom_field, :text, name: "LongText") } + let(:cf_long_text_description) { "" } + let(:cf_long_text) { create(:issue_custom_field, :text, + name: "Work Package Custom Field Long Text") } let!(:cf_disabled_in_project) do # NOT enabled by project.work_package_custom_field_ids => NOT in PDF create(:float_wp_custom_field, name: "DisabledCustomField") @@ -71,6 +87,7 @@ let(:cf_global_bool) do create( :work_package_custom_field, + name: "Work Package Custom Field Boolean", field_format: "bool", is_for_all: true, default_value: true @@ -78,7 +95,6 @@ end let(:status) { create(:status, name: "random", is_default: true) } let!(:parent_work_package) { create(:work_package, type:, subject: "Parent wp") } - let(:description) do <<~DESCRIPTION **Lorem** _ipsum_ ~~dolor~~ `sit` [amet](https://example.com/), consetetur sadipscing elitr. @@ -128,6 +144,24 @@ .and_return attachments end end + let(:forbidden_work_package) do + create(:work_package, + id: 10, + project: forbidden_project, + type:, + subject: "forbidden Work package", + start_date: "2024-05-30", + due_date: "2024-05-30", + created_at: export_time, + updated_at: export_time, + author: another_user, + assigned_to: another_user + ).tap do |wp| + allow(wp) + .to receive(:attachments) + .and_return attachments + end + end let(:options) { {} } let(:exporter) do described_class.new(work_package, options) @@ -142,13 +176,14 @@ end end let(:expected_details) do - exporter.send(:attributes_data_by_wp, work_package) - .flat_map do |item| - value = get_column_value(item[:name]) - result = [item[:label].upcase] - result << value if value.present? - result - end + ["#{type.name} ##{work_package.id} - #{work_package.subject}"] + + exporter.send(:attributes_data_by_wp, work_package) + .flat_map do |item| + value = get_column_value(item[:name]) + result = [item[:label].upcase] + result << value if value.present? + result + end end def get_column_value(column_name) @@ -166,26 +201,28 @@ def get_column_value(column_name) end describe "with a request for a PDF" do - it "contains correct data" do - result = pdf[:strings] - expected_result = [ - "#{type.name} ##{work_package.id} - #{work_package.subject}", - *expected_details, - label_title(:description), - "Lorem", " ", "ipsum", " ", "dolor", " ", "sit", " ", - "amet", ", consetetur sadipscing elitr.", " ", "@OpenProject Admin", - "Image Caption", - "Foo", - "LongText", "foo", - "1", export_time_formatted, project.name - ].flatten - # Joining the results for comparison since word wrapping leads to a different array for the same content - expect(result.join(" ")).to eq(expected_result.join(" ")) - expect(result.join(" ")).not_to include("DisabledCustomField") - expect(pdf[:images].length).to eq(2) + describe "with rich text and images" do + let(:cf_long_text_description) { "foo" } + it "contains correct data" do + result = pdf[:strings] + expected_result = [ + *expected_details, + label_title(:description), + "Lorem", " ", "ipsum", " ", "dolor", " ", "sit", " ", + "amet", ", consetetur sadipscing elitr.", " ", "@OpenProject Admin", + "Image Caption", + "Foo", + cf_long_text.name, "foo", + "1", export_time_formatted, project.name + ].flatten + # Joining the results for comparison since word wrapping leads to a different array for the same content + expect(result.join(" ")).to eq(expected_result.join(" ")) + expect(result.join(" ")).not_to include("DisabledCustomField") + expect(pdf[:images].length).to eq(2) + end end - describe "with embedded attributes" do + describe "with embedded work package attributes" do let(:supported_work_package_embeds) do [ ["assignee", user.name], @@ -209,18 +246,6 @@ def get_column_value(column_name) ["description", "[#{I18n.t('export.macro.rich_text_unsupported')}]"] ] end - let(:supported_project_embeds) do - [ - ["active", "Yes"], - ["description", "[#{I18n.t('export.macro.rich_text_unsupported')}]"], - ["identifier", project.identifier], - ["name", project.name], - ["status", I18n.t("activerecord.attributes.project.status_codes.#{project.status_code}")], - ["statusExplanation", "[#{I18n.t('export.macro.rich_text_unsupported')}]"], - ["parent", parent_project.name], - ["public", "Yes"] - ] - end let(:supported_work_package_embeds_table) do supported_work_package_embeds.map do |embed| "workPackageLabel:#{embed[0]}workPackageValue:#{embed[0]}" @@ -230,6 +255,12 @@ def get_column_value(column_name) <<~DESCRIPTION ## Work package attributes and labels #{supported_work_package_embeds_table} + + " - end - end - let(:cf_long_text_description) do - <<~DESCRIPTION - ## Project attributes and labels -
    Custom field boolean + workPackageValue:1:"#{cf_global_bool.name}" +
    Custom field rich text + workPackageValue:1:"#{cf_long_text.name}" +
    No replacement of: workPackageValue:1:assignee workPackageLabel:assignee @@ -242,24 +273,16 @@ def get_column_value(column_name) workPackageValue:3:assignee workPackageLabel:assignee ``` + + Work package not found: + workPackageValue:1234567890:assignee + Access denied: + workPackageValue:#{forbidden_work_package.id}:assignee DESCRIPTION end - let(:supported_project_embeds_table) do - supported_project_embeds.map do |embed| - "
    projectLabel:#{embed[0]}projectValue:#{embed[0]}
    #{supported_project_embeds_table}
    - DESCRIPTION - end - it "contains resolved attributes and labels" do result = pdf[:strings] expected_result = [ - "#{type.name} ##{work_package.id} - #{work_package.subject}", *expected_details, label_title(:description), "Work package attributes and labels", @@ -268,20 +291,90 @@ def get_column_value(column_name) API::Utilities::PropertyNameConverter.to_ar_name(embed[0].to_sym, context: work_package) ), embed[1]] end, + "Custom field boolean", I18n.t(:general_text_Yes), + "1", export_time_formatted, project.name, + "Custom field rich text", "[#{I18n.t('export.macro.rich_text_unsupported')}]", "No replacement of:", "workPackageValue:1:assignee", " ", "workPackageLabel:assignee", "workPackageValue:2:assignee workPackageLabel:assignee", - "1", export_time_formatted, project.name, "workPackageValue:3:assignee", "workPackageLabel:assignee", - "LongText", + "Work package not found: ", + "[#{I18n.t('export.macro.error', message: + I18n.t('export.macro.resource_not_found', resource: "WorkPackage 1234567890"))}] ", + "Access denied: ", + "[#{I18n.t('export.macro.error', message: + I18n.t('export.macro.resource_not_found', resource: "WorkPackage #{forbidden_work_package.id}"))}]", + "2", export_time_formatted, project.name + ].flatten + expect(result.join(" ")).to eq(expected_result.join(" ")) + end + end + + describe "with embedded project attributes" do + let(:supported_project_embeds) do + [ + ["active", I18n.t(:general_text_Yes)], + ["description", "[#{I18n.t('export.macro.rich_text_unsupported')}]"], + ["identifier", project.identifier], + ["name", project.name], + ["status", I18n.t("activerecord.attributes.project.status_codes.#{project.status_code}")], + ["statusExplanation", "[#{I18n.t('export.macro.rich_text_unsupported')}]"], + ["parent", parent_project.name], + ["public", I18n.t(:general_text_Yes)] + ] + end + let(:supported_project_embeds_table) do + supported_project_embeds.map do |embed| + "projectLabel:#{embed[0]}projectValue:#{embed[0]}" + end + end + let(:description) do + <<~DESCRIPTION + ## Project attributes and labels + #{supported_project_embeds_table} + +
    No replacement of: + projectValue:1:status + projectLabel:status +
    + + `projectValue:2:status projectLabel:status` + + ``` + projectValue:3:status + projectLabel:status + ``` + + Project not found: + projectValue:1234567890:active + Access denied: + projectValue:#{forbidden_project.id}:active + DESCRIPTION + end + it "contains resolved attributes and labels" do + result = pdf[:strings] + expected_result = [ + *expected_details, + label_title(:description), "Project attributes and labels", supported_project_embeds.map do |embed| [Project.human_attribute_name( API::Utilities::PropertyNameConverter.to_ar_name(embed[0].to_sym, context: project) ), embed[1]] end, - "2", export_time_formatted, project.name + + "No replacement of:", "projectValue:1:status", " ", "projectLabel:status", + "projectValue:2:status projectLabel:status", + "projectValue:3:status", "projectLabel:status", + + "Project not found: ", + "[#{I18n.t('export.macro.error', message: + I18n.t('export.macro.resource_not_found', resource: "Project 1234567890"))}] ", + "Access denied: ", + "[#{I18n.t('export.macro.error', message: + I18n.t('export.macro.resource_not_found', resource: "Project #{forbidden_project.id}"))}]", + + "1", export_time_formatted, project.name ].flatten - # Joining the results for comparison since word wrapping leads to a different array for the same content expect(result.join(" ")).to eq(expected_result.join(" ")) end end From 2e013efc5c207f773af5dc048937b8581b8e9931 Mon Sep 17 00:00:00 2001 From: Kabiru Mwenja Date: Tue, 4 Jun 2024 13:29:14 +0300 Subject: [PATCH 130/176] feat[Op#54749]: add client side text filter --- .../row_component.html.erb | 9 ++- .../project_mappings.html.erb | 18 +++++ config/locales/en.yml | 3 + ...able-project-mappings-filter.controller.ts | 73 +++++++++++++++++++ 4 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 frontend/src/stimulus/controllers/dynamic/projects/settings/available-project-mappings-filter.controller.ts diff --git a/app/components/settings/project_custom_fields/project_custom_field_mapping/row_component.html.erb b/app/components/settings/project_custom_fields/project_custom_field_mapping/row_component.html.erb index 097b38764a0a..c92f886b908c 100644 --- a/app/components/settings/project_custom_fields/project_custom_field_mapping/row_component.html.erb +++ b/app/components/settings/project_custom_fields/project_custom_field_mapping/row_component.html.erb @@ -27,7 +27,14 @@ See COPYRIGHT and LICENSE files for more details. ++#%> -<%= component_wrapper(tag: "tr", class: row_css_class, data: { turbo: true }) do %> +<% + wrapper_data_attributes = { + turbo: true, + "projects--settings--available-project-mappings-filter-target": "searchItem" + } +%> + +<%= component_wrapper(tag: "tr", class: row_css_class, data: wrapper_data_attributes) do %> <% columns.each do |column| %> <%= column_value(column) %> diff --git a/app/views/admin/settings/project_custom_fields/project_mappings.html.erb b/app/views/admin/settings/project_custom_fields/project_mappings.html.erb index 7699c86ac2b9..d97890b6652e 100644 --- a/app/views/admin/settings/project_custom_fields/project_mappings.html.erb +++ b/app/views/admin/settings/project_custom_fields/project_mappings.html.erb @@ -27,6 +27,11 @@ See COPYRIGHT and LICENSE files for more details. ++#%> +<% content_controller 'projects--settings--available-project-mappings-filter', + dynamic: true +%> + + <%= render(Settings::ProjectCustomFields::EditFormHeaderComponent.new( custom_field: @custom_field, @@ -36,6 +41,19 @@ See COPYRIGHT and LICENSE files for more details. <%= render(Primer::OpenProject::SubHeader.new) do |component| + component.with_filter_input( + name: "available-project-mappings-filter", + label: I18n.t("projects.settings.project_custom_fields.project_mapping_filter.label"), + visually_hide_label: true, + placeholder: I18n.t("projects.settings.project_custom_fields.project_mapping_filter.placeholder"), + show_clear_button: true, + clear_button_id: "available-project-mappings-filter-clear-button", + data: { + action: "input->projects--settings--available-project-mappings-filter#filterLists", + "projects--settings--available-project-mappings-filter-target": "filter" + } + ) + component.with_action_component do render(Settings::ProjectCustomFields::ProjectCustomFieldMapping::NewProjectMappingComponent.new( project_mapping: @project_mapping, diff --git a/config/locales/en.yml b/config/locales/en.yml index dddcdd77298f..2082d2a6b236 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -336,6 +336,9 @@ Project attributes and sections are defined in the
    { + this.resetFilterViaClearButton(); + }); + } + + disconnect():void { + this.element.querySelector('#available-project-mappings-filter-clear-button')?.removeEventListener('click', () => { + this.resetFilterViaClearButton(); + }); + } + + filterLists() { + const query = this.filterTarget.value.toLowerCase(); + + this.searchItemTargets.forEach((item) => { + const text = item.textContent?.toLowerCase(); + + if (text?.includes(query)) { + (item as HTMLElement).classList.remove('d-none'); + } else { + (item as HTMLElement).classList.add('d-none'); + } + }); + } + + resetFilterViaClearButton() { + this.searchItemTargets.forEach((item) => { + (item as HTMLElement).classList.remove('d-none'); + }); + } +} From 6bbe353ed7ece028180a19e9e3af8bac6e358945 Mon Sep 17 00:00:00 2001 From: Henriette Darge Date: Tue, 4 Jun 2024 12:41:40 +0200 Subject: [PATCH 131/176] Use Subheader component in project/xy/settings/project_custom_fields --- .../index_component.html.erb | 35 ++++++++++--------- .../show_component.html.erb | 2 +- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/app/components/projects/settings/project_custom_field_sections/index_component.html.erb b/app/components/projects/settings/project_custom_field_sections/index_component.html.erb index 5da79313acf2..6a85a3914204 100644 --- a/app/components/projects/settings/project_custom_field_sections/index_component.html.erb +++ b/app/components/projects/settings/project_custom_field_sections/index_component.html.erb @@ -1,23 +1,24 @@ <%= component_wrapper(data: wrapper_data_attributes) do flex_layout do |flex| - flex.with_row(mt: 3) do - render(Primer::Alpha::TextField.new( - name: "project-custom-fields-mapping-filter", - label: t('projects.settings.project_custom_fields.filter.label'), - visually_hide_label: true, - placeholder: t('projects.settings.project_custom_fields.filter.label'), - leading_visual: { - icon: :search, - size: :small - }, - show_clear_button: true, - clear_button_id: "project-custom-fields-mapping-filter-clear-button", - data: { - action: "input->projects--settings--project-custom-fields-mapping-filter#filterLists", - "projects--settings--project-custom-fields-mapping-filter-target": "filter" - } - )) + flex.with_row do + render(Primer::OpenProject::SubHeader.new) do |subheader| + subheader.with_filter_input(name: "project-custom-fields-mapping-filter", + label: t('projects.settings.project_custom_fields.filter.label'), + visually_hide_label: true, + placeholder: t('projects.settings.project_custom_fields.filter.label'), + leading_visual: { + icon: :search, + size: :small + }, + input_width: :xlarge, + show_clear_button: true, + clear_button_id: "project-custom-fields-mapping-filter-clear-button", + data: { + action: "input->projects--settings--project-custom-fields-mapping-filter#filterLists", + "projects--settings--project-custom-fields-mapping-filter-target": "filter" + }) + end end @project_custom_field_sections.each do |project_custom_field_section| diff --git a/app/components/projects/settings/project_custom_field_sections/show_component.html.erb b/app/components/projects/settings/project_custom_field_sections/show_component.html.erb index 33c01da2fde6..727d8901228b 100644 --- a/app/components/projects/settings/project_custom_field_sections/show_component.html.erb +++ b/app/components/projects/settings/project_custom_field_sections/show_component.html.erb @@ -1,6 +1,6 @@ <%= component_wrapper do - render(border_box_container(mt: 3, classes: 'op-project-custom-field-section', data: { + render(border_box_container(mb: 3, classes: 'op-project-custom-field-section', data: { test_selector: "project-custom-field-section-#{@project_custom_field_section.id}" })) do |component| component.with_header(font_weight: :bold, py: 2) do From 9ff727c505d264fd503337bc5e6f71b79babde64 Mon Sep 17 00:00:00 2001 From: as-op Date: Tue, 4 Jun 2024 13:02:04 +0200 Subject: [PATCH 132/176] check for display rights of project attributes --- app/models/exports/formatters/custom_field.rb | 2 +- app/models/work_package/exports/macros/attributes.rb | 5 ++++- config/initializers/export_formats.rb | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/models/exports/formatters/custom_field.rb b/app/models/exports/formatters/custom_field.rb index 66dac9606b14..ef55bd0aff25 100644 --- a/app/models/exports/formatters/custom_field.rb +++ b/app/models/exports/formatters/custom_field.rb @@ -6,7 +6,7 @@ def self.apply?(attribute, export_format) end ## - # Takes a WorkPackage and an attribute and returns the value to be exported. + # Takes a WorkPackage or Project and an attribute and returns the value to be exported. def retrieve_value(object) custom_field = find_custom_field(object) return "" if custom_field.nil? diff --git a/app/models/work_package/exports/macros/attributes.rb b/app/models/work_package/exports/macros/attributes.rb index 659e5db19562..eb48c6be8632 100644 --- a/app/models/work_package/exports/macros/attributes.rb +++ b/app/models/work_package/exports/macros/attributes.rb @@ -137,7 +137,10 @@ def self.resolve_value_project(project, attribute) # currently we do not support embedding rich text fields: long text custom fields return msg_macro_error_rich_text if cf.formattable? - # TODO: Is the user allowed to see this custom field/"project attribute"? + # Is the user allowed to see this custom field/"project attribute"? + if project.available_custom_fields.find { |pcf| pcf.id == cf.id }.nil? + return msg_macro_error(I18n.t("export.macro.resource_not_found", resource: attribute)) + end end # currently we do not support embedding rich text field: e.g. projectValue:1234:description diff --git a/config/initializers/export_formats.rb b/config/initializers/export_formats.rb index 3b959de78632..9d7603cef5e9 100644 --- a/config/initializers/export_formats.rb +++ b/config/initializers/export_formats.rb @@ -19,6 +19,7 @@ list Project, Projects::Exports::CSV formatter Project, Exports::Formatters::CustomField + formatter Project, Exports::Formatters::CustomFieldPdf formatter Project, Projects::Exports::Formatters::Status formatter Project, Projects::Exports::Formatters::Description formatter Project, Projects::Exports::Formatters::Public From 42caf31b8414a4800cfcd77dfaf375eeabe4d6f7 Mon Sep 17 00:00:00 2001 From: Kabiru Mwenja Date: Tue, 4 Jun 2024 14:33:11 +0300 Subject: [PATCH 133/176] tests[Op#54749]: add bulk create unit specs --- .../bulk_create_service.rb | 2 + .../bulk_create_service_spec.rb | 110 ++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 spec/services/project_custom_field_project_mappings/bulk_create_service_spec.rb diff --git a/app/services/project_custom_field_project_mappings/bulk_create_service.rb b/app/services/project_custom_field_project_mappings/bulk_create_service.rb index 8bc811d85ba5..410082f37aab 100644 --- a/app/services/project_custom_field_project_mappings/bulk_create_service.rb +++ b/app/services/project_custom_field_project_mappings/bulk_create_service.rb @@ -46,6 +46,8 @@ def perform service_call end + private + def validate_permissions if @user.allowed_in_project?(:select_project_custom_fields, projects) ServiceResult.success diff --git a/spec/services/project_custom_field_project_mappings/bulk_create_service_spec.rb b/spec/services/project_custom_field_project_mappings/bulk_create_service_spec.rb new file mode 100644 index 000000000000..968458780c19 --- /dev/null +++ b/spec/services/project_custom_field_project_mappings/bulk_create_service_spec.rb @@ -0,0 +1,110 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2012-2024 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +require "spec_helper" + +RSpec.describe ProjectCustomFieldProjectMappings::BulkCreateService do + shared_let(:project_custom_field) { create(:project_custom_field) } + + context "with admin permissions" do + let(:user) { create(:admin) } + + context "with a single project" do + let(:project) { create(:project) } + let(:instance) { described_class.new(user:, project:, project_custom_field:) } + + it "creates the mappings" do + expect { instance.call }.to change(ProjectCustomFieldProjectMapping, :count).by(1) + + aggregate_failures "creates the mapping for the correct project and custom field" do + expect(ProjectCustomFieldProjectMapping.last.project).to eq(project) + expect(ProjectCustomFieldProjectMapping.last.project_custom_field).to eq(project_custom_field) + end + end + end + + context "with subprojects" do + let(:project) { create(:project) } + let!(:subproject) { create(:project, parent: project) } + let(:instance) { described_class.new(user:, project:, project_custom_field:, include_sub_projects: true) } + + it "creates the mappings for the project and sub-projects" do + expect { instance.call }.to change(ProjectCustomFieldProjectMapping, :count).by(2) + + aggregate_failures "creates the mapping for the correct project and custom field" do + expect(ProjectCustomFieldProjectMapping.last.project).to eq(subproject) + expect(ProjectCustomFieldProjectMapping.last.project_custom_field).to eq(project_custom_field) + end + end + end + end + + context "with non-admin but sufficient permissions" do + let(:user) do + create(:user, + member_with_permissions: { + project => %w[ + view_work_packages + edit_project + select_project_custom_fields + ] + }) + end + + let(:project) { create(:project) } + let(:instance) { described_class.new(user:, project:, project_custom_field:) } + + it "creates the mappings" do + expect { instance.call }.to change(ProjectCustomFieldProjectMapping, :count).by(1) + + aggregate_failures "creates the mapping for the correct project and custom field" do + expect(ProjectCustomFieldProjectMapping.last.project).to eq(project) + expect(ProjectCustomFieldProjectMapping.last.project_custom_field).to eq(project_custom_field) + end + end + end + + context "without sufficient permissions" do + let(:user) do + create(:user, + member_with_permissions: { + project => %w[ + view_work_packages + edit_project + ] + }) + end + let(:project) { create(:project) } + let(:instance) { described_class.new(user:, project:, project_custom_field:) } + + it "does not create the mappings" do + expect { instance.call }.not_to change(ProjectCustomFieldProjectMapping, :count) + expect(instance.call).to be_failure + end + end +end From ae934bb2aa0ddd0e43f4bf21264a44df4382d8b2 Mon Sep 17 00:00:00 2001 From: as-op Date: Tue, 4 Jun 2024 13:38:31 +0200 Subject: [PATCH 134/176] test for display rights of project attributes --- .../pdf_export/work_package_to_pdf_spec.rb | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/spec/models/work_packages/pdf_export/work_package_to_pdf_spec.rb b/spec/models/work_packages/pdf_export/work_package_to_pdf_spec.rb index 208e33e6cba8..814f76bc9a18 100644 --- a/spec/models/work_packages/pdf_export/work_package_to_pdf_spec.rb +++ b/spec/models/work_packages/pdf_export/work_package_to_pdf_spec.rb @@ -39,6 +39,19 @@ let(:parent_project) do create(:project, name: "Parent project") end + let(:project_custom_field_bool) { create(:project_custom_field, :boolean, + name: "Boolean project custom field") } + let(:project_custom_field_string) { + create(:project_custom_field, :string, + name: "Secret string", default_value: "admin eyes only", + visible: false) + } + let(:project_custom_field_long_text) { + create(:project_custom_field, :text, + name: "Rich text project custom field", + default_value: "rich text field value" + ) + } let(:project) do create(:project, name: "Foo Bla. Report No. 4/2021 with/for Case 42", @@ -47,6 +60,9 @@ status_code: "on_track", active: true, parent: parent_project, + custom_field_values: { + project_custom_field_bool.id => true + }, work_package_custom_fields: [cf_long_text, cf_disabled_in_project, cf_global_bool], work_package_custom_field_ids: [cf_long_text.id, cf_global_bool.id]) # cf_disabled_in_project.id is disabled end @@ -55,7 +71,7 @@ name: "Forbidden project", types: [type], id: 666, - public: true, + public: false, status_code: "on_track", active: true, parent: parent_project, @@ -331,6 +347,15 @@ def get_column_value(column_name) <<~DESCRIPTION ## Project attributes and labels #{supported_project_embeds_table} + + +
    Custom field boolean + projectValue:"#{project_custom_field_bool.name}" +
    Custom field rich text + projectValue:"#{project_custom_field_long_text.name}" +
    Custom field hidden + projectValue:"#{project_custom_field_string.name}" +
    No replacement of: projectValue:1:status projectLabel:status @@ -361,6 +386,11 @@ def get_column_value(column_name) API::Utilities::PropertyNameConverter.to_ar_name(embed[0].to_sym, context: project) ), embed[1]] end, + "Custom field boolean", I18n.t(:general_text_Yes), + "Custom field rich text", "[#{I18n.t('export.macro.rich_text_unsupported')}]", + "Custom field hidden", + "[#{I18n.t('export.macro.error', message: + I18n.t('export.macro.resource_not_found', resource: "Secret string"))}]", "No replacement of:", "projectValue:1:status", " ", "projectLabel:status", "projectValue:2:status projectLabel:status", From b54268f0c96cdbdd7c768ce023ff9ae64e1ad6ad Mon Sep 17 00:00:00 2001 From: ulferts Date: Tue, 4 Jun 2024 13:48:36 +0200 Subject: [PATCH 135/176] Add release-notes file --- docs/release-notes/14-1-1/README.md | 29 +++++++++++++++++++++++++++++ docs/release-notes/README.md | 7 +++++++ 2 files changed, 36 insertions(+) create mode 100644 docs/release-notes/14-1-1/README.md diff --git a/docs/release-notes/14-1-1/README.md b/docs/release-notes/14-1-1/README.md new file mode 100644 index 000000000000..94b8c0162bbf --- /dev/null +++ b/docs/release-notes/14-1-1/README.md @@ -0,0 +1,29 @@ +--- +title: OpenProject 14.1.1 +sidebar_navigation: + title: 14.1.1 +release_version: 14.1.1 +release_date: 2024-06-04 +--- + +# OpenProject 14.1.1 + +Release date: 2024-06-04 + +We released [OpenProject 14.1.1](https://community.openproject.org/versions/2056). +The release contains several bug fixes and we recommend updating to the newest version. + + + +## Bug fixes and changes + + + + +- Bugfix: Waiting modal doesn't time out \[[#55016](https://community.openproject.org/wp/55016)\] +- Bugfix: ScheduleReminderMailsNotificationsJob constantly broken after 24 hour outage - no reminder mails send \[[#55223](https://community.openproject.org/wp/55223)\] +- Bugfix: The available\_projects api endpoint displays custom project fields incorrectly \[[#55381](https://community.openproject.org/wp/55381)\] +- Bugfix: Typo in historic migation \[[#55421](https://community.openproject.org/wp/55421)\] + + + diff --git a/docs/release-notes/README.md b/docs/release-notes/README.md index 6efe42df3bbb..e458586215a9 100644 --- a/docs/release-notes/README.md +++ b/docs/release-notes/README.md @@ -13,6 +13,13 @@ Stay up to date and get an overview of the new features included in the releases +## 14.1.1 + +Release date: 2024-06-04 + +[Release Notes](14-1-1/) + + ## 14.1.0 Release date: 2024-05-22 From 7c52e94671bd24792c4b01bf1cc94f42008c4c71 Mon Sep 17 00:00:00 2001 From: ulferts Date: Tue, 4 Jun 2024 13:48:38 +0200 Subject: [PATCH 136/176] Bumped version to 14.1.2 [ci skip] --- lib/open_project/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/open_project/version.rb b/lib/open_project/version.rb index 389e48191dbb..244ffeaf80ae 100644 --- a/lib/open_project/version.rb +++ b/lib/open_project/version.rb @@ -33,7 +33,7 @@ module OpenProject module VERSION # :nodoc: MAJOR = 14 MINOR = 1 - PATCH = 1 + PATCH = 2 class << self # Used by semver to define the special version (if any). From 563337ddbc2842dfb4d8d52c1d247c2c1687f1e9 Mon Sep 17 00:00:00 2001 From: Andreas Pfohl Date: Tue, 4 Jun 2024 14:19:56 +0200 Subject: [PATCH 137/176] feat[Op#54749]: Added leading icon to app project mapping button --- .../new_project_mapping_component.html.erb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb index 7fc6a633f969..f6fc118db231 100644 --- a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb +++ b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb @@ -47,7 +47,10 @@ size: :large ) ) do |dialog| - dialog.with_show_button(scheme: :primary) { show_button_text } + dialog.with_show_button(scheme: :primary) do |button| + button.with_leading_visual_icon(icon: :project) + show_button_text + end dialog.with_header( show_divider: false, From 3ebbb7236038f827fab7bda9314a3f14d451a005 Mon Sep 17 00:00:00 2001 From: Kabiru Mwenja Date: Tue, 4 Jun 2024 15:21:42 +0300 Subject: [PATCH 138/176] tests[Op#54749]: add feature tests fr linking project --- .../project_mappings_spec.rb | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/spec/features/admin/project_custom_fields/project_mappings_spec.rb b/spec/features/admin/project_custom_fields/project_mappings_spec.rb index 2491b114c14a..93f226dd3f5f 100644 --- a/spec/features/admin/project_custom_fields/project_mappings_spec.rb +++ b/spec/features/admin/project_custom_fields/project_mappings_spec.rb @@ -82,6 +82,24 @@ end end + it "allows to link a project" do + project = create(:project) + subproject = create(:project, parent: project) + click_on "Add projects" + + within_test_selector("settings--new-project-custom-field-mapping-component") do + autocompleter = page.find(".op-project-autocompleter") + autocompleter.fill_in with: project.name + find(".ng-option-label", text: project.name).click + check "Include sub-projects" + + click_on "Add" + end + + expect(page).to have_text(project.name) + expect(page).to have_text(subproject.name) + end + context "and the project custom field is required" do shared_let(:project_custom_field) { create(:project_custom_field, is_required: true) } From 6039f2d89e68a111b8a87399b0c9e67d87b0561b Mon Sep 17 00:00:00 2001 From: Andreas Pfohl Date: Tue, 4 Jun 2024 15:10:29 +0200 Subject: [PATCH 139/176] feat[Op#54749]: Added correct include projects icon for attribute mapping --- Gemfile | 4 ++-- Gemfile.lock | 10 +++++----- .../new_project_mapping_component.html.erb | 2 +- frontend/package-lock.json | 14 +++++++------- frontend/package.json | 2 +- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Gemfile b/Gemfile index 3d2a029227ef..07fa1cb975ed 100644 --- a/Gemfile +++ b/Gemfile @@ -386,6 +386,6 @@ gemfiles.each do |file| send(:eval_gemfile, file) if File.readable?(file) end -gem "openproject-octicons", "~>19.13.0" -gem "openproject-octicons_helper", "~>19.13.0" +gem "openproject-octicons", "~>19.14.0" +gem "openproject-octicons_helper", "~>19.14.0" gem "openproject-primer_view_components", "~>0.32.1" diff --git a/Gemfile.lock b/Gemfile.lock index 33240a7e53fb..0b10ce1ec8d0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -770,10 +770,10 @@ GEM validate_email validate_url webfinger (~> 2.0) - openproject-octicons (19.13.0) - openproject-octicons_helper (19.13.0) + openproject-octicons (19.14.0) + openproject-octicons_helper (19.14.0) actionview - openproject-octicons (= 19.13.0) + openproject-octicons (= 19.14.0) railties openproject-primer_view_components (0.32.1) actionview (>= 5.0.0) @@ -1266,8 +1266,8 @@ DEPENDENCIES openproject-job_status! openproject-ldap_groups! openproject-meeting! - openproject-octicons (~> 19.13.0) - openproject-octicons_helper (~> 19.13.0) + openproject-octicons (~> 19.14.0) + openproject-octicons_helper (~> 19.14.0) openproject-openid_connect! openproject-primer_view_components (~> 0.32.1) openproject-recaptcha! diff --git a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb index f6fc118db231..dd5105151385 100644 --- a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb +++ b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb @@ -48,7 +48,7 @@ ) ) do |dialog| dialog.with_show_button(scheme: :primary) do |button| - button.with_leading_visual_icon(icon: :project) + button.with_leading_visual_icon(icon: 'op-include-projects') show_button_text end diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 771be4c13dc9..9752c1ce8eb1 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -46,7 +46,7 @@ "@ng-select/ng-select": "^12.0.7", "@ngneat/content-loader": "^7.0.0", "@ngx-formly/core": "^6.1.4", - "@openproject/octicons-angular": "^19.13.0", + "@openproject/octicons-angular": "^19.14.0", "@openproject/primer-view-components": "^0.32.1", "@openproject/reactivestates": "^3.0.1", "@primer/css": "^21.2.2", @@ -4802,9 +4802,9 @@ "integrity": "sha512-jrqoTI8lk5UziDsDPJ2Y+nmXYCcRhmr6uMARr3v/W6AMxRgsnRLWJyWKYr6FjaGMgbyxXG+OkCUPQY4Xl3toGg==" }, "node_modules/@openproject/octicons-angular": { - "version": "19.13.0", - "resolved": "https://registry.npmjs.org/@openproject/octicons-angular/-/octicons-angular-19.13.0.tgz", - "integrity": "sha512-rpqWRFDmtp7N1Baxf4q3hIOAKlzzx0xqMFd3sgpCblJjioOdtDGJlu6coFEEK4bZaQ5AMJdj7iUA0R3F5pQjpA==", + "version": "19.14.0", + "resolved": "https://registry.npmjs.org/@openproject/octicons-angular/-/octicons-angular-19.14.0.tgz", + "integrity": "sha512-26r+Fq5f8ZhWfwH3JwK18eOgK3juzNf9dIidVRRmjFXxTY6oreozclCQf1lqZMlxi3gVUTj9qB35hwINWtMPJQ==", "dependencies": { "tslib": "^2.3.0" }, @@ -25856,9 +25856,9 @@ "integrity": "sha512-jrqoTI8lk5UziDsDPJ2Y+nmXYCcRhmr6uMARr3v/W6AMxRgsnRLWJyWKYr6FjaGMgbyxXG+OkCUPQY4Xl3toGg==" }, "@openproject/octicons-angular": { - "version": "19.13.0", - "resolved": "https://registry.npmjs.org/@openproject/octicons-angular/-/octicons-angular-19.13.0.tgz", - "integrity": "sha512-rpqWRFDmtp7N1Baxf4q3hIOAKlzzx0xqMFd3sgpCblJjioOdtDGJlu6coFEEK4bZaQ5AMJdj7iUA0R3F5pQjpA==", + "version": "19.14.0", + "resolved": "https://registry.npmjs.org/@openproject/octicons-angular/-/octicons-angular-19.14.0.tgz", + "integrity": "sha512-26r+Fq5f8ZhWfwH3JwK18eOgK3juzNf9dIidVRRmjFXxTY6oreozclCQf1lqZMlxi3gVUTj9qB35hwINWtMPJQ==", "requires": { "tslib": "^2.3.0" } diff --git a/frontend/package.json b/frontend/package.json index dc37ae33af2d..91b7ebe2390b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -97,7 +97,7 @@ "@ng-select/ng-select": "^12.0.7", "@ngneat/content-loader": "^7.0.0", "@ngx-formly/core": "^6.1.4", - "@openproject/octicons-angular": "^19.13.0", + "@openproject/octicons-angular": "^19.14.0", "@openproject/primer-view-components": "^0.32.1", "@openproject/reactivestates": "^3.0.1", "@primer/css": "^21.2.2", From 96df4f5cd3952bdc0926eccc7a42d4d3c2c5f1f2 Mon Sep 17 00:00:00 2001 From: as-op Date: Tue, 4 Jun 2024 15:47:01 +0200 Subject: [PATCH 140/176] fix missing variable for wp list to pdf report --- app/models/work_package/pdf_export/markdown_field.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/models/work_package/pdf_export/markdown_field.rb b/app/models/work_package/pdf_export/markdown_field.rb index b3a6447b8a94..ddb7648c8b0f 100644 --- a/app/models/work_package/pdf_export/markdown_field.rb +++ b/app/models/work_package/pdf_export/markdown_field.rb @@ -38,17 +38,17 @@ def write_markdown_field!(work_package, markdown, label) pdf.formatted_text([styles.wp_markdown_label.merge({ text: label })]) end with_margin(styles.wp_markdown_margins) do - write_markdown! work_package, apply_markdown_field_macros(markdown) + write_markdown! work_package, apply_markdown_field_macros(markdown, work_package) end end private - def apply_markdown_field_macros(markdown) - apply_macros(markdown, WorkPackage::Exports::Macros::Attributes) + def apply_markdown_field_macros(markdown, work_package) + apply_macros(markdown, work_package, WorkPackage::Exports::Macros::Attributes) end - def apply_macros(markdown, formatter) + def apply_macros(markdown, work_package, formatter) return markdown unless formatter.applicable?(markdown) document = Markly.parse(markdown) From f4279573bb8c0471252ef126a36a2ca965556125 Mon Sep 17 00:00:00 2001 From: Aaron Contreras Date: Tue, 4 Jun 2024 10:20:27 -0500 Subject: [PATCH 141/176] Sync pacakge-lock.json with package.json --- frontend/package-lock.json | 2636 ++++++++++++++++++++++-------------- 1 file changed, 1636 insertions(+), 1000 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 771be4c13dc9..f748fe3157f5 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -54,7 +54,6 @@ "@uirouter/angular": "^13.0.0", "@uirouter/core": "^6.1.0", "@uirouter/rx": "^1.0.0", - "@vusion/webfonts-generator": "^0.8.0", "@w11k/ngx-componentdestroyed": "^5.0.2", "@xeokit/xeokit-bim-viewer": "2.5.1-beta-28", "autoprefixer": "^10.4.19", @@ -103,6 +102,7 @@ "typedjson": "^1.5.1", "urijs": "^1.19.11", "uuid": "^8.3.2", + "webfonts-generator-casaper": "^0.5.2", "zone.js": "~0.14.4" }, "devDependencies": { @@ -5328,14 +5328,6 @@ "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==", "dev": true }, - "node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "engines": { - "node": ">= 10" - } - }, "node_modules/@tsconfig/node10": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", @@ -6406,172 +6398,6 @@ "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" } }, - "node_modules/@vusion/webfonts-generator": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@vusion/webfonts-generator/-/webfonts-generator-0.8.0.tgz", - "integrity": "sha512-1q17CF6umBEjlAtO37TzRw3aOCCAyFX+T4HPG70BmM6qx8s6H4/LQOa8eHFZq/oiMuMyd0FehKgUt/pqYlIMWA==", - "dependencies": { - "handlebars": "^4.0.11", - "mkdirp": "^1.0.4", - "q": "^1.1.2", - "svg2ttf": "^6.0.3", - "svgicons2svgfont": "^10.0.4", - "ttf2eot": "^3.0.0", - "ttf2woff": "^3.0.0", - "ttf2woff2": "^4.0.4", - "underscore": "^1.9.1", - "url-join": "^4.0.0" - } - }, - "node_modules/@vusion/webfonts-generator/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "node_modules/@vusion/webfonts-generator/node_modules/bufferstreams": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bufferstreams/-/bufferstreams-3.0.0.tgz", - "integrity": "sha512-Qg0ggJUWJq90vtg4lDsGN9CDWvzBMQxhiEkSOD/sJfYt6BLect3eV1/S6K7SCSKJ34n60rf6U5eUPmQENVE4UA==", - "dependencies": { - "readable-stream": "^3.4.0" - }, - "engines": { - "node": ">=8.12.0" - } - }, - "node_modules/@vusion/webfonts-generator/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/@vusion/webfonts-generator/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@vusion/webfonts-generator/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@vusion/webfonts-generator/node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" - }, - "node_modules/@vusion/webfonts-generator/node_modules/svg-pathdata": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/svg-pathdata/-/svg-pathdata-6.0.3.tgz", - "integrity": "sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw==", - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@vusion/webfonts-generator/node_modules/svg2ttf": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/svg2ttf/-/svg2ttf-6.0.3.tgz", - "integrity": "sha512-CgqMyZrbOPpc+WqH7aga4JWkDPso23EgypLsbQ6gN3uoPWwwiLjXvzgrwGADBExvCRJrWFzAeK1bSoSpE7ixSQ==", - "dependencies": { - "@xmldom/xmldom": "^0.7.2", - "argparse": "^2.0.1", - "cubic2quad": "^1.2.1", - "lodash": "^4.17.10", - "microbuffer": "^1.0.0", - "svgpath": "^2.1.5" - }, - "bin": { - "svg2ttf": "svg2ttf.js" - } - }, - "node_modules/@vusion/webfonts-generator/node_modules/svgicons2svgfont": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/svgicons2svgfont/-/svgicons2svgfont-10.0.6.tgz", - "integrity": "sha512-fUgQEVg3XwTbOHvlXahHGqCet5Wvfo1bV4DCvbSRvjsOCPCRunYbG4dUJCPegps37BMph3eOrfoobhH5AWuC6A==", - "dependencies": { - "commander": "^7.2.0", - "geometry-interfaces": "^1.1.4", - "glob": "^7.1.6", - "neatequal": "^1.0.0", - "readable-stream": "^3.4.0", - "sax": "^1.2.4", - "svg-pathdata": "^6.0.0" - }, - "bin": { - "svgicons2svgfont": "bin/svgicons2svgfont.js" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@vusion/webfonts-generator/node_modules/ttf2eot": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/ttf2eot/-/ttf2eot-3.1.0.tgz", - "integrity": "sha512-aHTbcYosNHVqb2Qtt9Xfta77ae/5y0VfdwNLUS6sGBeGr22cX2JDMo/i5h3uuOf+FAD3akYOr17+fYd5NK8aXw==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "ttf2eot": "ttf2eot.js" - } - }, - "node_modules/@vusion/webfonts-generator/node_modules/ttf2woff": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ttf2woff/-/ttf2woff-3.0.0.tgz", - "integrity": "sha512-OvmFcj70PhmAsVQKfC15XoKH55cRWuaRzvr2fpTNhTNer6JBpG8n6vOhRrIgxMjcikyYt88xqYXMMVapJ4Rjvg==", - "dependencies": { - "argparse": "^2.0.1", - "pako": "^1.0.0" - }, - "bin": { - "ttf2woff": "ttf2woff.js" - } - }, - "node_modules/@vusion/webfonts-generator/node_modules/ttf2woff2": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/ttf2woff2/-/ttf2woff2-4.0.5.tgz", - "integrity": "sha512-zpoU0NopfjoyVqkFeQ722SyKk/n607mm5OHxuDS/wCCSy82B8H3hHXrezftA2KMbKqfJIjie2lsJHdvPnBGbsw==", - "hasInstallScript": true, - "dependencies": { - "bindings": "^1.5.0", - "bufferstreams": "^3.0.0", - "nan": "^2.14.2", - "node-gyp": "^9.0.0" - }, - "bin": { - "ttf2woff2": "bin/ttf2woff2.js" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@vusion/webfonts-generator/node_modules/url-join": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", - "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" - }, "node_modules/@w11k/ngx-componentdestroyed": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/@w11k/ngx-componentdestroyed/-/ngx-componentdestroyed-5.0.2.tgz", @@ -6735,14 +6561,6 @@ "html2canvas": "^1.4.1" } }, - "node_modules/@xmldom/xmldom": { - "version": "0.7.13", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.13.tgz", - "integrity": "sha512-lm2GW5PkosIzccsaZIz7tp8cPADSIlIHWDFTR1N0SzfinhhYgeIQjFMz4rYzanCScr3DqQLeomUDArp6MWKm+g==", - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", @@ -6867,28 +6685,6 @@ "node": ">=8.9.0" } }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/agentkeepalive": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", - "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", - "dependencies": { - "humanize-ms": "^1.2.1" - }, - "engines": { - "node": ">= 8.0.0" - } - }, "node_modules/aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -7379,23 +7175,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz", "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==" }, - "node_modules/aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" - }, - "node_modules/are-we-there-yet": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", - "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -7457,7 +7236,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", - "dev": true, "dependencies": { "call-bind": "^1.0.5", "is-array-buffer": "^3.0.4" @@ -7644,7 +7422,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", - "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.5", @@ -7662,6 +7439,24 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "license": "MIT", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, "node_modules/assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", @@ -7686,8 +7481,7 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/atoa": { "version": "1.0.0", @@ -7755,7 +7549,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dev": true, "dependencies": { "possible-typed-array-names": "^1.0.0" }, @@ -7766,6 +7559,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.0.tgz", + "integrity": "sha512-3AungXC4I8kKsS9PuS4JH2nc+0bVY/mjgrephHTIi8fpEeGsTHBUJeosp0Wc1myYMElmD0B3Oc4XL/HVJ4PV2g==", + "license": "MIT" + }, "node_modules/axe-core": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", @@ -8024,6 +7832,15 @@ "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "license": "BSD-3-Clause", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, "node_modules/big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", @@ -8245,6 +8062,48 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, + "node_modules/bufferstreams": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bufferstreams/-/bufferstreams-2.0.1.tgz", + "integrity": "sha512-ZswyIoBfFb3cVDsnZLLj2IDJ/0ppYdil/v2EGlZXvoefO689FokEmFEldhN5dV7R2QBxFneqTJOMIpfqhj+n0g==", + "license": "MIT", + "dependencies": { + "readable-stream": "^2.3.6" + }, + "engines": { + "node": ">=6.9.5" + } + }, + "node_modules/bufferstreams/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/bufferstreams/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/bufferstreams/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/builtins": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.1.0.tgz", @@ -8266,79 +8125,6 @@ "node": ">= 0.8" } }, - "node_modules/cacache": { - "version": "17.1.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-17.1.3.tgz", - "integrity": "sha512-jAdjGxmPxZh0IipMdR7fK/4sDSrHMLUV0+GvVUsjwyGNKHsh79kW/otg+GkbXwl6Uzvy9wsvHOX4nUoWldeZMg==", - "dependencies": { - "@npmcli/fs": "^3.1.0", - "fs-minipass": "^3.0.0", - "glob": "^10.2.2", - "lru-cache": "^7.7.1", - "minipass": "^5.0.0", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "p-map": "^4.0.0", - "ssri": "^10.0.0", - "tar": "^6.1.11", - "unique-filename": "^3.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/cacache/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/cacache/node_modules/glob": { - "version": "10.3.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.3.tgz", - "integrity": "sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw==", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.0.3", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" - }, - "bin": { - "glob": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/cacache/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "engines": { - "node": ">=12" - } - }, - "node_modules/cacache/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/cache-base": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", @@ -8424,6 +8210,12 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "license": "Apache-2.0" + }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -8613,6 +8405,15 @@ "node": ">=6" } }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/codemirror": { "version": "5.65.16", "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.16.tgz", @@ -8647,14 +8448,6 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "node_modules/color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "bin": { - "color-support": "bin.js" - } - }, "node_modules/colorette": { "version": "2.0.20", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", @@ -8673,7 +8466,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -9403,11 +9195,22 @@ "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", "dev": true }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/data-view-buffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", - "dev": true, "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -9424,7 +9227,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -9441,7 +9243,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", - "dev": true, "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -9610,7 +9411,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -9651,7 +9451,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, "engines": { "node": ">=0.4.0" } @@ -9899,6 +9698,16 @@ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "license": "MIT", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -10122,7 +9931,6 @@ "version": "1.23.3", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", - "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.1", "arraybuffer.prototype.slice": "^1.0.3", @@ -10237,7 +10045,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", - "dev": true, "dependencies": { "es-errors": "^1.3.0" }, @@ -10249,7 +10056,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", - "dev": true, "dependencies": { "get-intrinsic": "^1.2.4", "has-tostringtag": "^1.0.2", @@ -10272,7 +10078,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -11402,8 +11207,7 @@ "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, "node_modules/extend-shallow": { "version": "2.0.1", @@ -11460,6 +11264,15 @@ "node": ">=0.10.0" } }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "engines": [ + "node >=0.6.0" + ], + "license": "MIT" + }, "node_modules/eyes": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", @@ -11778,7 +11591,6 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, "dependencies": { "is-callable": "^1.1.3" } @@ -11830,6 +11642,15 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, "node_modules/form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -11959,7 +11780,6 @@ "version": "1.1.6", "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -11977,29 +11797,10 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/gauge": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", - "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^3.0.7", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -12114,7 +11915,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", - "dev": true, "dependencies": { "call-bind": "^1.0.5", "es-errors": "^1.3.0", @@ -12136,6 +11936,15 @@ "node": ">=0.10.0" } }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, "node_modules/gl-matrix": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.4.3.tgz", @@ -12216,7 +12025,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dev": true, "dependencies": { "define-properties": "^1.1.3" }, @@ -12567,11 +12375,55 @@ "node": ">=0.10.0" } }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "license": "MIT", + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/har-validator/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/har-validator/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "license": "MIT" + }, "node_modules/has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -12621,7 +12473,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, "dependencies": { "has-symbols": "^1.0.3" }, @@ -12943,19 +12794,6 @@ "node": ">=8.0.0" } }, - "node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/http-proxy-middleware": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", @@ -13074,16 +12912,19 @@ "node": ">=8" } }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "license": "MIT", "dependencies": { - "agent-base": "6", - "debug": "4" + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" }, "engines": { - "node": ">= 6" + "node": ">=0.8", + "npm": ">=1.3.7" } }, "node_modules/human-signals": { @@ -13094,14 +12935,6 @@ "node": ">=10.17.0" } }, - "node_modules/humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", - "dependencies": { - "ms": "^2.0.0" - } - }, "node_modules/i18n-js": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/i18n-js/-/i18n-js-4.4.3.tgz", @@ -13365,7 +13198,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", - "dev": true, "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.0", @@ -13409,7 +13241,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.1" @@ -13445,7 +13276,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, "dependencies": { "has-bigints": "^1.0.1" }, @@ -13468,7 +13298,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -13484,7 +13313,6 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -13519,7 +13347,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", - "dev": true, "dependencies": { "is-typed-array": "^1.1.13" }, @@ -13534,7 +13361,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -13673,7 +13499,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -13694,7 +13519,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -13771,7 +13595,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -13808,7 +13631,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", - "dev": true, "dependencies": { "call-bind": "^1.0.7" }, @@ -13834,7 +13656,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -13849,7 +13670,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, "dependencies": { "has-symbols": "^1.0.2" }, @@ -13864,7 +13684,6 @@ "version": "1.1.13", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "dev": true, "dependencies": { "which-typed-array": "^1.1.14" }, @@ -13875,6 +13694,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "license": "MIT" + }, "node_modules/is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", @@ -13899,7 +13724,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.2" }, @@ -13948,8 +13772,7 @@ "node_modules/isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" }, "node_modules/isbinaryfile": { "version": "4.0.10", @@ -13990,6 +13813,12 @@ "ws": "*" } }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "license": "MIT" + }, "node_modules/istanbul-lib-coverage": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", @@ -14439,6 +14268,12 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "license": "MIT" + }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -14472,6 +14307,12 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "license": "(AFL-2.1 OR BSD-3-Clause)" + }, "node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -14486,8 +14327,7 @@ "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" }, "node_modules/json5": { "version": "2.2.3", @@ -14541,6 +14381,21 @@ "node": "*" } }, + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "license": "MIT", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/jsx-ast-utils": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", @@ -15297,39 +15152,6 @@ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" }, - "node_modules/make-fetch-happen": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", - "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", - "dependencies": { - "agentkeepalive": "^4.2.1", - "cacache": "^17.0.0", - "http-cache-semantics": "^4.1.1", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^7.7.1", - "minipass": "^5.0.0", - "minipass-fetch": "^3.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^7.0.0", - "ssri": "^10.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/make-fetch-happen/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "engines": { - "node": ">=12" - } - }, "node_modules/make-plural": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-7.3.0.tgz", @@ -15598,33 +15420,6 @@ "node": ">=8" } }, - "node_modules/minipass-collect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", - "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-collect/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-collect/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "node_modules/minipass-fetch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.3.tgz", @@ -16096,30 +15891,6 @@ "node": ">= 6.13.0" } }, - "node_modules/node-gyp": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.0.tgz", - "integrity": "sha512-dMXsYP6gc9rRbejLXmTbVRYjAHw7ppswsKyMxuxJxxOHzluIO1rGp9TOQgjFJ+2MCqcOcQTOPB/8Xwhr+7s4Eg==", - "dependencies": { - "env-paths": "^2.2.0", - "exponential-backoff": "^3.1.1", - "glob": "^7.1.4", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^11.0.3", - "nopt": "^6.0.0", - "npmlog": "^6.0.0", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.2", - "which": "^2.0.2" - }, - "bin": { - "node-gyp": "bin/node-gyp.js" - }, - "engines": { - "node": "^12.13 || ^14.13 || >=16" - } - }, "node_modules/node-gyp-build": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", @@ -16131,25 +15902,6 @@ "node-gyp-build-test": "build-test.js" } }, - "node_modules/node-gyp/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -16167,20 +15919,6 @@ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" }, - "node_modules/nopt": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", - "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", - "dependencies": { - "abbrev": "^1.0.0" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, "node_modules/normalize-package-data": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.0.tgz", @@ -16430,20 +16168,6 @@ "node": ">=8" } }, - "node_modules/npmlog": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", - "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", - "dependencies": { - "are-we-there-yet": "^3.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^4.0.3", - "set-blocking": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, "node_modules/nth-check": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", @@ -16455,6 +16179,15 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/nx": { "version": "18.2.4", "resolved": "https://registry.npmjs.org/nx/-/nx-18.2.4.tgz", @@ -16662,11 +16395,19 @@ "node": ">=8" } }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -16740,7 +16481,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, "engines": { "node": ">= 0.4" } @@ -16761,7 +16501,6 @@ "version": "4.1.5", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.5", "define-properties": "^1.2.1", @@ -17046,6 +16785,15 @@ "node": ">=8" } }, + "node_modules/os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", @@ -17054,6 +16802,17 @@ "node": ">=0.10.0" } }, + "node_modules/osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "dependencies": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -17428,6 +17187,12 @@ "node": ">=8" } }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "license": "MIT" + }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -17593,7 +17358,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "dev": true, "engines": { "node": ">= 0.4" } @@ -17847,6 +17611,12 @@ "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", "optional": true }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "license": "MIT" + }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -18200,7 +17970,6 @@ "version": "1.5.2", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", - "dev": true, "dependencies": { "call-bind": "^1.0.6", "define-properties": "^1.2.1", @@ -18312,6 +18081,71 @@ "node": ">=0.10" } }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "license": "Apache-2.0", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/request/node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -18562,7 +18396,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "get-intrinsic": "^1.2.4", @@ -18594,7 +18427,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", - "dev": true, "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -19028,7 +18860,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dev": true, "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -19375,19 +19206,6 @@ "npm": ">= 3.0.0" } }, - "node_modules/socks-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", - "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", - "dependencies": { - "agent-base": "^6.0.2", - "debug": "^4.3.3", - "socks": "^2.6.2" - }, - "engines": { - "node": ">= 10" - } - }, "node_modules/source-map": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", @@ -19737,6 +19555,31 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, + "node_modules/sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "license": "MIT", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ssri": { "version": "10.0.4", "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.4.tgz", @@ -19913,6 +19756,17 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, + "node_modules/string.fromcodepoint": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string.fromcodepoint/-/string.fromcodepoint-0.2.1.tgz", + "integrity": "sha512-n69H31OnxSGSZyZbgBlvYIXlrMhJQ0dQAX1js1QDhpaUH6zmU3QYlj07bCwCNlPOu3oRXIubGPl2gDGnHsiCqg==" + }, + "node_modules/string.prototype.codepointat": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz", + "integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==", + "license": "MIT" + }, "node_modules/string.prototype.matchall": { "version": "4.0.11", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", @@ -19943,7 +19797,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -19961,7 +19814,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -19975,7 +19827,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -20093,6 +19944,110 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/svg-pathdata": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/svg-pathdata/-/svg-pathdata-5.0.5.tgz", + "integrity": "sha512-TAAvLNSE3fEhyl/Da19JWfMAdhSXTYeviXsLSoDT1UM76ADj5ndwAPX1FKQEgB/gFMPavOy6tOqfalXKUiXrow==", + "license": "MIT", + "engines": { + "node": ">=6.9.5" + } + }, + "node_modules/svg2ttf": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/svg2ttf/-/svg2ttf-5.2.0.tgz", + "integrity": "sha512-CzxPnSm2/CrMnJuKlXVllOx+q9wuarbIMi4Vf14eJoeESRqAOxVZiH0Ias71mhyXYGgz88A4T/E8fN/Y8eXoYA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "cubic2quad": "^1.0.0", + "lodash": "^4.17.10", + "microbuffer": "^1.0.0", + "svgpath": "^2.1.5", + "xmldom": "~0.5.0" + }, + "bin": { + "svg2ttf": "svg2ttf.js" + } + }, + "node_modules/svg2ttf/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/svgicons2svgfont": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/svgicons2svgfont/-/svgicons2svgfont-9.2.0.tgz", + "integrity": "sha512-mWeiuob7L2ZTcnAEP4JvSQ1pnIsGjV16ykQ0fCiiXqoUAQ/iNsDvBc601ojjfP89eCPtr3IVZ9mDxYpdxYO3xQ==", + "license": "MIT", + "dependencies": { + "array.prototype.flatmap": "1.2.4", + "commander": "^4.0.1", + "geometry-interfaces": "^1.1.4", + "glob": "^7.1.6", + "neatequal": "^1.0.0", + "readable-stream": "^3.4.0", + "sax": "^1.2.4", + "string.fromcodepoint": "^0.2.1", + "string.prototype.codepointat": "^0.2.1", + "svg-pathdata": "^5.0.2" + }, + "bin": { + "svgicons2svgfont": "bin/svgicons2svgfont.js" + }, + "engines": { + "node": ">=6.9.5" + } + }, + "node_modules/svgicons2svgfont/node_modules/array.prototype.flatmap": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz", + "integrity": "sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1", + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svgicons2svgfont/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/svgicons2svgfont/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/svgpath": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/svgpath/-/svgpath-2.6.0.tgz", @@ -20750,6 +20705,19 @@ "node": ">=6" } }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", @@ -20824,6 +20792,346 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==" }, + "node_modules/ttf2eot": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ttf2eot/-/ttf2eot-2.0.0.tgz", + "integrity": "sha512-U56aG2Ylw7psLOmakjemAzmpqVgeadwENg9oaDjaZG5NYX4WB6+7h74bNPcc+0BXsoU5A/XWiHabDXyzFOmsxQ==", + "license": "MIT", + "dependencies": { + "argparse": "^1.0.6", + "microbuffer": "^1.0.0" + }, + "bin": { + "ttf2eot": "ttf2eot.js" + } + }, + "node_modules/ttf2woff": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ttf2woff/-/ttf2woff-2.0.2.tgz", + "integrity": "sha512-X68badwBjAy/+itU49scLjXUL094up+rHuYk+YAOTTBYSUMOmLZ7VyhZJuqQESj1gnyLAC2/5V8Euv+mExmyPA==", + "license": "MIT", + "dependencies": { + "argparse": "^1.0.6", + "microbuffer": "^1.0.0", + "pako": "^1.0.0" + }, + "bin": { + "ttf2woff": "ttf2woff.js" + } + }, + "node_modules/ttf2woff/node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "license": "(MIT AND Zlib)" + }, + "node_modules/ttf2woff2": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ttf2woff2/-/ttf2woff2-3.0.0.tgz", + "integrity": "sha512-5/Web6B0lF/STNAQ0d5vAlRRquuWsNj8wOmKQ9ql9Bsgbx8MsLnNzaBG9vBcSE4s4Ry1QOr/MyUrDUIVgVPEfw==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "bindings": "^1.3.0", + "bufferstreams": "^2.0.1", + "nan": "^2.10.0", + "node-gyp": "^4.0.0" + }, + "bin": { + "ttf2woff2": "bin/ttf2woff2.js" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/ttf2woff2/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ttf2woff2/node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "license": "ISC" + }, + "node_modules/ttf2woff2/node_modules/are-we-there-yet": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "node_modules/ttf2woff2/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "license": "ISC" + }, + "node_modules/ttf2woff2/node_modules/fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "license": "ISC", + "dependencies": { + "minipass": "^2.6.0" + } + }, + "node_modules/ttf2woff2/node_modules/gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/ttf2woff2/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ttf2woff2/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "license": "MIT", + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ttf2woff2/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/ttf2woff2/node_modules/minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "license": "ISC", + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/ttf2woff2/node_modules/minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "license": "MIT", + "dependencies": { + "minipass": "^2.9.0" + } + }, + "node_modules/ttf2woff2/node_modules/node-gyp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-4.0.0.tgz", + "integrity": "sha512-2XiryJ8sICNo6ej8d0idXDEMKfVfFK7kekGCtJAuelGsYHQxhj13KTf95swTCN2dZ/4lTfZ84Fu31jqJEEgjWA==", + "license": "MIT", + "dependencies": { + "glob": "^7.0.3", + "graceful-fs": "^4.1.2", + "mkdirp": "^0.5.0", + "nopt": "2 || 3", + "npmlog": "0 || 1 || 2 || 3 || 4", + "osenv": "0", + "request": "^2.87.0", + "rimraf": "2", + "semver": "~5.3.0", + "tar": "^4.4.8", + "which": "1" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/ttf2woff2/node_modules/nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", + "license": "ISC", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/ttf2woff2/node_modules/npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "node_modules/ttf2woff2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/ttf2woff2/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/ttf2woff2/node_modules/semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha512-mfmm3/H9+67MCVix1h+IXTpDwL6710LyHuk7+cWC9T1mE0qz4iHhh6r4hU2wrIT9iTsAAC2XQRvfblL028cpLw==", + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/ttf2woff2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/ttf2woff2/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "license": "MIT", + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ttf2woff2/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ttf2woff2/node_modules/tar": { + "version": "4.4.19", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", + "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", + "license": "ISC", + "dependencies": { + "chownr": "^1.1.4", + "fs-minipass": "^1.2.7", + "minipass": "^2.9.0", + "minizlib": "^1.3.3", + "mkdirp": "^0.5.5", + "safe-buffer": "^5.2.1", + "yallist": "^3.1.1" + }, + "engines": { + "node": ">=4.5" + } + }, + "node_modules/ttf2woff2/node_modules/tar/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/ttf2woff2/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, "node_modules/tuf-js": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-2.2.0.tgz", @@ -20950,6 +21258,24 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "license": "Unlicense" + }, "node_modules/type": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", @@ -21000,7 +21326,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -21014,7 +21339,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -21033,7 +21357,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", - "dev": true, "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", @@ -21053,7 +21376,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -21168,7 +21490,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", @@ -21508,6 +21829,26 @@ "node": ">= 0.8" } }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/verror/node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "license": "MIT" + }, "node_modules/vite": { "version": "5.1.7", "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.7.tgz", @@ -22026,6 +22367,42 @@ "defaults": "^1.0.3" } }, + "node_modules/webfonts-generator-casaper": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/webfonts-generator-casaper/-/webfonts-generator-casaper-0.5.2.tgz", + "integrity": "sha512-beM/bZ/N+ajdldAwrILYKWnHNgMje9MwetYM52lJ15CLOGliyt82m3g39y2cZoi/Ca+Wqs8NKMhMrNOYYgX6Qg==", + "license": "Unlicense", + "dependencies": { + "handlebars": "^4.0.5", + "mkdirp": "^1.0.4", + "q": "^1.1.2", + "svg2ttf": "^5.0.0", + "svgicons2svgfont": "^9.1.1", + "ttf2eot": "^2.0.0", + "ttf2woff": "^2.0.1", + "ttf2woff2": "^3.0.0", + "underscore": "^1.7.0", + "url-join": "^4.0.1" + } + }, + "node_modules/webfonts-generator-casaper/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/webfonts-generator-casaper/node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", + "license": "MIT" + }, "node_modules/webpack": { "version": "5.90.3", "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.3.tgz", @@ -22463,7 +22840,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, "dependencies": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", @@ -22520,7 +22896,6 @@ "version": "1.1.15", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", - "dev": true, "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", @@ -22665,6 +23040,15 @@ "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==", "dev": true }, + "node_modules/xmldom": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.5.0.tgz", + "integrity": "sha512-Foaj5FXVzgn7xFzsKeNIde9g6aFBxTPi37iwsno8QvApmtg7KYrr+OPyRHcJF7dud2a5nGRBXK3n0dL62Gf7PA==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -26219,11 +26603,6 @@ "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==", "dev": true }, - "@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==" - }, "@tsconfig/node10": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", @@ -27005,131 +27384,6 @@ "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.1.0.tgz", "integrity": "sha512-wO4Dk/rm8u7RNhOf95ZzcEmC9rYOncYgvq4z3duaJrCgjN8BxAnDVyndanfcJZ0O6XZzHz6Q0hTimxTg8Y9g/A==" }, - "@vusion/webfonts-generator": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@vusion/webfonts-generator/-/webfonts-generator-0.8.0.tgz", - "integrity": "sha512-1q17CF6umBEjlAtO37TzRw3aOCCAyFX+T4HPG70BmM6qx8s6H4/LQOa8eHFZq/oiMuMyd0FehKgUt/pqYlIMWA==", - "requires": { - "handlebars": "^4.0.11", - "mkdirp": "^1.0.4", - "q": "^1.1.2", - "svg2ttf": "^6.0.3", - "svgicons2svgfont": "^10.0.4", - "ttf2eot": "^3.0.0", - "ttf2woff": "^3.0.0", - "ttf2woff2": "^4.0.4", - "underscore": "^1.9.1", - "url-join": "^4.0.0" - }, - "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "bufferstreams": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bufferstreams/-/bufferstreams-3.0.0.tgz", - "integrity": "sha512-Qg0ggJUWJq90vtg4lDsGN9CDWvzBMQxhiEkSOD/sJfYt6BLect3eV1/S6K7SCSKJ34n60rf6U5eUPmQENVE4UA==", - "requires": { - "readable-stream": "^3.4.0" - } - }, - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" - }, - "svg-pathdata": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/svg-pathdata/-/svg-pathdata-6.0.3.tgz", - "integrity": "sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw==" - }, - "svg2ttf": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/svg2ttf/-/svg2ttf-6.0.3.tgz", - "integrity": "sha512-CgqMyZrbOPpc+WqH7aga4JWkDPso23EgypLsbQ6gN3uoPWwwiLjXvzgrwGADBExvCRJrWFzAeK1bSoSpE7ixSQ==", - "requires": { - "@xmldom/xmldom": "^0.7.2", - "argparse": "^2.0.1", - "cubic2quad": "^1.2.1", - "lodash": "^4.17.10", - "microbuffer": "^1.0.0", - "svgpath": "^2.1.5" - } - }, - "svgicons2svgfont": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/svgicons2svgfont/-/svgicons2svgfont-10.0.6.tgz", - "integrity": "sha512-fUgQEVg3XwTbOHvlXahHGqCet5Wvfo1bV4DCvbSRvjsOCPCRunYbG4dUJCPegps37BMph3eOrfoobhH5AWuC6A==", - "requires": { - "commander": "^7.2.0", - "geometry-interfaces": "^1.1.4", - "glob": "^7.1.6", - "neatequal": "^1.0.0", - "readable-stream": "^3.4.0", - "sax": "^1.2.4", - "svg-pathdata": "^6.0.0" - } - }, - "ttf2eot": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/ttf2eot/-/ttf2eot-3.1.0.tgz", - "integrity": "sha512-aHTbcYosNHVqb2Qtt9Xfta77ae/5y0VfdwNLUS6sGBeGr22cX2JDMo/i5h3uuOf+FAD3akYOr17+fYd5NK8aXw==", - "requires": { - "argparse": "^2.0.1" - } - }, - "ttf2woff": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ttf2woff/-/ttf2woff-3.0.0.tgz", - "integrity": "sha512-OvmFcj70PhmAsVQKfC15XoKH55cRWuaRzvr2fpTNhTNer6JBpG8n6vOhRrIgxMjcikyYt88xqYXMMVapJ4Rjvg==", - "requires": { - "argparse": "^2.0.1", - "pako": "^1.0.0" - } - }, - "ttf2woff2": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/ttf2woff2/-/ttf2woff2-4.0.5.tgz", - "integrity": "sha512-zpoU0NopfjoyVqkFeQ722SyKk/n607mm5OHxuDS/wCCSy82B8H3hHXrezftA2KMbKqfJIjie2lsJHdvPnBGbsw==", - "requires": { - "bindings": "^1.5.0", - "bufferstreams": "^3.0.0", - "nan": "^2.14.2", - "node-gyp": "^9.0.0" - } - }, - "url-join": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", - "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" - } - } - }, "@w11k/ngx-componentdestroyed": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/@w11k/ngx-componentdestroyed/-/ngx-componentdestroyed-5.0.2.tgz", @@ -27289,11 +27543,6 @@ "html2canvas": "^1.4.1" } }, - "@xmldom/xmldom": { - "version": "0.7.13", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.13.tgz", - "integrity": "sha512-lm2GW5PkosIzccsaZIz7tp8cPADSIlIHWDFTR1N0SzfinhhYgeIQjFMz4rYzanCScr3DqQLeomUDArp6MWKm+g==" - }, "@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", @@ -27392,22 +27641,6 @@ } } }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "requires": { - "debug": "4" - } - }, - "agentkeepalive": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", - "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", - "requires": { - "humanize-ms": "^1.2.1" - } - }, "aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -27772,20 +28005,6 @@ } } }, - "aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" - }, - "are-we-there-yet": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", - "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - } - }, "arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -27835,7 +28054,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", - "dev": true, "requires": { "call-bind": "^1.0.5", "is-array-buffer": "^3.0.4" @@ -27976,7 +28194,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", - "dev": true, "requires": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.5", @@ -27988,6 +28205,19 @@ "is-shared-array-buffer": "^1.0.2" } }, + "asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" + }, "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", @@ -28009,8 +28239,7 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "atoa": { "version": "1.0.0", @@ -28049,11 +28278,20 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dev": true, "requires": { "possible-typed-array-names": "^1.0.0" } }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==" + }, + "aws4": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.0.tgz", + "integrity": "sha512-3AungXC4I8kKsS9PuS4JH2nc+0bVY/mjgrephHTIi8fpEeGsTHBUJeosp0Wc1myYMElmD0B3Oc4XL/HVJ4PV2g==" + }, "axe-core": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", @@ -28249,6 +28487,14 @@ "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "requires": { + "tweetnacl": "^0.14.3" + } + }, "big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", @@ -28409,6 +28655,43 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, + "bufferstreams": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bufferstreams/-/bufferstreams-2.0.1.tgz", + "integrity": "sha512-ZswyIoBfFb3cVDsnZLLj2IDJ/0ppYdil/v2EGlZXvoefO689FokEmFEldhN5dV7R2QBxFneqTJOMIpfqhj+n0g==", + "requires": { + "readable-stream": "^2.3.6" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "builtins": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.1.0.tgz", @@ -28427,60 +28710,6 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==" }, - "cacache": { - "version": "17.1.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-17.1.3.tgz", - "integrity": "sha512-jAdjGxmPxZh0IipMdR7fK/4sDSrHMLUV0+GvVUsjwyGNKHsh79kW/otg+GkbXwl6Uzvy9wsvHOX4nUoWldeZMg==", - "requires": { - "@npmcli/fs": "^3.1.0", - "fs-minipass": "^3.0.0", - "glob": "^10.2.2", - "lru-cache": "^7.7.1", - "minipass": "^5.0.0", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "p-map": "^4.0.0", - "ssri": "^10.0.0", - "tar": "^6.1.11", - "unique-filename": "^3.0.0" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "requires": { - "balanced-match": "^1.0.0" - } - }, - "glob": { - "version": "10.3.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.3.tgz", - "integrity": "sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw==", - "requires": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.0.3", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" - } - }, - "lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==" - }, - "minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, "cache-base": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", @@ -28534,6 +28763,11 @@ "rsvp": "^4.8.4" } }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" + }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -28669,6 +28903,11 @@ "shallow-clone": "^3.0.0" } }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==" + }, "codemirror": { "version": "5.65.16", "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.16.tgz", @@ -28697,11 +28936,6 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" - }, "colorette": { "version": "2.0.20", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", @@ -28717,7 +28951,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -29254,11 +29487,18 @@ "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", "dev": true }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "requires": { + "assert-plus": "^1.0.0" + } + }, "data-view-buffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", - "dev": true, "requires": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -29269,7 +29509,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", - "dev": true, "requires": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -29280,7 +29519,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", - "dev": true, "requires": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -29408,7 +29646,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, "requires": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -29433,8 +29670,7 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, "delegates": { "version": "1.0.0", @@ -29627,6 +29863,15 @@ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -29794,7 +30039,6 @@ "version": "1.23.3", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", - "dev": true, "requires": { "array-buffer-byte-length": "^1.0.1", "arraybuffer.prototype.slice": "^1.0.3", @@ -29894,7 +30138,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", - "dev": true, "requires": { "es-errors": "^1.3.0" } @@ -29903,7 +30146,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", - "dev": true, "requires": { "get-intrinsic": "^1.2.4", "has-tostringtag": "^1.0.2", @@ -29923,7 +30165,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, "requires": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -30821,8 +31062,7 @@ "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, "extend-shallow": { "version": "2.0.1", @@ -30869,6 +31109,11 @@ "to-regex": "^3.0.1" } }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==" + }, "eyes": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", @@ -31119,7 +31364,6 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, "requires": { "is-callable": "^1.1.3" } @@ -31155,6 +31399,11 @@ } } }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==" + }, "form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -31246,7 +31495,6 @@ "version": "1.1.6", "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -31257,23 +31505,7 @@ "functions-have-names": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true - }, - "gauge": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", - "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", - "requires": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^3.0.7", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" - } + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==" }, "gensync": { "version": "1.0.0-beta.2", @@ -31358,7 +31590,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", - "dev": true, "requires": { "call-bind": "^1.0.5", "es-errors": "^1.3.0", @@ -31371,6 +31602,14 @@ "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", "dev": true }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "requires": { + "assert-plus": "^1.0.0" + } + }, "gl-matrix": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.4.3.tgz", @@ -31432,7 +31671,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dev": true, "requires": { "define-properties": "^1.1.3" } @@ -31715,11 +31953,42 @@ "typeof-article": "^0.1.1" } }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==" + }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + } + } + }, "has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==" }, "has-flag": { "version": "3.0.0", @@ -31748,7 +32017,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, "requires": { "has-symbols": "^1.0.3" } @@ -32002,16 +32270,6 @@ "requires-port": "^1.0.0" } }, - "http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "requires": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - } - }, "http-proxy-middleware": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", @@ -32087,13 +32345,14 @@ } } }, - "https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", "requires": { - "agent-base": "6", - "debug": "4" + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" } }, "human-signals": { @@ -32101,14 +32360,6 @@ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==" }, - "humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", - "requires": { - "ms": "^2.0.0" - } - }, "i18n-js": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/i18n-js/-/i18n-js-4.4.3.tgz", @@ -32292,7 +32543,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", - "dev": true, "requires": { "es-errors": "^1.3.0", "hasown": "^2.0.0", @@ -32327,7 +32577,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", - "dev": true, "requires": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.1" @@ -32351,7 +32600,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, "requires": { "has-bigints": "^1.0.1" } @@ -32368,7 +32616,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, "requires": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -32377,8 +32624,7 @@ "is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==" }, "is-core-module": { "version": "2.13.1", @@ -32401,7 +32647,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", - "dev": true, "requires": { "is-typed-array": "^1.1.13" } @@ -32410,7 +32655,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, "requires": { "has-tostringtag": "^1.0.0" } @@ -32500,8 +32744,7 @@ "is-negative-zero": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "dev": true + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==" }, "is-number": { "version": "4.0.0", @@ -32513,7 +32756,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, "requires": { "has-tostringtag": "^1.0.0" } @@ -32571,7 +32813,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, "requires": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -32596,7 +32837,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", - "dev": true, "requires": { "call-bind": "^1.0.7" } @@ -32610,7 +32850,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, "requires": { "has-tostringtag": "^1.0.0" } @@ -32619,7 +32858,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, "requires": { "has-symbols": "^1.0.2" } @@ -32628,11 +32866,15 @@ "version": "1.1.13", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "dev": true, "requires": { "which-typed-array": "^1.1.14" } }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + }, "is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", @@ -32648,7 +32890,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, "requires": { "call-bind": "^1.0.2" } @@ -32685,8 +32926,7 @@ "isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" }, "isbinaryfile": { "version": "4.0.10", @@ -32715,6 +32955,11 @@ "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", "dev": true }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" + }, "istanbul-lib-coverage": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", @@ -33047,6 +33292,11 @@ "esprima": "^4.0.0" } }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" + }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -33068,6 +33318,11 @@ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.1.tgz", "integrity": "sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg==" }, + "json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + }, "json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -33082,8 +33337,7 @@ "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" }, "json5": { "version": "2.2.3", @@ -33120,6 +33374,17 @@ "through": ">=2.2.7 <3" } }, + "jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, "jsx-ast-utils": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", @@ -33710,35 +33975,6 @@ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" }, - "make-fetch-happen": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", - "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", - "requires": { - "agentkeepalive": "^4.2.1", - "cacache": "^17.0.0", - "http-cache-semantics": "^4.1.1", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^7.7.1", - "minipass": "^5.0.0", - "minipass-fetch": "^3.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^7.0.0", - "ssri": "^10.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==" - } - } - }, "make-plural": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-7.3.0.tgz", @@ -33939,29 +34175,6 @@ "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==" }, - "minipass-collect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", - "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "requires": { - "minipass": "^3.0.0" - }, - "dependencies": { - "minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "requires": { - "yallist": "^4.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } - } - }, "minipass-fetch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.3.tgz", @@ -34326,39 +34539,6 @@ "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==" }, - "node-gyp": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.0.tgz", - "integrity": "sha512-dMXsYP6gc9rRbejLXmTbVRYjAHw7ppswsKyMxuxJxxOHzluIO1rGp9TOQgjFJ+2MCqcOcQTOPB/8Xwhr+7s4Eg==", - "requires": { - "env-paths": "^2.2.0", - "exponential-backoff": "^3.1.1", - "glob": "^7.1.4", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^11.0.3", - "nopt": "^6.0.0", - "npmlog": "^6.0.0", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.2", - "which": "^2.0.2" - }, - "dependencies": { - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, "node-gyp-build": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", @@ -34382,14 +34562,6 @@ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" }, - "nopt": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", - "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", - "requires": { - "abbrev": "^1.0.0" - } - }, "normalize-package-data": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.0.tgz", @@ -34575,17 +34747,6 @@ "path-key": "^3.0.0" } }, - "npmlog": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", - "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", - "requires": { - "are-we-there-yet": "^3.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^4.0.3", - "set-blocking": "^2.0.0" - } - }, "nth-check": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", @@ -34594,6 +34755,11 @@ "boolbase": "^1.0.0" } }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==" + }, "nx": { "version": "18.2.4", "resolved": "https://registry.npmjs.org/nx/-/nx-18.2.4.tgz", @@ -34748,11 +34914,15 @@ } } }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, "object-copy": { "version": "0.1.0", @@ -34809,8 +34979,7 @@ "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" }, "object-visit": { "version": "1.0.1", @@ -34825,7 +34994,6 @@ "version": "4.1.5", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dev": true, "requires": { "call-bind": "^1.0.5", "define-properties": "^1.2.1", @@ -35034,11 +35202,25 @@ } } }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==" + }, "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==" }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -35310,6 +35492,11 @@ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" + }, "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -35424,8 +35611,7 @@ "possible-typed-array-names": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "dev": true + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==" }, "postcss": { "version": "8.4.31", @@ -35591,6 +35777,11 @@ "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", "optional": true }, + "psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" + }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -35854,7 +36045,6 @@ "version": "1.5.2", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", - "dev": true, "requires": { "call-bind": "^1.0.6", "define-properties": "^1.2.1", @@ -35937,6 +36127,55 @@ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==" }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==" + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + } + } + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -36112,7 +36351,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", - "dev": true, "requires": { "call-bind": "^1.0.7", "get-intrinsic": "^1.2.4", @@ -36138,7 +36376,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", - "dev": true, "requires": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -36464,7 +36701,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dev": true, "requires": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -36731,16 +36967,6 @@ "smart-buffer": "^4.2.0" } }, - "socks-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", - "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", - "requires": { - "agent-base": "^6.0.2", - "debug": "^4.3.3", - "socks": "^2.6.2" - } - }, "source-map": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", @@ -37013,6 +37239,22 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, + "sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, "ssri": { "version": "10.0.4", "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.4.tgz", @@ -37150,6 +37392,16 @@ } } }, + "string.fromcodepoint": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string.fromcodepoint/-/string.fromcodepoint-0.2.1.tgz", + "integrity": "sha512-n69H31OnxSGSZyZbgBlvYIXlrMhJQ0dQAX1js1QDhpaUH6zmU3QYlj07bCwCNlPOu3oRXIubGPl2gDGnHsiCqg==" + }, + "string.prototype.codepointat": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz", + "integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==" + }, "string.prototype.matchall": { "version": "4.0.11", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", @@ -37174,7 +37426,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", - "dev": true, "requires": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -37186,7 +37437,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", - "dev": true, "requires": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -37197,7 +37447,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "dev": true, "requires": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -37272,6 +37521,79 @@ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" }, + "svg-pathdata": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/svg-pathdata/-/svg-pathdata-5.0.5.tgz", + "integrity": "sha512-TAAvLNSE3fEhyl/Da19JWfMAdhSXTYeviXsLSoDT1UM76ADj5ndwAPX1FKQEgB/gFMPavOy6tOqfalXKUiXrow==" + }, + "svg2ttf": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/svg2ttf/-/svg2ttf-5.2.0.tgz", + "integrity": "sha512-CzxPnSm2/CrMnJuKlXVllOx+q9wuarbIMi4Vf14eJoeESRqAOxVZiH0Ias71mhyXYGgz88A4T/E8fN/Y8eXoYA==", + "requires": { + "argparse": "^2.0.1", + "cubic2quad": "^1.0.0", + "lodash": "^4.17.10", + "microbuffer": "^1.0.0", + "svgpath": "^2.1.5", + "xmldom": "~0.5.0" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + } + } + }, + "svgicons2svgfont": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/svgicons2svgfont/-/svgicons2svgfont-9.2.0.tgz", + "integrity": "sha512-mWeiuob7L2ZTcnAEP4JvSQ1pnIsGjV16ykQ0fCiiXqoUAQ/iNsDvBc601ojjfP89eCPtr3IVZ9mDxYpdxYO3xQ==", + "requires": { + "array.prototype.flatmap": "1.2.4", + "commander": "^4.0.1", + "geometry-interfaces": "^1.1.4", + "glob": "^7.1.6", + "neatequal": "^1.0.0", + "readable-stream": "^3.4.0", + "sax": "^1.2.4", + "string.fromcodepoint": "^0.2.1", + "string.prototype.codepointat": "^0.2.1", + "svg-pathdata": "^5.0.2" + }, + "dependencies": { + "array.prototype.flatmap": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz", + "integrity": "sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q==", + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1", + "function-bind": "^1.1.1" + } + }, + "commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==" + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, "svgpath": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/svgpath/-/svgpath-2.6.0.tgz", @@ -37790,6 +38112,15 @@ "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", "dev": true }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, "tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", @@ -37839,6 +38170,254 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==" }, + "ttf2eot": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ttf2eot/-/ttf2eot-2.0.0.tgz", + "integrity": "sha512-U56aG2Ylw7psLOmakjemAzmpqVgeadwENg9oaDjaZG5NYX4WB6+7h74bNPcc+0BXsoU5A/XWiHabDXyzFOmsxQ==", + "requires": { + "argparse": "^1.0.6", + "microbuffer": "^1.0.0" + } + }, + "ttf2woff": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ttf2woff/-/ttf2woff-2.0.2.tgz", + "integrity": "sha512-X68badwBjAy/+itU49scLjXUL094up+rHuYk+YAOTTBYSUMOmLZ7VyhZJuqQESj1gnyLAC2/5V8Euv+mExmyPA==", + "requires": { + "argparse": "^1.0.6", + "microbuffer": "^1.0.0", + "pako": "^1.0.0" + }, + "dependencies": { + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + } + } + }, + "ttf2woff2": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ttf2woff2/-/ttf2woff2-3.0.0.tgz", + "integrity": "sha512-5/Web6B0lF/STNAQ0d5vAlRRquuWsNj8wOmKQ9ql9Bsgbx8MsLnNzaBG9vBcSE4s4Ry1QOr/MyUrDUIVgVPEfw==", + "requires": { + "bindings": "^1.3.0", + "bufferstreams": "^2.0.1", + "nan": "^2.10.0", + "node-gyp": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==" + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "are-we-there-yet": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "requires": { + "minipass": "^2.6.0" + } + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==", + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "requires": { + "minipass": "^2.9.0" + } + }, + "node-gyp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-4.0.0.tgz", + "integrity": "sha512-2XiryJ8sICNo6ej8d0idXDEMKfVfFK7kekGCtJAuelGsYHQxhj13KTf95swTCN2dZ/4lTfZ84Fu31jqJEEgjWA==", + "requires": { + "glob": "^7.0.3", + "graceful-fs": "^4.1.2", + "mkdirp": "^0.5.0", + "nopt": "2 || 3", + "npmlog": "0 || 1 || 2 || 3 || 4", + "osenv": "0", + "request": "^2.87.0", + "rimraf": "2", + "semver": "~5.3.0", + "tar": "^4.4.8", + "which": "1" + } + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", + "requires": { + "abbrev": "1" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + } + }, + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha512-mfmm3/H9+67MCVix1h+IXTpDwL6710LyHuk7+cWC9T1mE0qz4iHhh6r4hU2wrIT9iTsAAC2XQRvfblL028cpLw==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "tar": { + "version": "4.4.19", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", + "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", + "requires": { + "chownr": "^1.1.4", + "fs-minipass": "^1.2.7", + "minipass": "^2.9.0", + "minizlib": "^1.3.3", + "mkdirp": "^0.5.5", + "safe-buffer": "^5.2.1", + "yallist": "^3.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + } + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + } + } + }, "tuf-js": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-2.2.0.tgz", @@ -37934,6 +38513,19 @@ } } }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" + }, "type": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", @@ -37972,7 +38564,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", - "dev": true, "requires": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -37983,7 +38574,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", - "dev": true, "requires": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -37996,7 +38586,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", - "dev": true, "requires": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", @@ -38010,7 +38599,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", - "dev": true, "requires": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -38086,7 +38674,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, "requires": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", @@ -38341,6 +38928,23 @@ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" + } + } + }, "vite": { "version": "5.1.7", "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.7.tgz", @@ -38578,6 +39182,35 @@ "defaults": "^1.0.3" } }, + "webfonts-generator-casaper": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/webfonts-generator-casaper/-/webfonts-generator-casaper-0.5.2.tgz", + "integrity": "sha512-beM/bZ/N+ajdldAwrILYKWnHNgMje9MwetYM52lJ15CLOGliyt82m3g39y2cZoi/Ca+Wqs8NKMhMrNOYYgX6Qg==", + "requires": { + "handlebars": "^4.0.5", + "mkdirp": "^1.0.4", + "q": "^1.1.2", + "svg2ttf": "^5.0.0", + "svgicons2svgfont": "^9.1.1", + "ttf2eot": "^2.0.0", + "ttf2woff": "^2.0.1", + "ttf2woff2": "^3.0.0", + "underscore": "^1.7.0", + "url-join": "^4.0.1" + }, + "dependencies": { + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + }, + "url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" + } + } + }, "webpack": { "version": "5.90.3", "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.3.tgz", @@ -38862,7 +39495,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, "requires": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", @@ -38907,7 +39539,6 @@ "version": "1.1.15", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", - "dev": true, "requires": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", @@ -39006,6 +39637,11 @@ "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==", "dev": true }, + "xmldom": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.5.0.tgz", + "integrity": "sha512-Foaj5FXVzgn7xFzsKeNIde9g6aFBxTPi37iwsno8QvApmtg7KYrr+OPyRHcJF7dud2a5nGRBXK3n0dL62Gf7PA==" + }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", From c1e46072e92398761b886f8679a86319145f7655 Mon Sep 17 00:00:00 2001 From: Aaron Contreras Date: Tue, 4 Jun 2024 10:34:17 -0500 Subject: [PATCH 142/176] Ensure only valid durations are accepted Strings such as "Hello world" aren't durations and hence, should not be parsed or continue through to the services. An early validation at the controller level guards against these. --- .../work_packages/progress_controller.rb | 15 ++++++++------- app/services/duration_converter.rb | 1 + 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/app/controllers/work_packages/progress_controller.rb b/app/controllers/work_packages/progress_controller.rb index e56e7c558d12..d9e5cfa196a4 100644 --- a/app/controllers/work_packages/progress_controller.rb +++ b/app/controllers/work_packages/progress_controller.rb @@ -131,13 +131,14 @@ def extract_persisted_progress_attributes def work_package_params params.require(:work_package) .permit(allowed_params).tap do |wp_params| - if wp_params["estimated_hours"].present? - wp_params["estimated_hours"] = - DurationConverter.parse(wp_params["estimated_hours"]) - end - if wp_params["remaining_hours"].present? - wp_params["remaining_hours"] = - DurationConverter.parse(wp_params["remaining_hours"]) + %w[estimated_hours remaining_hours].each do |attr| + if wp_params[attr].present? + begin + wp_params[attr] = DurationConverter.parse(wp_params[attr]) + rescue ChronicDuration::DurationParseError + @work_package.errors.add(attr.to_sym, :invalid) + end + end end end end diff --git a/app/services/duration_converter.rb b/app/services/duration_converter.rb index 8d8a00e48936..0d6ddb66b049 100644 --- a/app/services/duration_converter.rb +++ b/app/services/duration_converter.rb @@ -93,6 +93,7 @@ def parse(duration_string) "hours" end + ChronicDuration.raise_exceptions = true ChronicDuration.parse(duration_string, keep_zero: true, default_unit:, From 0b0c3a8404c22b585d8c0e84520f6f04da269dca Mon Sep 17 00:00:00 2001 From: Eugene <110599815+daggett-doofus@users.noreply.github.com> Date: Tue, 4 Jun 2024 23:15:18 +0200 Subject: [PATCH 143/176] add logos feature for support Ukraine (#15360) * add logos feature for support Ukraine --- app/assets/images/logo-black-bg-ua.png | Bin 0 -> 9346 bytes app/assets/images/logo-white-bg-ua.png | Bin 0 -> 8863 bytes app/views/custom_styles/_inline_css_logo.erb | 54 +++++++++++-------- 3 files changed, 32 insertions(+), 22 deletions(-) create mode 100644 app/assets/images/logo-black-bg-ua.png create mode 100644 app/assets/images/logo-white-bg-ua.png diff --git a/app/assets/images/logo-black-bg-ua.png b/app/assets/images/logo-black-bg-ua.png new file mode 100644 index 0000000000000000000000000000000000000000..176f3cf46da3516fc82f5c909afdc8d7029a26c3 GIT binary patch literal 9346 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 literal 0 HcmV?d00001 diff --git a/app/assets/images/logo-white-bg-ua.png b/app/assets/images/logo-white-bg-ua.png new file mode 100644 index 0000000000000000000000000000000000000000..7278fdcf6d2a68ab21dda6739a9713a1dd3c18c9 GIT binary patch literal 8863 zcmW+*c|26#8@^)~BC;2e?8cH**6eE~WjBK+BPJBNUCT zWX&?hI+ihZzv*}XxS#vJ_nh~>=eg&c_kG@zXnDt&Q|6#zio-PAz$K`3Z#($QD=TX^SYs``%wcCKI0PYt$8d|U55(Ju3kMCfy&u}CUV zYU2WD{9t?OaQ=$l6Le>QTH)@QsxWmH{~tli_xbS+7U|Bxwv^;kQOh)s2jcdtj*-Fd zSTo8hmSYb$e<3d;qIOQBX6}~}KHddK4j0t_UZr^i04~#yYZeIU=KSEuasnoR)M%df zPu)4ZAG6}d{Am>OgQfGI!Xk$)bWw}Rsrj8XgUdff>4yq zgNl*@5h{YHuik1Jyc1>1U+)Bz^Q(s~MWYVCBfStoKQp|jle}~^0|t6Cygk-4!P%d$ zdN!%Mj^%)3Lc#Ffiop_-E{+I3CxJ8+E)_0v2E^9v&mcO4kUs{xv;t!3himv zMx3Iany0S7Ln6#Uz@-;wXDhpj7P}_dzD1d-y!tnkU9GX=Ue2hB@RTQDfr}v%B8RY0 zge@HqlO0{d?shKOGLsWmv2K&oUcu6-q-%|}9OQDcc7he(`(2Pc9(pZ4T^xwfZcQ+> z@$vgE{2Z1iZQInoe6r{Cpz2a0Yk53RX!XD5&u!v#gh~5!HDhNP_{L#b-&(L0k~fm@ z*`&C`|HLLm3!J8#D~Ly+mx_U;iVEU8*IYjCryE+RB??^)o~8XMnfK7Cbk^I9Q_EQl zu5kR#N&VwP7Kz5PU2oL#%Om;OMLGcfs?&>2r{7I%D7{rRQ7l3Gmwk_tJPR(SBuGFa z@CDNs(bpEAk0pSbk1Xv?jy*SWk~udYu4W@*86k2)5w(|qw3PLNo(n~@j}I<{N&mmu z`V73S)GmEAVc{_xd-S#xz}lVbjspyOO86ZCFk7cC;!Yi)f_OE^>@jLq5q%__Z0(x zst21nQaY953W-i5eOk`e|0SWu`XU$Ico!?4v}VA%HX_72dmijA%oi&J-MiND5n|m> zU4Ey*gs${YI+GhyG35{8M__(s{AjrYT758bsMm-THe2Mjx8BGPfHsDRUH;p5QGDFs zNHzlfMv<3OILTr}f2MJF>b2~I-e6_Ll;+JZtuEXZ>NRyejGdynbB*?Yuz5kbzg=Gy zDXm{KM+AWhj-JM%xv(>5`9NX8CbOA#UB^2bh;XQ#=TYXpfns{hV#0eZgi^7y^yAed z^4fjaE&<5{0$d>0)SQO&hPl?hKMGGGZJeHG9&Gx$Mp z0jmGB!k>gaJk|h_M}CGaKAFjL5jv4XY^|4jX7N@EP5pKB7-zVeYGr+Ny?nXVp;fh* z^Gj2gZ069YRV`yzoZJA9X@BHAVR8C}FwmIv z7_k>k+_yNH7s~eK%XKyAAMP)Cd#o)Nb$U2`7s6#Tm7RPOI_(vx?DSMHD9k5(EGjE@ zyLx(5qz4s_m=f4d_7SV-arbQm-AcxMy}OZyD0ASZGFy- zd?h?dp9@sSpc$Qh@nj$2a*w+{;q%3i&0L{h-KGk!^G$b+22pSp@ru_Mj52kY5g1e`eWt9O}4 zv+b3G!Fw5SXX?`{Xyn=siufc$V|#c(FB zs82pGV&z7Rr%ckm3Md9t=FZ%~Lat`6geuZ07RHJ+aR9sbJo^!>z|NY^k6<`k&TD*# z6MF3StvfS}fPlnwCd6T@u1+il)Wi5|wf5|F2{IkPF4*-Fl=RF?z7F*zDRPH1W0D8R zTnGmR_2`2sbw`|IQIxO90V_Yv$^DZ+o0Dx1E3`w1Gfv?-AzbTZdqUl8lF2T%LFmgpVu+yh^gs9zTpkrqS8 zLbo2e6W_*K3IWMkF8gUc5^8e1-xP*hJC0-wx9)a&+RtjIVYD&1g5zNboGt=yyxr*8 zjTj4?OPyppb(m)8TMs#yBYYeZAkK_a$n^~J`5QXs|Bp&Y_Ag1(YeNroV|644jywh* zy@y@>;^kGX89s6ST95akqt=f~7}SLABy8tzinHUuSKE^*@1oebM1V()C!%Ze65qP< z&@ul`5jHEObs*vjhZLf1Kw~MeaH}x^av+_sS?}4meOXyWq%Rpwax@$$nH1P2Aip+s zg5w%{S8KoI=Q_3QNV>cAM&oVcs~i$F#>rIWUVF1=uzBr2PRrXK{2WIG=Ef654A-BV z$4jVNc-u<@Zr8P(Q#L}A`;YBRAYx4pm>_N;|EhOVm9IkBkvs6IB`VoLd`p+)w9J$w zKuxw90`57r5-@Z;2TeHnt=lO4x85eqs- zH?Nkb{Pl$1JY%*uutcA}F*HKP*jbP>JtD`7kiDG;>RxwY}p?I|Sk z@FUYgn-R;4o)T^MgNxWLkbeM9(}B-l}PPOLRsy=ZoSt`)INb-+A4^5fs<-IBWg(rf!iOYowMO(G&k3K67&;8Pt1jxUqxjCz~9pBO4w zf7Qq|_=G4($idY8_eVTn1Ch8ZVg^Yx*Byx6PGok@yK?{4zWxc^=TBK};ICnaR0r_n zHzW=R+pV~=AbdB60708beuuw)y2YVVPQMnMw===QxT--LM|*=_0fvxeIzQ8At8&d{ z6=sqc<@~O3=kV2t6G0>Yp?Q;^Q_Wi`q(PIKM_ux}%Km+kx4*DOHhIHX^>TQs!#0Ni z8woG|v?ilP*B!C60CLfvVN4pJ*Xby#gr-<5L$gPD^`|i?-V|;8rU!SqrlTfV|0Slv zZgMB$+m4+upIPGF=Zj6m9->dj4rsvYp!q@ox}1}Hk)X(7^TBE0qFRr)KACYRrjt#e zV8p5mLOA1Jnb5GIyHx3Rs-`d?XKL)+vBuRnL*1#YyJPB0+w{b@J3YN?P; zF8p>+!I9Oc z%H^_JUuZn#BsDAK96(I!t%c1IQ|6Ey3iU?`_%8Un?6*MM_qg5lpRkgR$_0C$sEP*7 z1gnkTS*9)gC=0YyL*nv4cLYDTZPoi2pE0wc*`}2-Dl$SVM5Q3W^XW;|BAd2g?|yyL zi)fy>;jvt(bLCv2TYt$(%ClWor()2uYvx9oVb~6~f!#sG=aKaB=|BniKKOgzHX#xf z5+Z-SBdrbosByNJaJf46U8CzfCe`gI7JM!gG*rY%oKra5$@)uedeS15PDoheVV#F_ z=}nu<2}wDsffN@0Z1rDh|6G+__Mz*Qy9|YTa*{%ow>c$G=jBN8XjH$r*ykV4BD9TH zz3!emI=28zGno zP=Bq?=qT{;O6KD9y-cQO_Yvz)EM$%cC|h=Fq0S$t(PvLj)^Y343j>Bkt#@yy>oiXG z2vdWU+BK13eCq|6+8~*ymA8;= z;oc1vehRVgeY@AM_eNcIh4!e>`N&epVSL0n zyZ0a03#7Q4uzEv>>M^$%pq+c3hPa>POFG_`j_Q3eI&7Y|eXM40jPz!z&dALaEs#EZ zD36_QpH(Joh?i^~xrk>=d(}WqG~425!AR7E*Jb>D=WotcSG1@in4RH|xB0jiRV8xm zK1R2=<9yzqbKBLR-S4u#<6FVPXt91<~5#h8$iwI*EgW%k)rH3J?tLSF9EUq zO1_ovE4xRZ@vi6}*t-;RTg`^f$>}CvW5G4ZkG2}zc2eVzusxbic<}kzv$-PH3$OUc zi-!zkf;YOhA=z-z)%HK!(s6ISKKh`UPxJV=`64LeE4(-QA87gfSs}q$?$VunnW$g2 z4g8+`o6;V}U8EV_5h_HM+6f0;yhNt!RtUw7NS=uKRp)xf^{YyW*U(uvaah_!gy}id z+;1W$Jcw#yEk9q%E|IxKOrnHl)i1ur+L2a7yF*1g9>LxFqXaK6Ic%b>1?uzBn+AG9 zXYat?(c?arDYFp0(s2iWwBgi7xBUwZiLlV+r#BDlp;1cdB zVrg%Oz;?Fs^ZSY=pSr^}t2xAw9h~?Qw1-x-@gEoZB*xgWo_#U)+u6^Q+1_#ax;nho zU*%ky$VE4R*}0{|6`>!f&1d#gR0Pk729cJZQp~yb8Q2Z$JB9atV9&}v z6-c`4+iz>~=mf5q^gBf4ZZy2(y~i8`NTo&MpWB;_wC z=T#{MbX=_LEXKO`s(um$3IA$jC%A;+UxS=39xj;y8mJzC4_1v}EbtkEDHV^KhXC zJG!?&5`>tR9$xF~PgC^TKg_lQEJR|*SgOA#Jl?jH=doc=xBGhwsk+!Fk&@+h4;h5c z3bKlJ=4;)VQ{Cj!r)dAAxQXaVk+QoZA{n6ith*SIR|N+ck^I5`$E~dIFF1Z6oe!gqIb?3Vt#G<=|#W$Q~4k(Hc@GZ)qtDdH2V;nFIb_E*8CKB|pM+l4^~GyGCt08$VCQ12K=D z(W76!)+iKZ1I4)7`LI;;oW2IJ$DW7-fW*VI?MFun94#pfu*Q;Rwp->x((gt+OY>E7fG*<4oWq&!JGM-6jIuKA^s3iuC0@E6e}gQxEf^@nymCVngNPymg7m%B@y6=Ddki)npOZu5kddLLewX! zcM^;I){Yhl+2#chSphQ^pz~71IY0@++V13M3*HQGJ5x?gk!1k7VKRV=EoR3Q=zKgf zcMY*?=E@of%$gzIn+!}~E6)S4|Nas*NMqM7TLLfa7@<1m8pvU}qHszP?H$ZOmjPe9+&Ecj>LX%2EEY)etky}fDIVvfl=pP zmp-|Ad`e_+zvbW)FLWmZ-RW#{71MsgqiZqRiCjrAEQqz01WKPw%i;8~#MDVejVSc= z$2$vyBNc3*G=|tQ_dFMA?L?o|Is3?SP)G!biNwWI^V(QFIgDE1~)K;27m^qwtj=-7XFA{U#c8eocd0PXqwQHhOv>4Nys&uHb6ex(>(0tk z_u;*Prkx$W?ma@=BDwN2xNDCB_`M2m7LuqpvRJFLRj{o}*Jt`UHpJ`W5r?GngQG%6`3_=E${DDPjw^x0NZQ^sJ?=D?bmh)I|R9)&#`aO`mulH=AEc-0g zA+XlAFo&+BnZ4)G>~B4^SvI)qr`jlBy}>`)EnaDO3+hFmMX^u&0Fo`KReHobMaWgO zE*4TUV}J^1PCwl1&V~4G5o@nM*!?tN-&r7EBJ833jMo`w*jbP(YZR+**myx~dh^}U zCTDq?y|Ay}?G3|Ji_r37b$(6@x4OZ66EPDGBrO!Lq%%$W=jFX3g$PWTP4 zP^~2`3v@!<3sz5g(<}2=myTOEkEfVRX<4)(;=c^?^Wf2)_UZPM6eoAF=a^n_K>ol}_i5>jM+5*u7mRw(rGS#+V%+@b@f& zpLuPR6kEAtPw*XGvFSTGw9(Be5+eMv<5UZ?rKx#mSPy-#Zn9PGb&NEWYx<=8=5pAr zjoyKlB_D9l zrb#PD(v-+KlQ%x=jt!5UG_uLCtB7#1D+&oe3>D^AlvD4Cj0A}qYH|MYp39g#@bkF^ z9~c$MRiXXrS503q!rO_ejxTgY&5SeL1Fa&tv;_y9iq0>1|H=QDT{b8plfB%+@xe{> z&=`)Lh_nz+*GqU_UD6`ryY8xT=_CsM$t=^*NF}kO874D}rACuEEFIoUYH6fKzJio? zQ$NLXJZV$q5Q)9#QYL1E=lp#meRk>c(sK9>n2Z8E;fPwC{XH!VRNgLV*QdRkD1b4G~J3>KAwN%fUz7ZtO?#=p*9(%6j7LYmp(h{59QJye44(({#? zfufsH!Kw=IikxLDZpvcy#b!NB(ewzb7DPaNI+L(KxpacXtXKPewIw$u)MWWq3614s z#B_*~dXiB_K$ey0cAUW|%tceW-jyARkD;00QQh0b3P2t>ok56vXHwDWX@2{}D{Phd zy$wU=?&AJjDPBI(7C~bI%KhlYJb*)=U2L@tHT;+A@h0 zm6teo>J%XnY`?1l?8C2gu=*#!*H8XPlEW_@n;hU2{OXW}*AH%O@*;k5E{xzbQsW)$ zTPdAh#c3GBo$`%)=6B?*z$A~cGagm9?&=)gR@9q^HQ`h#Y6TJ(S3GLwJ-09gZV_fM zoL+d&Qn+Q@Flek;Y=Bs2=jH75KaG%Hu(*!OT!bHJu2uvz{iQy9f_b}~h#dLjC!cTLa-H2x z=xoQPFRi59hZ!4!%@r))tiFD?TC*cRxZx9OT4K95t#OC9-UnR_54NXn%OIyVO6%)< zi}S_WM0L!M_bJn(-8ojv%ty@SeHrsp^8=OD1?8`2BF0K9ZtLh*jII5#OmQr891HBB z6cVFnhyJ`6>(cY?D=sKycb_2IDb(uh!H>ZwPLRot{4An-2f8TBW3p+*zlxd@9DN*m zzo1DIUmKkRCWmWpx4m^#T>kTZK>dBzpRH|?)`7z)TS=-&pl8$F;bNJI8>PL|U1dwS>^LUOJg>dv%0f&XkMXFvFDE~tAmM&PN_P{q(n zxOD884-P~`!H;jpsN@hEXLAvRxq7zgfKRqV-EfOv(+2O4`ijnDVgqEp)8~1B6_A&4 zbfY`*pcLEuR+d&a%K*|3y>Zsoa|ssyQ5wQM5C5gaOZWl^W81;I1Y&_7C7{pPBMow`UCaN9>N9 z&tCI}KU^B@u&v|!{&g`y0GIJpn_CbHK@j`1Hqm#&8;*gX7_E?+UB7on*S_+V zUpe#w0ci{hyMW7%@yvoPF@GFKj~o{M4FY2JM1;3#JOaKxGaBuMwv`#$jGqDnz~9OW zv*%#1RQ|wrU=`~}r#QWm?X81K;YDepX+k$y!srVo&HJZMQcqDI^boO?RjTg%7w}-)n6EY zQknS7X9H^nC=hP*HGe45dIY-%02}WcW)e6rcvUQaRj{E|pA%#raj%a{y{o6#FK^Bw zym2&+`1q|74JzD-EZKp`-|P}gTS2>jWVX?u8Td~+MH*up3wrcwH;9Hm`QlK(7NA~~ zokPgw1ma85!o3jxp#6Yn6JXIv-As4YQ;+435gUZxn{Q}xH*FW7U8aV2 K3{ZM5&;AFDQi?zT literal 0 HcmV?d00001 diff --git a/app/views/custom_styles/_inline_css_logo.erb b/app/views/custom_styles/_inline_css_logo.erb index 9ac46c69ed8a..c08ea9449440 100644 --- a/app/views/custom_styles/_inline_css_logo.erb +++ b/app/views/custom_styles/_inline_css_logo.erb @@ -27,28 +27,38 @@ See COPYRIGHT and LICENSE files for more details. ++#%> -<% cache(CustomStyle.current) do %> - -<% end %> + .op-logo--link_high_contrast { + background-image: url(<%= OpenProject::Configuration.bim? ? high_contrast_bim_logo_url : high_contrast_logo_url %>); + } + From 65f45f060185144915ceb180bcf631ef8a1a0e38 Mon Sep 17 00:00:00 2001 From: OpenProject Actions CI Date: Wed, 5 Jun 2024 03:10:26 +0000 Subject: [PATCH 144/176] update locales from crowdin [ci skip] --- config/locales/crowdin/af.yml | 14 +-- config/locales/crowdin/ar.yml | 14 +-- config/locales/crowdin/az.yml | 14 +-- config/locales/crowdin/be.yml | 14 +-- config/locales/crowdin/bg.yml | 14 +-- config/locales/crowdin/ca.yml | 14 +-- config/locales/crowdin/ckb-IR.yml | 14 +-- config/locales/crowdin/cs.yml | 14 +-- config/locales/crowdin/da.yml | 14 +-- config/locales/crowdin/de.yml | 14 +-- config/locales/crowdin/el.yml | 14 +-- config/locales/crowdin/eo.yml | 14 +-- config/locales/crowdin/es.yml | 14 +-- config/locales/crowdin/et.yml | 14 +-- config/locales/crowdin/eu.yml | 14 +-- config/locales/crowdin/fa.yml | 14 +-- config/locales/crowdin/fi.yml | 14 +-- config/locales/crowdin/fil.yml | 14 +-- config/locales/crowdin/fr.yml | 14 +-- config/locales/crowdin/he.yml | 14 +-- config/locales/crowdin/hi.yml | 14 +-- config/locales/crowdin/hr.yml | 14 +-- config/locales/crowdin/hu.yml | 14 +-- config/locales/crowdin/id.yml | 14 +-- config/locales/crowdin/it.yml | 14 +-- config/locales/crowdin/ja.yml | 14 +-- config/locales/crowdin/js-no.yml | 6 +- config/locales/crowdin/js-ru.yml | 14 +-- config/locales/crowdin/js-zh-CN.yml | 10 +- config/locales/crowdin/ka.yml | 14 +-- config/locales/crowdin/kk.yml | 14 +-- config/locales/crowdin/ko.yml | 14 +-- config/locales/crowdin/lt.yml | 14 +-- config/locales/crowdin/lv.yml | 14 +-- config/locales/crowdin/mn.yml | 14 +-- config/locales/crowdin/ms.yml | 51 ++++------ config/locales/crowdin/ne.yml | 14 +-- config/locales/crowdin/nl.yml | 14 +-- config/locales/crowdin/no.yml | 93 ++++++++---------- config/locales/crowdin/pl.yml | 14 +-- config/locales/crowdin/pt-BR.yml | 14 +-- config/locales/crowdin/pt-PT.yml | 14 +-- config/locales/crowdin/ro.yml | 14 +-- config/locales/crowdin/ru.yml | 72 ++++++-------- config/locales/crowdin/rw.yml | 14 +-- config/locales/crowdin/si.yml | 14 +-- config/locales/crowdin/sk.yml | 14 +-- config/locales/crowdin/sl.yml | 14 +-- config/locales/crowdin/sr.yml | 14 +-- config/locales/crowdin/sv.yml | 14 +-- config/locales/crowdin/th.yml | 14 +-- config/locales/crowdin/tr.yml | 14 +-- config/locales/crowdin/uk.yml | 14 +-- config/locales/crowdin/uz.yml | 14 +-- config/locales/crowdin/vi.yml | 14 +-- config/locales/crowdin/zh-CN.yml | 95 ++++++++----------- config/locales/crowdin/zh-TW.yml | 14 +-- modules/boards/config/locales/crowdin/no.yml | 2 +- .../ldap_groups/config/locales/crowdin/no.yml | 2 +- modules/meeting/config/locales/crowdin/af.yml | 14 +++ modules/meeting/config/locales/crowdin/ar.yml | 14 +++ modules/meeting/config/locales/crowdin/az.yml | 14 +++ modules/meeting/config/locales/crowdin/be.yml | 14 +++ modules/meeting/config/locales/crowdin/bg.yml | 14 +++ modules/meeting/config/locales/crowdin/ca.yml | 14 +++ .../meeting/config/locales/crowdin/ckb-IR.yml | 14 +++ modules/meeting/config/locales/crowdin/cs.yml | 14 +++ modules/meeting/config/locales/crowdin/da.yml | 14 +++ modules/meeting/config/locales/crowdin/de.yml | 14 +++ modules/meeting/config/locales/crowdin/el.yml | 14 +++ modules/meeting/config/locales/crowdin/eo.yml | 14 +++ modules/meeting/config/locales/crowdin/es.yml | 14 +++ modules/meeting/config/locales/crowdin/et.yml | 14 +++ modules/meeting/config/locales/crowdin/eu.yml | 14 +++ modules/meeting/config/locales/crowdin/fa.yml | 14 +++ modules/meeting/config/locales/crowdin/fi.yml | 14 +++ .../meeting/config/locales/crowdin/fil.yml | 14 +++ modules/meeting/config/locales/crowdin/fr.yml | 14 +++ modules/meeting/config/locales/crowdin/he.yml | 14 +++ modules/meeting/config/locales/crowdin/hi.yml | 14 +++ modules/meeting/config/locales/crowdin/hr.yml | 14 +++ modules/meeting/config/locales/crowdin/hu.yml | 14 +++ modules/meeting/config/locales/crowdin/id.yml | 14 +++ modules/meeting/config/locales/crowdin/it.yml | 14 +++ modules/meeting/config/locales/crowdin/ja.yml | 14 +++ modules/meeting/config/locales/crowdin/ka.yml | 14 +++ modules/meeting/config/locales/crowdin/kk.yml | 14 +++ modules/meeting/config/locales/crowdin/ko.yml | 14 +++ modules/meeting/config/locales/crowdin/lt.yml | 14 +++ modules/meeting/config/locales/crowdin/lv.yml | 14 +++ modules/meeting/config/locales/crowdin/mn.yml | 14 +++ modules/meeting/config/locales/crowdin/ms.yml | 14 +++ modules/meeting/config/locales/crowdin/ne.yml | 14 +++ modules/meeting/config/locales/crowdin/nl.yml | 14 +++ modules/meeting/config/locales/crowdin/no.yml | 14 +++ modules/meeting/config/locales/crowdin/pl.yml | 14 +++ .../meeting/config/locales/crowdin/pt-BR.yml | 14 +++ .../meeting/config/locales/crowdin/pt-PT.yml | 14 +++ modules/meeting/config/locales/crowdin/ro.yml | 14 +++ modules/meeting/config/locales/crowdin/ru.yml | 14 +++ modules/meeting/config/locales/crowdin/rw.yml | 14 +++ modules/meeting/config/locales/crowdin/si.yml | 14 +++ modules/meeting/config/locales/crowdin/sk.yml | 14 +++ modules/meeting/config/locales/crowdin/sl.yml | 14 +++ modules/meeting/config/locales/crowdin/sr.yml | 14 +++ modules/meeting/config/locales/crowdin/sv.yml | 14 +++ modules/meeting/config/locales/crowdin/th.yml | 14 +++ modules/meeting/config/locales/crowdin/tr.yml | 14 +++ modules/meeting/config/locales/crowdin/uk.yml | 14 +++ modules/meeting/config/locales/crowdin/uz.yml | 14 +++ modules/meeting/config/locales/crowdin/vi.yml | 14 +++ .../meeting/config/locales/crowdin/zh-CN.yml | 14 +++ .../meeting/config/locales/crowdin/zh-TW.yml | 14 +++ .../config/locales/crowdin/no.yml | 12 +-- .../webhooks/config/locales/crowdin/no.yml | 26 ++--- 115 files changed, 972 insertions(+), 867 deletions(-) diff --git a/config/locales/crowdin/af.yml b/config/locales/crowdin/af.yml index e2d79b119133..56c7e97d96c2 100644 --- a/config/locales/crowdin/af.yml +++ b/config/locales/crowdin/af.yml @@ -1160,18 +1160,6 @@ af: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Verskilstelle" message: "Forums" @@ -2953,7 +2941,7 @@ af: setting_date_format: "Datum" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Default language" setting_default_projects_modules: "Default enabled modules for new projects" setting_default_projects_public: "Nuwe projekte is openbaar by verstek" diff --git a/config/locales/crowdin/ar.yml b/config/locales/crowdin/ar.yml index 506b0221f8db..6c6814a9096e 100644 --- a/config/locales/crowdin/ar.yml +++ b/config/locales/crowdin/ar.yml @@ -1220,18 +1220,6 @@ ar: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "مجموعة التغييرات" message: "منتديات" @@ -3091,7 +3079,7 @@ ar: setting_date_format: "التاريخ" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "اللغة الافتراضية" setting_default_projects_modules: "وحدات التمكين الافتراضية للمشاريع الجديدة" setting_default_projects_public: "هناك مشاريع جديدة عامة بشكل افتراضي" diff --git a/config/locales/crowdin/az.yml b/config/locales/crowdin/az.yml index 9fa95b623f9d..00ec786d618e 100644 --- a/config/locales/crowdin/az.yml +++ b/config/locales/crowdin/az.yml @@ -1160,18 +1160,6 @@ az: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Changesets" message: "Forums" @@ -2953,7 +2941,7 @@ az: setting_date_format: "Date" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Default language" setting_default_projects_modules: "Default enabled modules for new projects" setting_default_projects_public: "New projects are public by default" diff --git a/config/locales/crowdin/be.yml b/config/locales/crowdin/be.yml index b7213d7392e7..834af1a43be8 100644 --- a/config/locales/crowdin/be.yml +++ b/config/locales/crowdin/be.yml @@ -1190,18 +1190,6 @@ be: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Changesets" message: "Forums" @@ -3023,7 +3011,7 @@ be: setting_date_format: "Дата" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Default language" setting_default_projects_modules: "Default enabled modules for new projects" setting_default_projects_public: "New projects are public by default" diff --git a/config/locales/crowdin/bg.yml b/config/locales/crowdin/bg.yml index df20af17f9ec..2ec28fa73139 100644 --- a/config/locales/crowdin/bg.yml +++ b/config/locales/crowdin/bg.yml @@ -1160,18 +1160,6 @@ bg: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Набори от промени" message: "Форуми" @@ -2953,7 +2941,7 @@ bg: setting_date_format: "Дата" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Език по подразбиране" setting_default_projects_modules: "Default enabled modules for new projects" setting_default_projects_public: "New projects are public by default" diff --git a/config/locales/crowdin/ca.yml b/config/locales/crowdin/ca.yml index 5dab5b793912..515a8392841a 100644 --- a/config/locales/crowdin/ca.yml +++ b/config/locales/crowdin/ca.yml @@ -1156,18 +1156,6 @@ ca: other: "%{count} hores" updated: "canviat de %{old_value} a %{value}" logged_for: "Registrat per" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "eliminat" - updated: "canviat de %{old_value} a %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordenat" - work_package: - updated: "canviat de %{old_value} a %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Conjunt de canvis" message: "Fòrums" @@ -2942,7 +2930,7 @@ ca: setting_date_format: "Data" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Idioma per defecte" setting_default_projects_modules: "Mòduls activats per defecte en els projectes nous" setting_default_projects_public: "Els projectes nous són públics per defecte" diff --git a/config/locales/crowdin/ckb-IR.yml b/config/locales/crowdin/ckb-IR.yml index 5e41471b4455..9783c45b9de4 100644 --- a/config/locales/crowdin/ckb-IR.yml +++ b/config/locales/crowdin/ckb-IR.yml @@ -1160,18 +1160,6 @@ ckb-IR: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Changesets" message: "Forums" @@ -2953,7 +2941,7 @@ ckb-IR: setting_date_format: "Date" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Default language" setting_default_projects_modules: "Default enabled modules for new projects" setting_default_projects_public: "New projects are public by default" diff --git a/config/locales/crowdin/cs.yml b/config/locales/crowdin/cs.yml index 57311c479947..c51c8696874e 100644 --- a/config/locales/crowdin/cs.yml +++ b/config/locales/crowdin/cs.yml @@ -1190,18 +1190,6 @@ cs: other: "%{count} hodiny" updated: "změněno z %{old_value} na %{value}" logged_for: "Přihlášen " - meeting_agenda_item: - duration: - added: "nastavit na %{value}" - added_html: "nastavit na %{value}" - removed: "odstraněno" - updated: "změněno z %{old_value} na %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "změněno z %{old_value} na %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Změny" message: "Fóra" @@ -3022,7 +3010,7 @@ cs: setting_date_format: "Datum" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Výchozí jazyk" setting_default_projects_modules: "Výchozí zapnutné moduly pro nový projekt" setting_default_projects_public: "Nové projekty nastavovat jako veřejné" diff --git a/config/locales/crowdin/da.yml b/config/locales/crowdin/da.yml index b5f61013281a..1591e225ad36 100644 --- a/config/locales/crowdin/da.yml +++ b/config/locales/crowdin/da.yml @@ -1158,18 +1158,6 @@ da: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Pakker af ændringer" message: "Fora" @@ -2949,7 +2937,7 @@ da: setting_date_format: "Dato" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Forhåndsvalgt sprog" setting_default_projects_modules: "Forhåndsvalgt aktive moduler for nye projekter" setting_default_projects_public: "Nye projekter er på forhånd sat som offentlige" diff --git a/config/locales/crowdin/de.yml b/config/locales/crowdin/de.yml index 14a643a6c1da..2262f5325dd3 100644 --- a/config/locales/crowdin/de.yml +++ b/config/locales/crowdin/de.yml @@ -1155,18 +1155,6 @@ de: other: "%{count} Stunden" updated: "geändert von %{old_value} zu %{value}" logged_for: "Gebucht für" - meeting_agenda_item: - duration: - added: "auf %{value} eingestellt" - added_html: "auf %{value} eingestellt" - removed: "entfernt" - updated: "von %{old_value} zu %{value} geändert" - updated_html: "von %{old_value} zu %{value} geändert" - position: - updated: "neu geordnet" - work_package: - updated: "von %{old_value} zu %{value} geändert" - updated_html: "von %{old_value} zu %{value} geändert" filter: changeset: "Änderungssätze" message: "Foren" @@ -2948,7 +2936,7 @@ de: setting_date_format: "Datum" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Standard-Sprache" setting_default_projects_modules: "Standardmäßig aktivierte Module für neue Projekte" setting_default_projects_public: "Neue Projekte sind standardmäßig öffentlich" diff --git a/config/locales/crowdin/el.yml b/config/locales/crowdin/el.yml index 1b1e74b06bda..f110cb99d005 100644 --- a/config/locales/crowdin/el.yml +++ b/config/locales/crowdin/el.yml @@ -1156,18 +1156,6 @@ el: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Σύνολα Αλλαγών" message: "Φόρουμ" @@ -2948,7 +2936,7 @@ el: setting_date_format: "Ημερομηνία" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Προεπιλεγμένη γλώσσα" setting_default_projects_modules: "Ενότητα ενεργοποιημένες από προεπιλογή για τα νέα έργα" setting_default_projects_public: "Τα νέα έργα είναι δημόσια από προεπιλογή" diff --git a/config/locales/crowdin/eo.yml b/config/locales/crowdin/eo.yml index 9076e6fae3d1..8cacb55ff887 100644 --- a/config/locales/crowdin/eo.yml +++ b/config/locales/crowdin/eo.yml @@ -1160,18 +1160,6 @@ eo: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Ŝanĝaroj" message: "Forumoj" @@ -2953,7 +2941,7 @@ eo: setting_date_format: "Dato" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Default language" setting_default_projects_modules: "Default enabled modules for new projects" setting_default_projects_public: "New projects are public by default" diff --git a/config/locales/crowdin/es.yml b/config/locales/crowdin/es.yml index 85b21762f682..152d6eb01df5 100644 --- a/config/locales/crowdin/es.yml +++ b/config/locales/crowdin/es.yml @@ -1157,18 +1157,6 @@ es: other: "%{count} horas" updated: "cambiado de %{old_value} a %{value}" logged_for: "Registrado para" - meeting_agenda_item: - duration: - added: "fijado en %{value}" - added_html: "fijado en %{value}" - removed: "eliminado" - updated: "cambiado de %{old_value} a %{value}" - updated_html: "cambiado de %{old_value} a %{value}" - position: - updated: "reordenado" - work_package: - updated: "cambiado de %{old_value} a %{value}" - updated_html: "cambiado de %{old_value} a %{value}" filter: changeset: "Conjuntos de cambios" message: "Foros" @@ -2949,7 +2937,7 @@ es: setting_date_format: "Fecha" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Idioma predeterminado" setting_default_projects_modules: "Modulos activados por defecto para nuevos proyectos" setting_default_projects_public: "Nuevos proyectos son públicos por defecto" diff --git a/config/locales/crowdin/et.yml b/config/locales/crowdin/et.yml index f048098b9dee..218b9a9ad47b 100644 --- a/config/locales/crowdin/et.yml +++ b/config/locales/crowdin/et.yml @@ -1160,18 +1160,6 @@ et: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Toimikud" message: "Foorumid" @@ -2953,7 +2941,7 @@ et: setting_date_format: "Kuupäev" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Vaikimisi keel" setting_default_projects_modules: "Uue projekti vaikimisi moodulid" setting_default_projects_public: "Uued projektid on vaikimisi avalikud" diff --git a/config/locales/crowdin/eu.yml b/config/locales/crowdin/eu.yml index b2cb9bfd6cf8..5834b70abd83 100644 --- a/config/locales/crowdin/eu.yml +++ b/config/locales/crowdin/eu.yml @@ -1160,18 +1160,6 @@ eu: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Changesets" message: "Forums" @@ -2953,7 +2941,7 @@ eu: setting_date_format: "Date" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Default language" setting_default_projects_modules: "Default enabled modules for new projects" setting_default_projects_public: "New projects are public by default" diff --git a/config/locales/crowdin/fa.yml b/config/locales/crowdin/fa.yml index 222aad136e01..b974534ed50f 100644 --- a/config/locales/crowdin/fa.yml +++ b/config/locales/crowdin/fa.yml @@ -1160,18 +1160,6 @@ fa: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Changesets" message: "Forums" @@ -2953,7 +2941,7 @@ fa: setting_date_format: "تاریخ" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Default language" setting_default_projects_modules: "Default enabled modules for new projects" setting_default_projects_public: "New projects are public by default" diff --git a/config/locales/crowdin/fi.yml b/config/locales/crowdin/fi.yml index ccea99bb2195..f6a81986f13d 100644 --- a/config/locales/crowdin/fi.yml +++ b/config/locales/crowdin/fi.yml @@ -1160,18 +1160,6 @@ fi: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Muutosryhmät" message: "Keskustelupalstat" @@ -2953,7 +2941,7 @@ fi: setting_date_format: "Päivämäärä" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Vakiokieli" setting_default_projects_modules: "Oletusmodulit uusille projketeille" setting_default_projects_public: "Uudet projektit ovat oletuksena julkisia" diff --git a/config/locales/crowdin/fil.yml b/config/locales/crowdin/fil.yml index d9fc3d7d85c7..5fc508ce112f 100644 --- a/config/locales/crowdin/fil.yml +++ b/config/locales/crowdin/fil.yml @@ -1160,18 +1160,6 @@ fil: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Changesets" message: "Mga forum" @@ -2951,7 +2939,7 @@ fil: setting_date_format: "Petsa" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Default na linggwahe" setting_default_projects_modules: "I-default ang pinaganang mga modyul para sa bagong proyekto" setting_default_projects_public: "Bagong proyektong ay publiko sa pamamagitan ng default" diff --git a/config/locales/crowdin/fr.yml b/config/locales/crowdin/fr.yml index 5eb72e366034..2372d3248256 100644 --- a/config/locales/crowdin/fr.yml +++ b/config/locales/crowdin/fr.yml @@ -1160,18 +1160,6 @@ fr: other: "%{count} heures" updated: "modifié de %{old_value} à %{value}" logged_for: "Connecté(e) pendant" - meeting_agenda_item: - duration: - added: "défini sur %{value}" - added_html: "défini sur %{value}" - removed: "supprimé" - updated: "modifié de %{old_value} à %{value}" - updated_html: "modifié de %{old_value} à %{value}" - position: - updated: "réorganisé" - work_package: - updated: "modifié de %{old_value} à %{value}" - updated_html: "modifié de %{old_value} à %{value}" filter: changeset: "Révisions" message: "Forums" @@ -2953,7 +2941,7 @@ fr: setting_date_format: "Date" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Langage par défaut" setting_default_projects_modules: "Modules activés par défaut pour les nouveaux projets" setting_default_projects_public: "Les nouveaux projets sont publics par défaut" diff --git a/config/locales/crowdin/he.yml b/config/locales/crowdin/he.yml index 3cee5323b3a2..33bb962cf831 100644 --- a/config/locales/crowdin/he.yml +++ b/config/locales/crowdin/he.yml @@ -1190,18 +1190,6 @@ he: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "שינויים" message: "פורומים" @@ -3023,7 +3011,7 @@ he: setting_date_format: "תאריך" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Default language" setting_default_projects_modules: "Default enabled modules for new projects" setting_default_projects_public: "New projects are public by default" diff --git a/config/locales/crowdin/hi.yml b/config/locales/crowdin/hi.yml index b187b02e2ac3..fe1dd29095c9 100644 --- a/config/locales/crowdin/hi.yml +++ b/config/locales/crowdin/hi.yml @@ -1158,18 +1158,6 @@ hi: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Changesets" message: "मंच" @@ -2951,7 +2939,7 @@ hi: setting_date_format: "तिथि" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Default language" setting_default_projects_modules: "Default enabled modules for new projects" setting_default_projects_public: "New projects are public by default" diff --git a/config/locales/crowdin/hr.yml b/config/locales/crowdin/hr.yml index 80289f6df602..431560bee2ef 100644 --- a/config/locales/crowdin/hr.yml +++ b/config/locales/crowdin/hr.yml @@ -1175,18 +1175,6 @@ hr: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Changesets" message: "Forumi" @@ -2988,7 +2976,7 @@ hr: setting_date_format: "Datum" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Zadani jezik" setting_default_projects_modules: "Zadani omogućeni moduli za nove projekte" setting_default_projects_public: "Novi projekti su zadani kao javni" diff --git a/config/locales/crowdin/hu.yml b/config/locales/crowdin/hu.yml index 9e89df72c7b8..9bc6c74f86b3 100644 --- a/config/locales/crowdin/hu.yml +++ b/config/locales/crowdin/hu.yml @@ -1157,18 +1157,6 @@ hu: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Commit-ok" message: "Fórumok" @@ -2949,7 +2937,7 @@ hu: setting_date_format: "dátum" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Alapértelmezett nyelv" setting_default_projects_modules: "Az új projektekben alapértelmezetten engedélyezett modulok" setting_default_projects_public: "Új projektek nyilvánosak alapértelmezetten" diff --git a/config/locales/crowdin/id.yml b/config/locales/crowdin/id.yml index 0fe8a317c0b5..d088021d52ed 100644 --- a/config/locales/crowdin/id.yml +++ b/config/locales/crowdin/id.yml @@ -1138,18 +1138,6 @@ id: other: "Satu\n %{count} jam\n\n Lainnya\n %{count} jam" updated: "diubah dari %{old_value} menjadi %{value}" logged_for: "Masuk untuk" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "diubah dari %{old_value} menjadi %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "diubah dari %{old_value} menjadi %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Set perubahan" message: "Forum" @@ -2907,7 +2895,7 @@ id: setting_date_format: "Tanggal" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Bahasa default" setting_default_projects_modules: "Modul default aktif untuk Project baru" setting_default_projects_public: "Project baru default untuk publik" diff --git a/config/locales/crowdin/it.yml b/config/locales/crowdin/it.yml index d31d39e66407..1505cf26ed4b 100644 --- a/config/locales/crowdin/it.yml +++ b/config/locales/crowdin/it.yml @@ -1157,18 +1157,6 @@ it: other: "%{count} ore" updated: "modificato da %{old_value} a %{value}" logged_for: "Registrato per" - meeting_agenda_item: - duration: - added: "impostato a %{value}" - added_html: "impostato a %{value}" - removed: "rimosso" - updated: "modificato da %{old_value} a %{value}" - updated_html: "modificato da %{old_value} a %{value}" - position: - updated: "riordinato" - work_package: - updated: "modificato da %{old_value} a %{value}" - updated_html: "modificato da %{old_value} a %{value}" filter: changeset: "Insiemi di modifiche" message: "Forum" @@ -2950,7 +2938,7 @@ it: setting_date_format: "Data" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Linguaggio predefinito" setting_default_projects_modules: "Moduli abilitati in automatico su nuovi progetti" setting_default_projects_public: "I nuovi progetti sono pubblici come impostazione predefinita" diff --git a/config/locales/crowdin/ja.yml b/config/locales/crowdin/ja.yml index f7d7f03ee580..89e912cc08ae 100644 --- a/config/locales/crowdin/ja.yml +++ b/config/locales/crowdin/ja.yml @@ -1141,18 +1141,6 @@ ja: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "更新履歴" message: "フォーラム" @@ -2914,7 +2902,7 @@ ja: setting_date_format: "日付" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "デフォルトの言語" setting_default_projects_modules: "新規プロジェクトにおいてデフォルトで有効になるモジュール" setting_default_projects_public: "デフォルトで新しいプロジェクトは公開にする" diff --git a/config/locales/crowdin/js-no.yml b/config/locales/crowdin/js-no.yml index 7ed5fdd40b60..f560f80dd630 100644 --- a/config/locales/crowdin/js-no.yml +++ b/config/locales/crowdin/js-no.yml @@ -1284,9 +1284,9 @@ next_button: "Fortsett" exclusion_info: modal: - title: "Status excluded from hierarchy totals" + title: "Status ekskludert fra hierarkiske summer" content: >- - The status '%{status_name}' has been configured to be excluded from hierarchy totals of Work, Remaining work, and % Complete. The totals do not take this value into account. + Statusen '%{status_name}' er konfigurert til å bli ekskludert fra hierarkiske summer av Arbeid, Gjenstående arbeid og % Ferdig. Summene tar ikke hensyn til denne verdien. favorite_projects: no_results: "Du har ingen favorittprosjekter" no_results_subtext: "Legg til ett eller flere prosjekter som favoritt via oversikten eller i en prosjektliste." @@ -1347,7 +1347,7 @@ remove: "Fjern" drop_modal: focus_grab: "Dette er et fokusanker for modaler. Trykk shift+tab for å gå tilbake til modal trigger elementet." - close: "Close modal" + close: "Lukk modal" open_project_storage_modal: waiting_title: timeout: "Tidsavbrudd" diff --git a/config/locales/crowdin/js-ru.yml b/config/locales/crowdin/js-ru.yml index ed3b41847b0a..7c78db83986d 100644 --- a/config/locales/crowdin/js-ru.yml +++ b/config/locales/crowdin/js-ru.yml @@ -375,7 +375,7 @@ ru: ical_generation_error_text: "Произошла ошибка при генерации URL-адреса календаря." success_message: 'URL-адрес "%{name}" был успешно скопирован в ваш буфер обмена. Вставьте его в свой клиент календаря, чтобы завершить подписку.' label_activate: "Активировать" - label_assignee: "Ответственный" + label_assignee: "Назначенный" label_add_column_after: "Добавить столбец после" label_add_column_before: "Добавить столбец перед" label_add_columns: "Добавить столбец" @@ -612,7 +612,7 @@ ru: mentioned: "упомянутый" watched: "наблюдатель" assigned: "назначенный" - responsible: "подотчетный" + responsible: "ответственный" created: "создано" scheduled: "запланировано" commented: "прокомментировано" @@ -659,7 +659,7 @@ ru: message: "Есть новые уведомления." link_text: "Нажмите здесь, чтобы загрузить их." menu: - accountable: "Подотчетный" + accountable: "Ответственный" by_project: "Непрочитано по проекту" by_reason: "Причина" inbox: "Входящие" @@ -688,7 +688,7 @@ ru: title: "Упомянутые" description: "Получать уведомления каждый раз, когда кто-то упоминает меня" assignee: "Назначенный" - responsible: "Подотчетный" + responsible: "Ответственный" shared: "Общий доступ" watched: "Наблюдатель" work_package_commented: "Все новые комментарии" @@ -1289,9 +1289,9 @@ ru: next_button: "Продолжить" exclusion_info: modal: - title: "Status excluded from hierarchy totals" + title: "Статус исключён из иерархии итогов" content: >- - The status '%{status_name}' has been configured to be excluded from hierarchy totals of Work, Remaining work, and % Complete. The totals do not take this value into account. + Статус '%{status_name}' был настроен на исключение из иерархии итогов Работы, Оставшейся работы и % завершения. Итоговые показатели не учитывают это значение. favorite_projects: no_results: "У вас нет избранных проектов" no_results_subtext: "Добавьте один или несколько проектов в избранное через их обзор или в списке проектов." @@ -1352,7 +1352,7 @@ ru: remove: "Удалить" drop_modal: focus_grab: "Это якорь фокусировки для модальностей. Нажмите shift+ tab, чтобы вернуться к элементу модального триггера." - close: "Close modal" + close: "Закрыть диалоговое окно" open_project_storage_modal: waiting_title: timeout: "Время ожидания истекло" diff --git a/config/locales/crowdin/js-zh-CN.yml b/config/locales/crowdin/js-zh-CN.yml index 2a56d6dd3a72..a9e97fc4706e 100644 --- a/config/locales/crowdin/js-zh-CN.yml +++ b/config/locales/crowdin/js-zh-CN.yml @@ -1280,9 +1280,9 @@ zh-CN: next_button: "继续" exclusion_info: modal: - title: "Status excluded from hierarchy totals" + title: "从层次结构总计中排除的状态" content: >- - The status '%{status_name}' has been configured to be excluded from hierarchy totals of Work, Remaining work, and % Complete. The totals do not take this value into account. + 状态 "%{status_name}"已被配置为排除在 "工时"、"剩余工时 "和 "完成百分比 "的层次结构总计中。总计不考虑该值。 favorite_projects: no_results: "您没有收藏的项目" no_results_subtext: "通过项目概览或项目列表添加一个或多个项目作为收藏夹。" @@ -1343,12 +1343,12 @@ zh-CN: remove: "移除" drop_modal: focus_grab: "该信息是模态框的焦点锚点。按 Shift+Tab 可以返回到模态框的触发元素。" - close: "Close modal" + close: "关闭模式" open_project_storage_modal: waiting_title: - timeout: "Timeout" + timeout: "超时" waiting_subtitle: network_off: "网络有问题。" network_on: "网络已恢复。我们正在努力。" timeout: > - OpenProject could not provide you access to the project folder within the expected period of time. Please, try once again.

    If that problem persists please contact you OpenProject administrator to check the health status of the file storage setup. + OpenProject无法让您在预期时间内访问项目文件夹。请再试一次。

    如果问题仍然存在,请联系OpenProject管理员检查文件存储设置的运行状况。 diff --git a/config/locales/crowdin/ka.yml b/config/locales/crowdin/ka.yml index a618db30904c..0d98d5b23051 100644 --- a/config/locales/crowdin/ka.yml +++ b/config/locales/crowdin/ka.yml @@ -1160,18 +1160,6 @@ ka: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "რეგისტრაციის მიზეზი" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "ცვლილებები" message: "ფორუმები" @@ -2953,7 +2941,7 @@ ka: setting_date_format: "თარიღი" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Default language" setting_default_projects_modules: "Default enabled modules for new projects" setting_default_projects_public: "New projects are public by default" diff --git a/config/locales/crowdin/kk.yml b/config/locales/crowdin/kk.yml index 8e91e65dea25..e7bbb4ae4416 100644 --- a/config/locales/crowdin/kk.yml +++ b/config/locales/crowdin/kk.yml @@ -1160,18 +1160,6 @@ kk: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Changesets" message: "Forums" @@ -2953,7 +2941,7 @@ kk: setting_date_format: "Date" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Default language" setting_default_projects_modules: "Default enabled modules for new projects" setting_default_projects_public: "New projects are public by default" diff --git a/config/locales/crowdin/ko.yml b/config/locales/crowdin/ko.yml index 4ba8c5c921e7..c6c2bc0d0756 100644 --- a/config/locales/crowdin/ko.yml +++ b/config/locales/crowdin/ko.yml @@ -1144,18 +1144,6 @@ ko: other: "%{count}시간" updated: "%{old_value}에서 %{value}(으)로 변경됨" logged_for: "기록함 -" - meeting_agenda_item: - duration: - added: "%{value}(으)로 설정됨" - added_html: "%{value}(으)로 설정됨" - removed: "제거됨" - updated: "%{old_value}에서 %{value}(으)로 변경됨" - updated_html: "%{old_value}에서 %{value}(으)로 변경됨" - position: - updated: "재정렬됨" - work_package: - updated: "%{old_value}에서 %{value}(으)로 변경됨" - updated_html: "%{old_value}에서 %{value}(으)로 변경됨" filter: changeset: "변경 집합" message: "포럼" @@ -2914,7 +2902,7 @@ ko: setting_date_format: "날짜" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "기본 언어" setting_default_projects_modules: "새 프로젝트에 대해 기본적으로 활성화된 모듈" setting_default_projects_public: "새 프로젝트는 기본적으로 공용입니다." diff --git a/config/locales/crowdin/lt.yml b/config/locales/crowdin/lt.yml index d93404b5ab6f..6c4acc0d6a30 100644 --- a/config/locales/crowdin/lt.yml +++ b/config/locales/crowdin/lt.yml @@ -1187,18 +1187,6 @@ lt: other: "%{count} valandos" updated: "pakeitė iš %{old_value} į %{value}" logged_for: "Registruota" - meeting_agenda_item: - duration: - added: "nustatyti %{value}" - added_html: "nustatyti %{value}" - removed: "išimta" - updated: "pakeitė iš %{old_value} į %{value}" - updated_html: "pakeista iš %{old_value} į %{value}" - position: - updated: "perrikiuota" - work_package: - updated: "pakeista iš %{old_value} į %{value}" - updated_html: "pakeista iš %{old_value} į %{value}" filter: changeset: "Pakeitimų paketai" message: "Forumai" @@ -3016,7 +3004,7 @@ lt: setting_date_format: "Data" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Numatytoji kalba" setting_default_projects_modules: "Pagal nutylėjimą naujame projekte įjungti moduliai" setting_default_projects_public: "Nauji projektai yra vieši pagal nutylėjimą" diff --git a/config/locales/crowdin/lv.yml b/config/locales/crowdin/lv.yml index fee3e9ddbfa9..f3112f929518 100644 --- a/config/locales/crowdin/lv.yml +++ b/config/locales/crowdin/lv.yml @@ -1175,18 +1175,6 @@ lv: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Changesets" message: "Forums" @@ -2988,7 +2976,7 @@ lv: setting_date_format: "Datums" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Default language" setting_default_projects_modules: "Pēc noklusējuma aktivizētie moduļi jauniem projektiem" setting_default_projects_public: "New projects are public by default" diff --git a/config/locales/crowdin/mn.yml b/config/locales/crowdin/mn.yml index 5f29acaaa874..f4b2637f43df 100644 --- a/config/locales/crowdin/mn.yml +++ b/config/locales/crowdin/mn.yml @@ -1160,18 +1160,6 @@ mn: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Changesets" message: "Forums" @@ -2953,7 +2941,7 @@ mn: setting_date_format: "Date" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Default language" setting_default_projects_modules: "Default enabled modules for new projects" setting_default_projects_public: "New projects are public by default" diff --git a/config/locales/crowdin/ms.yml b/config/locales/crowdin/ms.yml index 5b08dd717475..4d630ae9fa2c 100644 --- a/config/locales/crowdin/ms.yml +++ b/config/locales/crowdin/ms.yml @@ -442,8 +442,7 @@ ms:
    Perhatian: Nilai yang diwarisi (cth, dari anak-anak atau saudara) masih akan digunakan. status_excluded_from_totals_text: |- - Check this option to exclude work packages with this status from totals of Work, - Remaining work, and % Complete in a hierarchy. + Tandakan pilihan ini untuk mengecualikan pakej kerja dengan status ini dari jumlah Kerja, Kerja yang berbaki, dan % Selesai dalam hierarki. status_color_text: | Klik untuk menugaskan atau menukar warna status ini. Ia ditunjukkan pada butang status dan boleh digunakan untuk menyoroti pakej kerja dalam jadual. @@ -452,9 +451,9 @@ ms: no_results_content_text: Tambah status baharu headers: is_default: "Default" - is_closed: "Closed" - is_readonly: "Read-only" - excluded_from_totals: "Excluded from totals" + is_closed: "Tertutup" + is_readonly: "Baca-sahaja" + excluded_from_totals: "Dikecualikan daripada jumlah" themes: light: "Terang" light_high_contrast: "Kontras tinggi yang terang" @@ -623,7 +622,7 @@ ms: status: is_closed: "Pakej kerja ditutup" is_readonly: "Pakej kerja baca-sahaja" - excluded_from_totals: "Exclude from calculation of totals in hierarchy" + excluded_from_totals: "Dikecualikan daripada pengiraan jumlah dalam hierarki" journal: notes: "Nota" member: @@ -960,7 +959,7 @@ ms: base: working_days_are_missing: "Sekurang-kurangnya sehari dalam seminggu perlu ditentukan sebagai hari bekerja." previous_working_day_changes_unprocessed: "Perubahan terdahulu pada konfigurasi hari bekerja belum dilaksanakan lagi." - hours_per_day_are_missing: "The number of hours per day must be defined." + hours_per_day_are_missing: "Bilangan jam dalam sehari perlu ditentukan." days_per_week_are_missing: "The number of days per week must be defined." days_per_month_are_missing: "The number of days per month must be defined." durations_are_not_positive_numbers: "The durations must be positive numbers." @@ -1144,18 +1143,6 @@ ms: other: "%{count} jam" updated: "ditukar dari %{old_value} kepada %{value}" logged_for: "Dilog untuk" - meeting_agenda_item: - duration: - added: "ditetapkan kepada %{value}" - added_html: "ditetapkan kepada %{value}" - removed: "dikeluarkan" - updated: "ditukar dari %{old_value} kepada %{value}" - updated_html: "ditukar dari %{old_value} kepada %{value}" - position: - updated: "disusun semula" - work_package: - updated: "ditukar dari %{old_value} kepada %{value}" - updated_html: "ditukar dari %{old_value} kepada %{value}" filter: changeset: "Set ubah suai" message: "Forum-forum" @@ -2915,7 +2902,7 @@ ms: setting_date_format: "Tarikh" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Bahasa default" setting_default_projects_modules: "Modul yang diaktifkan secara default untuk projek baharu" setting_default_projects_public: "Projek baharu adalah awam secara default" @@ -3310,10 +3297,10 @@ ms: menu_item: "Item menu" menu_item_setting: "Keterlihatan" wiki_menu_item_for: 'Item menu untuk halaman wiki "%{title}"' - wiki_menu_item_setting: "Penglihatan" + wiki_menu_item_setting: "Keterlihatan" wiki_menu_item_new_main_item_explanation: > - Anda sedang memadam item menu utama wiki yang tunggal. Anda kini perlu memilih halaman wiki di mana item menu baharu akan dijanakan. Untuk memadamkan modul wiki tersebut, ianya boleh dinyahaktifkan oleh pentadbir projek. - wiki_menu_item_delete_not_permitted: Item menu wiki bagi halaman wiki tunggal tidak boleh dipadam. + Anda sedang memadam satu-satunya item menu utama wiki. Anda kini perlu memilih halaman wiki di mana item menu baharu akan dijanakan. Untuk memadamkan modul wiki tersebut, ianya boleh dinyahaktifkan oleh pentadbir projek. + wiki_menu_item_delete_not_permitted: Item menu wiki bagi satu-satunya halaman wiki tidak boleh dipadam. #TODO: merge with work_packages top level key work_package: updated_automatically_by_child_changes: | @@ -3324,9 +3311,9 @@ ms: progress: label_note: "Perhatian:" modal: - work_based_help_text: "% Lengkap secara automatik diperolehi daripada Kerja dan Kerja yang berbaki." - status_based_help_text: "% Lengkap ditetapkan oleh status pakej kerja." - migration_warning_text: "Dalam mod pengiraan perkembangan berdasarkan kerja, % Lengkap tidak boleh ditetapkan secara manual dan ianya terikat dengan Kerja. Nilai sedia ada tersebut telah disimpan tetapi tidak boleh diedit. Sila input Kerja dahulu." + work_based_help_text: "% Selesai secara automatik diperolehi daripada Kerja dan Kerja yang berbaki." + status_based_help_text: "% Selesai ditetapkan oleh status pakej kerja." + migration_warning_text: "Dalam mod pengiraan perkembangan berdasarkan kerja, % Selesai tidak boleh ditetapkan secara manual dan ianya terikat kepada Kerja. Nilai sedia ada tersebut telah disimpan tetapi tidak boleh diedit. Sila input Kerja dahulu." sharing: count: zero: "0 pengguna" @@ -3344,7 +3331,7 @@ ms: label_toggle_all: "Tukar semua perkongsian" permissions: comment: "Komen" - comment_description: "Boleh lihat dan komen tentang pakej kerja ini." + comment_description: "Boleh lihat dan komen berkenaan pakej kerja ini." denied: "Anda tidak mempunyai kebenaran untuk berkongsi pakej kerja." edit: "Edit" edit_description: "Boleh lihat, komen dan edit pakej kerja ini." @@ -3357,7 +3344,7 @@ ms: text_empty_state_description: "Pakej kerja masih belum dikongsikan dengan sesiapa lagi." text_empty_state_header: "Tidak dikongsikan" text_user_limit_reached: "Menambah pengguna tambahan akan melebihi had semasa. Sila hubungi pentadbir untuk meningkatkan had pengguna bagi memastikan pengguna luaran dapat mengakses pakej kerja ini." - text_user_limit_reached_admins: 'Menambah pengguna tambahan akan melebihi had semasa. Sila naik taraf pelan anda untuk dapat menambah lebih banyak pengguna.' + text_user_limit_reached_admins: 'Menambah pengguna tambahan akan melebihi had semasa. Sila naik taraf pelan anda untuk membolehkan untuk menambah lebih banyak pengguna.' warning_user_limit_reached: > Menambah pengguna tambahan akan melebihi had semasa. Sila hubungi pentadbir untuk meningkatkan had pengguna bagi memastikan pengguna luaran dapat mengakses pakej kerja ini. warning_user_limit_reached_admin: > @@ -3377,12 +3364,12 @@ ms: additional_privileges_project_or_group: "Mungkin mempunyai keistimewaan tambahan (sebagai ahli projek atau kumpulan)" working_days: info: > - Days that are not selected are skipped when scheduling work packages (and not included in the day count). These can be overridden at a work-package level. + Hari yang tidak dipilih akan dilangkau semasa penjadualan pakej kerja (dan tidak termasuk dalam kiraan hari). Ini boleh digantikan di peringkat pakej-kerja. instance_wide_info: > - Tarikh yang ditambah ke senarai dibawah diterima sebagai tidak berfungsi dan dilangkau semasa menjadualkan pakej kerja. + Tarikh yang ditambah ke senarai dibawah diterima sebagai tidak berfungsi dan dilangkau semasa penjadualan pakej kerja. change_button: "Tukar hari bekerja" warning: > - Changing which days of the week are considered working days or non-working days can affect the start and finish days of all work packages in all projects in this instance. + Penukaran hari dalam seminggu yang dianggap sebagai hari bekerja atau hari tidak bekerja akan mempengaruhi hari mula dan akhir semua pakej kerja dalam semua projek bagi contoh ini. journal_note: changed: _**Hari bekerja** telah diubah (%{changes})._ days: @@ -3419,7 +3406,7 @@ ms: invalid_relation: "Hubungan tersebut adalah tidak sah." invalid_resource: "Untuk ciri-ciri '%{property}' sebuah pautan seperti '%{expected}' dijangkakan, tetapi mendapat '%{actual}'." invalid_signal: - embed: "Permintaan menyemat %{invalid} tidak disokong. Penyematan yang disokong adalah %{supported}." + embed: "Permintaan menyemat %{invalid} tidak disokong. Penyematan yang disokong ialah %{supported}." select: "Permintaan %{invalid} yang dipilih tidak disokong. Pilihan yang disokong ialah %{supported}." invalid_user_status_transition: "Status akaun pengguna semasa tidak membenarkan operasi ini." missing_content_type: "tidak ditentukan" diff --git a/config/locales/crowdin/ne.yml b/config/locales/crowdin/ne.yml index 27dc9706228d..17210a739714 100644 --- a/config/locales/crowdin/ne.yml +++ b/config/locales/crowdin/ne.yml @@ -1160,18 +1160,6 @@ ne: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Changesets" message: "Forums" @@ -2953,7 +2941,7 @@ ne: setting_date_format: "Date" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Default language" setting_default_projects_modules: "Default enabled modules for new projects" setting_default_projects_public: "New projects are public by default" diff --git a/config/locales/crowdin/nl.yml b/config/locales/crowdin/nl.yml index c24392461d01..d872d443a45a 100644 --- a/config/locales/crowdin/nl.yml +++ b/config/locales/crowdin/nl.yml @@ -1157,18 +1157,6 @@ nl: other: "%{count} uur" updated: "veranderd van %{old_value} naar %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "veranderd van %{old_value} naar %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "veranderd van %{old_value} naar %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Wijzigingensets" message: "Fora" @@ -2949,7 +2937,7 @@ nl: setting_date_format: "Datum" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Standaard taal" setting_default_projects_modules: "Standaard actieve modules voor nieuwe projecten" setting_default_projects_public: "Nieuwe projecten zijn standaard publiek" diff --git a/config/locales/crowdin/no.yml b/config/locales/crowdin/no.yml index 0a1b9b7102c2..1747eab6485c 100644 --- a/config/locales/crowdin/no.yml +++ b/config/locales/crowdin/no.yml @@ -266,7 +266,7 @@ my: "Mine prosjekter" favored: "Favorittprosjekter" archived: "Arkiverte prosjekter" - public: "Public project lists" + public: "Offentlige prosjektlister" my_private: "Mine private prosjektlister" new: placeholder: "Ny prosjektliste" @@ -294,12 +294,12 @@ actions: label_enable_single: "Aktivert i dette prosjektet, klikk for å deaktivere" label_disable_single: "Deaktivert i dette prosjektet, klikk for å aktivere" - deactivate_for_project: "Deactivate for this project" + deactivate_for_project: "Deaktiver for dette prosjektet" label_enable_all: "Aktiver alle" label_disable_all: "Deaktiver alle" is_required_blank_slate: - heading: Required in all projects - description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + heading: Påkrevd i alle prosjekter + description: Prosjektattributten er aktivert i alle prosjekter fordi "Påkrevd i alle prosjekter"-alternativet er valgt. Attributten kan ikke deaktiveres for hvert enkelt prosjekt. types: no_results_title_text: Det finnes ingen tilgjengelige typer. form: @@ -317,11 +317,11 @@ success: "Den endrede listen er lagret" failure: "Den endrede listen kan ikke lagres: %{errors}" publish: - success: "The list has been made public" - failure: "The list cannot be made public: %{errors}" + success: "Listen er blitt offentliggjort" + failure: "Listen kan ikke offentliggjøres: %{errors}" unpublish: - success: "The list has been made private" - failure: "The list cannot be made private: %{errors}" + success: "Listen er blitt gjort privat" + failure: "Listen kan ikke gjøres privat: %{errors}" can_be_saved: "Listen endret:" can_be_saved_as: "Endringene kan bare lagres i en ny liste." members: @@ -449,8 +449,7 @@
    Merknad: Arvede verdier (for eksempel fra barn eller relasjoner) vil fortsatt gjelde. status_excluded_from_totals_text: |- - Check this option to exclude work packages with this status from totals of Work, - Remaining work, and % Complete in a hierarchy. + Velg denne innstillingen for å utelukke arbeidspakker med denne statusen fra oppsummeringer for Arbeid, Gjenstående arbeid og % Ferdig i et hierarki. status_color_text: | Klikk for å tilknytte eller endre fargen på denne statusen. Den vises i statusknappen og kan brukes til å fremheve arbeidspakker i tabellen. @@ -458,10 +457,10 @@ no_results_title_text: Det er for tiden ingen status for arbeidspakken. no_results_content_text: Legg til en ny status headers: - is_default: "Default" - is_closed: "Closed" - is_readonly: "Read-only" - excluded_from_totals: "Excluded from totals" + is_default: "Standard" + is_closed: "Lukket" + is_readonly: "Kun lesetilgang" + excluded_from_totals: "Unntatt fra totaler" themes: light: "Lyst" light_high_contrast: "Lys høy kontrast" @@ -631,7 +630,7 @@ status: is_closed: "Arbeidspakke lukket" is_readonly: "Arbeidspakken er skrivebeskyttet" - excluded_from_totals: "Exclude from calculation of totals in hierarchy" + excluded_from_totals: "Unnta fra beregning av totaler i hierarki" journal: notes: "Notater" member: @@ -772,7 +771,7 @@ before_or_equal_to: "må være før eller lik %{date}." blank: "kan ikke være blank." blank_nested: "må ha egenskapen '%{property}' aktivert." - cannot_delete_mapping: "is required. Cannot be deleted." + cannot_delete_mapping: "er påkrevd. Kan ikke slettes." cant_link_a_work_package_with_a_descendant: "En arbeidspakke kan ikke knyttes til en av sine deloppgaver." circular_dependency: "En slik relasjon ville lage en sirkulær avhengighet." confirmation: "samsvarer ikke med %{attribute}." @@ -933,8 +932,8 @@ nonexistent: "Kolonnen '%{column}' eksisterer ikke." format: "%{message}" group_by_hierarchies_exclusive: "er gjensidig eksklusiv med grupper med '%{group_by}'. Du kan ikke aktivere begge." - can_only_be_modified_by_owner: "The query can only be modified by its owner." - need_permission_to_modify_public_query: "You cannot modify a public query." + can_only_be_modified_by_owner: "Spørringen kan bare endres av sin eier." + need_permission_to_modify_public_query: "Du kan ikke endre på et offentlig søk." filters: custom_fields: inexistent: "Det er ikke noe egendefinert felt for filteret." @@ -968,14 +967,14 @@ base: working_days_are_missing: "Minst en ukedag må defineres som en virkedag." previous_working_day_changes_unprocessed: "De tidligere endringene i konfigurasjonen av arbeidsdager har ikke blitt brukt ennå." - hours_per_day_are_missing: "The number of hours per day must be defined." - days_per_week_are_missing: "The number of days per week must be defined." - days_per_month_are_missing: "The number of days per month must be defined." - durations_are_not_positive_numbers: "The durations must be positive numbers." - hours_per_day_is_out_of_bounds: "Hours per day can't be more than 24" - days_per_week_is_out_of_bounds: "Days per week can't be more than 7" - days_per_month_is_out_of_bounds: "Days per month can't be more than 31" - days_per_week_and_days_per_month_are_inconsistent: "The number of days per week and the number of days per month must be consistent." + hours_per_day_are_missing: "Antall timer per dag må defineres." + days_per_week_are_missing: "Antall dager per uke må være definert." + days_per_month_are_missing: "Antall dager per måned må defineres." + durations_are_not_positive_numbers: "Varigheten må være positive tall." + hours_per_day_is_out_of_bounds: "Timer per dag kan ikke være mer enn 24" + days_per_week_is_out_of_bounds: "Dager per uke kan ikke være mer enn 7" + days_per_month_is_out_of_bounds: "Dager per måned kan ikke være mer enn 31" + days_per_week_and_days_per_month_are_inconsistent: "Antall dager per uke og antall dager per måned må være konsekvent." time_entry: attributes: hours: @@ -1160,18 +1159,6 @@ other: "%{count} timer" updated: "endret fra %{old_value} til %{value}" logged_for: "Logget for" - meeting_agenda_item: - duration: - added: "satt til %{value}" - added_html: "satt til %{value}" - removed: "fjernet" - updated: "endret fra %{old_value} til %{value}" - updated_html: "endret fra %{old_value} til %{value}" - position: - updated: "omsortert" - work_package: - updated: "endret fra %{old_value} til %{value}" - updated_html: "endret fra %{old_value} til %{value}" filter: changeset: "Changesets" message: "Forum" @@ -1350,8 +1337,8 @@ button_revoke_access: "Fjern tilgang" button_revoke_all: "Fjern alle" button_revoke_only: "Fjern kun %{shared_role_name}" - button_publish: "Make public" - button_unpublish: "Make private" + button_publish: "Offentliggjør" + button_unpublish: "Gjør privat" consent: checkbox_label: Jeg har merket meg og samtykker til det ovenfor. failure_message: Samtykke mislyktes, kan ikke fortsette. @@ -1692,9 +1679,9 @@ working: "%{date} er nå arbeidsdag" non_working: "%{date} er nå arbeidsfri" progress_mode_changed_to_status_based: Framdriftsmodus satt til statusbasert - status_excluded_from_totals_set_to_false_message: now included in hierarchy totals - status_excluded_from_totals_set_to_true_message: now excluded from hierarchy totals - status_percent_complete_changed: "% complete changed from %{old_value}% to %{new_value}%" + status_excluded_from_totals_set_to_false_message: nå inkludert i hierarkiske summer + status_excluded_from_totals_set_to_true_message: nå ekskludert fra hierarkiske summer + status_percent_complete_changed: "% ferdig endret fra %{old_value}% til %{new_value}%" system_update: file_links_journal: > Fra nå av vil aktivitet knyttet til linker (filer lagret i eksterne lagringer) vises her i aktivitetsfanen. Følgende representerer aktivitet med lenker som allerede eksisterer: @@ -2351,7 +2338,7 @@ label_workflow: "Arbeidsflyt" label_workflow_plural: "Arbeidsflyt" label_workflow_summary: "Sammendrag" - label_working_days_and_hours: "Working days and hours" + label_working_days_and_hours: "Arbeidsdager og timer" label_x_closed_work_packages_abbr: one: "1 lukket" other: "%{count} stengt" @@ -2735,7 +2722,7 @@ permission_save_bcf_queries: "Lagre BCF-spørringer" permission_manage_public_bcf_queries: "Administrere offentlige BCF-spørringer" permission_edit_attribute_help_texts: "Rediger hjelpetekster for egenskap" - permission_manage_public_project_queries: "Manage public project lists" + permission_manage_public_project_queries: "Administrere offentlige prosjektlister" placeholders: default: "-" project: @@ -2951,9 +2938,9 @@ setting_cross_project_work_package_relations: "Tillat relasjoner mellom arbeidspakker i ulike prosjekter" setting_first_week_of_year: "Første uke i år inneholder" setting_date_format: "Dato" - setting_days_per_month: "Days per month" + setting_days_per_month: "Dager per måned" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Standardspråk" setting_default_projects_modules: "Standardaktiverte moduler for nye prosjekter" setting_default_projects_public: "Nye prosjekter er offentlige som standard" @@ -2969,12 +2956,12 @@ setting_feeds_limit: "Innholdsgrense for Feed" setting_file_max_size_displayed: "Maks størrelse på tekstfiler som vises inline" setting_host_name: "Vertsnavn" - setting_hours_per_day: "Hours per day" + setting_hours_per_day: "Timer per dag" setting_hours_per_day_explanation: >- - This will define what is considered a "day" when displaying duration in a more natural way (for example, if a day is 8 hours, 32 hours would be 4 days). - setting_days_per_week: "Days per week" + Dette vil definere hva som anses som en "dag" når varigheten vises på en mer naturlig måte (for eksempel hvis dagen er 8 timer, vil 32 timer være 4 dager). + setting_days_per_week: "Dager per uke" setting_days_per_week_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a week is 5 days, 15 days would be 3 weeks). + Denne vil definere hva som regnes som en "uke" når varigheten vises på en mer naturlig måte (for eksempel hvis en uke er på 5 dager, er 15 dager 3 uker). setting_invitation_expiration_days: "Aktiverings e-post utløper etter" setting_work_package_done_ratio: "Beregning av fremdrift" setting_work_package_done_ratio_field: "Arbeidsbasert" @@ -3416,12 +3403,12 @@ additional_privileges_project_or_group: "Kan ha flere privilegier (som prosjekt- eller gruppemedlem)" working_days: info: > - Days that are not selected are skipped when scheduling work packages (and not included in the day count). These can be overridden at a work-package level. + Hoppet over dager som ikke er valgt ved planlegging av arbeidspakker (og ikke inkludert i antall dager). Disse kan overstyres på arbeidspakkenivå. instance_wide_info: > Datoer som er lagt til i listen nedenfor regnes som arbeidsfrie og hoppet over når arbeidspakker planlegges. change_button: "Endre arbeidsdager" warning: > - Changing which days of the week are considered working days or non-working days can affect the start and finish days of all work packages in all projects in this instance. + Endring av hvilke ukedager som regnes som arbeidsdager eller arbeidsfrie dager kan påvirke start- og sluttdager for alle arbeidspakker i alle prosjekter i denne forekomsten. journal_note: changed: _**Arbeidsdager** endret (%{changes})._ days: diff --git a/config/locales/crowdin/pl.yml b/config/locales/crowdin/pl.yml index d2120e18fd5a..3617c79bd8c6 100644 --- a/config/locales/crowdin/pl.yml +++ b/config/locales/crowdin/pl.yml @@ -1187,18 +1187,6 @@ pl: other: "%{count} godziny" updated: "zmieniono z %{old_value} na %{value}" logged_for: "Zalogowano przez" - meeting_agenda_item: - duration: - added: "ustawiono na %{value}" - added_html: "ustawiono na %{value}" - removed: "usunięto" - updated: "zmieniono z %{old_value} na %{value}" - updated_html: "zmieniono z %{old_value} na %{value}" - position: - updated: "zmieniono kolejność" - work_package: - updated: "zmieniono z %{old_value} na %{value}" - updated_html: "zmieniono z %{old_value} na %{value}" filter: changeset: "Zestawy zmian" message: "Fora" @@ -3017,7 +3005,7 @@ pl: setting_date_format: "Data" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Język domyślny" setting_default_projects_modules: "Domyślnie włączone moduły dla nowych projektów" setting_default_projects_public: "Nowe projekty są publiczne (domyślnie)" diff --git a/config/locales/crowdin/pt-BR.yml b/config/locales/crowdin/pt-BR.yml index 95516d43593a..5711acec8f8b 100644 --- a/config/locales/crowdin/pt-BR.yml +++ b/config/locales/crowdin/pt-BR.yml @@ -1159,18 +1159,6 @@ pt-BR: other: "%{count} horas" updated: "alterado de %{old_value} para %{value}" logged_for: "Registrado por" - meeting_agenda_item: - duration: - added: "definido como %{value}" - added_html: "definido como %{value}" - removed: "removido" - updated: "alterado de %{old_value} para %{value}" - updated_html: "alterado de %{old_value} para %{value}" - position: - updated: "reorganizado" - work_package: - updated: "alterado de %{old_value} para %{value}" - updated_html: "alterado de %{old_value} para %{value}" filter: changeset: "Cj de alterações" message: "Fóruns" @@ -2950,7 +2938,7 @@ pt-BR: setting_date_format: "Data" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Idioma padrão" setting_default_projects_modules: "Módulos habilitados por padrão para novos projetos" setting_default_projects_public: "Novos projetos são públicos por padrão" diff --git a/config/locales/crowdin/pt-PT.yml b/config/locales/crowdin/pt-PT.yml index 1ab02b56118e..d5e93a5d898c 100644 --- a/config/locales/crowdin/pt-PT.yml +++ b/config/locales/crowdin/pt-PT.yml @@ -1158,18 +1158,6 @@ pt-PT: other: "%{count} horas" updated: "alterado de %{old_value} para %{value}" logged_for: "Registado para" - meeting_agenda_item: - duration: - added: "definido como %{value}" - added_html: "definido como %{value}" - removed: "removido" - updated: "alterado de %{old_value} para %{value}" - updated_html: "alterado de %{old_value} para %{value}" - position: - updated: "reordenado" - work_package: - updated: "alterado de %{old_value} para %{value}" - updated_html: "alterado de %{old_value} para %{value}" filter: changeset: "Conjunto de alterações" message: "Fóruns" @@ -2948,7 +2936,7 @@ pt-PT: setting_date_format: "Data" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Idioma predefinido" setting_default_projects_modules: "Módulos ativos por predefinição para novos projetos" setting_default_projects_public: "Projetos novos são públicos por omissão" diff --git a/config/locales/crowdin/ro.yml b/config/locales/crowdin/ro.yml index e6e9635555d5..11a7bc6d561d 100644 --- a/config/locales/crowdin/ro.yml +++ b/config/locales/crowdin/ro.yml @@ -1175,18 +1175,6 @@ ro: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Seturi de modificări" message: "Forumuri" @@ -2987,7 +2975,7 @@ ro: setting_date_format: "Dată" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Limbă implicită" setting_default_projects_modules: "Module activate implicit la creare proiect" setting_default_projects_public: "Proiectele noi sunt implicit publice" diff --git a/config/locales/crowdin/ru.yml b/config/locales/crowdin/ru.yml index 462bf483e947..f7544cc11d87 100644 --- a/config/locales/crowdin/ru.yml +++ b/config/locales/crowdin/ru.yml @@ -460,8 +460,8 @@ ru:
    Примечание: Будут применены унаследованные значения (например, элементов предков или потомков). status_excluded_from_totals_text: |- - Check this option to exclude work packages with this status from totals of Work, - Remaining work, and % Complete in a hierarchy. + Отметьте эту опцию, чтобы исключить пакеты работ с этим статусом из итогов Работы, + Оставшейся работы и % Завершения в иерархии. status_color_text: | Щелкните, чтобы задать или изменить цвет этого статуса. Этот цвет отображается на кнопке статуса и может использоваться для выделения пакетов работ в таблице. @@ -469,10 +469,10 @@ ru: no_results_title_text: В данный момент статусы пакетов работ отсутствуют. no_results_content_text: Добавить новый статус headers: - is_default: "Default" - is_closed: "Closed" - is_readonly: "Read-only" - excluded_from_totals: "Excluded from totals" + is_default: "По умолчанию" + is_closed: "Закрыто" + is_readonly: "Только для чтения" + excluded_from_totals: "Исключено из итогов" themes: light: "Светлая" light_high_contrast: "Светлый высокий контраст" @@ -644,7 +644,7 @@ ru: status: is_closed: "Пакет работ закрыт" is_readonly: "Пакет работ только для просмотра" - excluded_from_totals: "Exclude from calculation of totals in hierarchy" + excluded_from_totals: "Исключить из расчета итогов в иерархии" journal: notes: "Примечания" member: @@ -981,14 +981,14 @@ ru: base: working_days_are_missing: "По крайней мере, один день недели должен быть определен как рабочий." previous_working_day_changes_unprocessed: "Предыдущие изменения конфигурации рабочих дней еще не были применены." - hours_per_day_are_missing: "The number of hours per day must be defined." - days_per_week_are_missing: "The number of days per week must be defined." - days_per_month_are_missing: "The number of days per month must be defined." - durations_are_not_positive_numbers: "The durations must be positive numbers." - hours_per_day_is_out_of_bounds: "Hours per day can't be more than 24" - days_per_week_is_out_of_bounds: "Days per week can't be more than 7" - days_per_month_is_out_of_bounds: "Days per month can't be more than 31" - days_per_week_and_days_per_month_are_inconsistent: "The number of days per week and the number of days per month must be consistent." + hours_per_day_are_missing: "Необходимо указать количество часов в день." + days_per_week_are_missing: "Необходимо указать количество дней в неделю." + days_per_month_are_missing: "Необходимо указать количество дней в месяце." + durations_are_not_positive_numbers: "Длительность должна быть положительным числом." + hours_per_day_is_out_of_bounds: "Количество часов в день не может быть больше 24" + days_per_week_is_out_of_bounds: "Количество дней в неделю не может быть больше 7" + days_per_month_is_out_of_bounds: "Количество дней в месяце не может быть больше 31" + days_per_week_and_days_per_month_are_inconsistent: "Количество дней в неделю и количество дней в месяц должны быть постоянными." time_entry: attributes: hours: @@ -1189,18 +1189,6 @@ ru: other: "%{count} часов" updated: "изменено с %{old_value} на %{value}" logged_for: "Зарегистрирован для" - meeting_agenda_item: - duration: - added: "установлено в %{value}" - added_html: "установлено в %{value}" - removed: "удалено" - updated: "изменено с %{old_value} на %{value}" - updated_html: "изменено с %{old_value} на %{value}" - position: - updated: "переупорядочено" - work_package: - updated: "изменено с %{old_value} на %{value}" - updated_html: "изменено с %{old_value} на %{value}" filter: changeset: "Наборы изменений" message: "Форумы" @@ -1254,7 +1242,7 @@ ru: password: "Пароль" priority: "Приоритет" project: "Проект" - responsible: "Подотчетный" + responsible: "Ответственный" role: "Роль" roles: "Роли" start_date: "Дата начала" @@ -1740,7 +1728,7 @@ ru: dates_changed: "Даты изменены" default_attribute_written: "Запись атрибутов со свойством \"только для чтения\"" progress_mode_changed_to_status_based: "Расчет прогресса обновлен" - status_changed: "Status '%{status_name}'" + status_changed: "Статус '%{status_name}'" system_update: "Обновление системы OpenProject:" cause_descriptions: work_package_predecessor_changed_times: внесением изменений в предшественника %{link} @@ -1757,9 +1745,9 @@ ru: working: "%{date} сейчас рабочий" non_working: "%{date} теперь нерабочий" progress_mode_changed_to_status_based: Расчет прогресса установлен в режим "На основе статуса" - status_excluded_from_totals_set_to_false_message: now included in hierarchy totals - status_excluded_from_totals_set_to_true_message: now excluded from hierarchy totals - status_percent_complete_changed: "% complete changed from %{old_value}% to %{new_value}%" + status_excluded_from_totals_set_to_false_message: теперь включено в иерархию итогов + status_excluded_from_totals_set_to_true_message: теперь исключено из иерархии итогов + status_percent_complete_changed: "% завершения изменен с %{old_value}% на %{new_value}%" system_update: file_links_journal: > Теперь на вкладке Активность появится активность, связанная со ссылками файлов (файлы, хранящиеся во внешних хранилищах). Ниже описывается деятельность по уже существующим ссылкам: @@ -2416,7 +2404,7 @@ ru: label_workflow: "Рабочий поток" label_workflow_plural: "Рабочие потоки" label_workflow_summary: "Сводка" - label_working_days_and_hours: "Working days and hours" + label_working_days_and_hours: "Рабочие дни и часы" label_x_closed_work_packages_abbr: one: "1 закрыто" other: "%{count} закрыто" @@ -2499,7 +2487,7 @@ ru: reason: watched: "Просмотрено" assigned: "Назначено" - responsible: "Подотчетный" + responsible: "Ответственный" mentioned: "Упомянутые" shared: "Общий доступ" subscribed: "все" @@ -3017,9 +3005,9 @@ ru: setting_cross_project_work_package_relations: "Разрешить перектестные связи пакетов работ проекта" setting_first_week_of_year: "Первая неделя в году содержит" setting_date_format: "Дата" - setting_days_per_month: "Days per month" + setting_days_per_month: "Количество дней в месяце" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Язык по умолчанию" setting_default_projects_modules: "По умолчанию доступные в новых проектах модули" setting_default_projects_public: "По умолчанию новые проекты видимы всем" @@ -3035,12 +3023,12 @@ ru: setting_feeds_limit: "Предел содержимого новостной ленты" setting_file_max_size_displayed: "Максимальная длина строки текстовых файлов" setting_host_name: "Имя компьютера в сети" - setting_hours_per_day: "Hours per day" + setting_hours_per_day: "Количество часов в день" setting_hours_per_day_explanation: >- - This will define what is considered a "day" when displaying duration in a more natural way (for example, if a day is 8 hours, 32 hours would be 4 days). - setting_days_per_week: "Days per week" + Это определяет, что считается «днем» при более естественном отображении продолжительности (например, если день 8 часов, то 32 часа будет 4 дня). + setting_days_per_week: "Количество дней в неделю" setting_days_per_week_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a week is 5 days, 15 days would be 3 weeks). + Это определяет, что считается "неделей" при более естественном отображении продолжительности (например, если в неделю 5 дней, то 15 дней будет 3 недели). setting_invitation_expiration_days: "Действие письма активации истекает после" setting_work_package_done_ratio: "Режим расчета прогресса" setting_work_package_done_ratio_field: "На основе трудозатрат" @@ -3483,12 +3471,12 @@ ru: additional_privileges_project_or_group: "Есть дополнительные привилегии (в качестве участника проекта или группы)" working_days: info: > - Days that are not selected are skipped when scheduling work packages (and not included in the day count). These can be overridden at a work-package level. + Невыбранные дни пропускаются при планировании пакетов работ (и не включаются в подсчет дней). Они могут быть переопределены на уровне пакетов работ. instance_wide_info: > Даты, добавленные в список ниже, считаются нерабочими и пропускаются при планировании пакетов работ. change_button: "Изменить рабочие дни" warning: > - Changing which days of the week are considered working days or non-working days can affect the start and finish days of all work packages in all projects in this instance. + Изменение дней недели, считающихся рабочими или нерабочими днями, может повлиять на начало и завершение всех пакетов работ во всех проектах. journal_note: changed: _**Рабочие дни** изменены (%{changes})._ days: diff --git a/config/locales/crowdin/rw.yml b/config/locales/crowdin/rw.yml index 6b95576ed2e0..7866289d0f30 100644 --- a/config/locales/crowdin/rw.yml +++ b/config/locales/crowdin/rw.yml @@ -1160,18 +1160,6 @@ rw: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Changesets" message: "Forums" @@ -2953,7 +2941,7 @@ rw: setting_date_format: "Date" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Default language" setting_default_projects_modules: "Default enabled modules for new projects" setting_default_projects_public: "New projects are public by default" diff --git a/config/locales/crowdin/si.yml b/config/locales/crowdin/si.yml index dfcafb38ebd0..272c8d93b0e8 100644 --- a/config/locales/crowdin/si.yml +++ b/config/locales/crowdin/si.yml @@ -1160,18 +1160,6 @@ si: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "වෙනස්කම්" message: "සංසද" @@ -2953,7 +2941,7 @@ si: setting_date_format: "දිනය" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "පෙරනිමි භාෂාව" setting_default_projects_modules: "නව ව්යාපෘති සඳහා පෙරනිමි සක්රීය මොඩියුල" setting_default_projects_public: "නව ව්යාපෘති පෙරනිමියෙන් පොදු වේ" diff --git a/config/locales/crowdin/sk.yml b/config/locales/crowdin/sk.yml index 6f62b9072027..818349ba0959 100644 --- a/config/locales/crowdin/sk.yml +++ b/config/locales/crowdin/sk.yml @@ -1190,18 +1190,6 @@ sk: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Sady zmien" message: "Diskusie" @@ -3022,7 +3010,7 @@ sk: setting_date_format: "Dátum" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Predvolený jazyk" setting_default_projects_modules: "Predvolené moduly novovytváraných projektov" setting_default_projects_public: "Nové projekty nastaviť ako verejné" diff --git a/config/locales/crowdin/sl.yml b/config/locales/crowdin/sl.yml index 0f7eea51c4a5..7cf6b7383d28 100644 --- a/config/locales/crowdin/sl.yml +++ b/config/locales/crowdin/sl.yml @@ -1187,18 +1187,6 @@ sl: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Zapisi sprememb" message: "Forumi" @@ -3019,7 +3007,7 @@ sl: setting_date_format: "Datum" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Privzeti jezik" setting_default_projects_modules: "Privzeti omogočeni moduli za nove projekte" setting_default_projects_public: "Novi projekti so privzeto javni" diff --git a/config/locales/crowdin/sr.yml b/config/locales/crowdin/sr.yml index 5a1d01426c3e..ae81c2b7a9b2 100644 --- a/config/locales/crowdin/sr.yml +++ b/config/locales/crowdin/sr.yml @@ -1175,18 +1175,6 @@ sr: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Changesets" message: "Forums" @@ -2988,7 +2976,7 @@ sr: setting_date_format: "Date" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Default language" setting_default_projects_modules: "Default enabled modules for new projects" setting_default_projects_public: "New projects are public by default" diff --git a/config/locales/crowdin/sv.yml b/config/locales/crowdin/sv.yml index 9a827f08fe9f..640df9856c36 100644 --- a/config/locales/crowdin/sv.yml +++ b/config/locales/crowdin/sv.yml @@ -1159,18 +1159,6 @@ sv: other: "%{count} timmar" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Uppdateringar" message: "Forum" @@ -2950,7 +2938,7 @@ sv: setting_date_format: "Datum" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Standardspråk" setting_default_projects_modules: "Standardmoduler för nya projekt" setting_default_projects_public: "Nya projekt är offentliga som standard" diff --git a/config/locales/crowdin/th.yml b/config/locales/crowdin/th.yml index c0611fd50ea8..6ce8bc99536f 100644 --- a/config/locales/crowdin/th.yml +++ b/config/locales/crowdin/th.yml @@ -1145,18 +1145,6 @@ th: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "ชุดการเปลี่ยนแปลง" message: "กระทู้" @@ -2918,7 +2906,7 @@ th: setting_date_format: "วันที่" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "ภาษาเริ่มต้น" setting_default_projects_modules: "ค่าเริ่มต้นของโมดูลที่เปิดใช้สำหรับโครงการใหม่" setting_default_projects_public: "โดยเริ่มแรก โครงการใหม่จะเป็นสาธารณะ" diff --git a/config/locales/crowdin/tr.yml b/config/locales/crowdin/tr.yml index e6f207193f39..796c03fe7fb8 100644 --- a/config/locales/crowdin/tr.yml +++ b/config/locales/crowdin/tr.yml @@ -1159,18 +1159,6 @@ tr: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Değişiklik Listeleri" message: "Forumlar" @@ -2949,7 +2937,7 @@ tr: setting_date_format: "Tarih" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Varsayılan dil" setting_default_projects_modules: "Yeni projeler için varsayılan etkin modüller" setting_default_projects_public: "Yeni projeler varsayılan olarak herkese açık" diff --git a/config/locales/crowdin/uk.yml b/config/locales/crowdin/uk.yml index 240139e977f1..a2b6f250b8d8 100644 --- a/config/locales/crowdin/uk.yml +++ b/config/locales/crowdin/uk.yml @@ -1185,18 +1185,6 @@ uk: other: "%{count} год" updated: "змінено з %{old_value} на %{value}" logged_for: "Зареєстровано для" - meeting_agenda_item: - duration: - added: "встановлено значення %{value}" - added_html: "встановлено значення %{value}" - removed: "вилучено" - updated: "змінено %{old_value} на %{value}" - updated_html: "змінено з %{old_value} на %{value}" - position: - updated: "перевпорядковано" - work_package: - updated: "змінено з %{old_value} на %{value}" - updated_html: "змінено з %{old_value} на %{value}" filter: changeset: "Набори змін" message: "Форуми" @@ -3015,7 +3003,7 @@ uk: setting_date_format: "Дата" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Мова за замовчуванням" setting_default_projects_modules: "Включені по замовчуванню модулі для нових проектів" setting_default_projects_public: "Нові проекти є загальнодоступними" diff --git a/config/locales/crowdin/uz.yml b/config/locales/crowdin/uz.yml index b6db08afd9d0..34818eeee254 100644 --- a/config/locales/crowdin/uz.yml +++ b/config/locales/crowdin/uz.yml @@ -1160,18 +1160,6 @@ uz: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Changesets" message: "Forums" @@ -2953,7 +2941,7 @@ uz: setting_date_format: "Date" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Default language" setting_default_projects_modules: "Default enabled modules for new projects" setting_default_projects_public: "New projects are public by default" diff --git a/config/locales/crowdin/vi.yml b/config/locales/crowdin/vi.yml index 80ca2faee368..64c3f56e1352 100644 --- a/config/locales/crowdin/vi.yml +++ b/config/locales/crowdin/vi.yml @@ -1147,18 +1147,6 @@ vi: other: "%{count} hours" updated: "changed from %{old_value} to %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" - position: - updated: "reordered" - work_package: - updated: "changed from %{old_value} to %{value}" - updated_html: "changed from %{old_value} to %{value}" filter: changeset: "Nhóm thay đổi" message: "Diễn đàn" @@ -2920,7 +2908,7 @@ vi: setting_date_format: "Ngày" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "Default language" setting_default_projects_modules: "Default enabled modules for new projects" setting_default_projects_public: "New projects are public by default" diff --git a/config/locales/crowdin/zh-CN.yml b/config/locales/crowdin/zh-CN.yml index 9c9824c3c1a3..1a722a4df817 100644 --- a/config/locales/crowdin/zh-CN.yml +++ b/config/locales/crowdin/zh-CN.yml @@ -263,7 +263,7 @@ zh-CN: my: "我的项目" favored: "收藏的项目" archived: "归档项目" - public: "Public project lists" + public: "公开项目列表" my_private: "我的私有项目列表" new: placeholder: "新项目列表" @@ -291,12 +291,12 @@ zh-CN: actions: label_enable_single: "在此项目中处于活动状态,点击禁用" label_disable_single: "在此项目中未启用,点击启用" - deactivate_for_project: "Deactivate for this project" + deactivate_for_project: "停用此项目" label_enable_all: "全部启用" label_disable_all: "全部禁用" is_required_blank_slate: - heading: Required in all projects - description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + heading: 所有项目中需要 + description: 此项目属性已在所有项目中激活,因为选中了“所有项目中需要”的选项。它在单个项目中不能被停用。 types: no_results_title_text: 目前有可用的类型。 form: @@ -314,11 +314,11 @@ zh-CN: success: "已保存修改后的列表" failure: "无法保存修改后的列表: %{errors}" publish: - success: "The list has been made public" - failure: "The list cannot be made public: %{errors}" + success: "此列表已设为公开" + failure: "此列表不能设为公开:%{errors}" unpublish: - success: "The list has been made private" - failure: "The list cannot be made private: %{errors}" + success: "此列表已被设为私有" + failure: "此列表不能被设为私有:%{errors}" can_be_saved: "列表已修改:" can_be_saved_as: "修改内容只能保存在新列表中。" members: @@ -440,8 +440,7 @@ zh-CN:
    :继承值(例如,来自子级或关系的值)仍然适用。 status_excluded_from_totals_text: |- - Check this option to exclude work packages with this status from totals of Work, - Remaining work, and % Complete in a hierarchy. + 选中此选项可将具有此状态的工作包在层级结构中从“总工时”,“剩余工作”,以及“完成百分比”中排除。 status_color_text: | 单击可以分配或更改此状态的颜色。 颜色显示在状态按钮中,可用于突出显示表中的工作包。 @@ -449,10 +448,10 @@ zh-CN: no_results_title_text: 目前没有工作包状态。 no_results_content_text: 添加新的状态 headers: - is_default: "Default" - is_closed: "Closed" - is_readonly: "Read-only" - excluded_from_totals: "Excluded from totals" + is_default: "默认" + is_closed: "已关闭" + is_readonly: "只读" + excluded_from_totals: "不包括在总计中" themes: light: "浅色" light_high_contrast: "浅色高对比度" @@ -620,7 +619,7 @@ zh-CN: status: is_closed: "工作包已关闭" is_readonly: "只读工作包" - excluded_from_totals: "Exclude from calculation of totals in hierarchy" + excluded_from_totals: "从层次结构的总计中排除" journal: notes: "备注" member: @@ -761,7 +760,7 @@ zh-CN: before_or_equal_to: "必须在早于或等于 %{date}" blank: "不能为空。" blank_nested: "需要设置属性“%{property}”。" - cannot_delete_mapping: "is required. Cannot be deleted." + cannot_delete_mapping: "必需项,不能删除" cant_link_a_work_package_with_a_descendant: "工作包无法链接到它的子任务之一。" circular_dependency: "这种关系将创建循环依赖项。" confirmation: "不匹配 %{attribute}。" @@ -922,8 +921,8 @@ zh-CN: nonexistent: "列“%{column}”不存在。" format: "%{message}" group_by_hierarchies_exclusive: "与按照“%{group_by}”分组的组互相排斥。您无法将它们都激活。" - can_only_be_modified_by_owner: "The query can only be modified by its owner." - need_permission_to_modify_public_query: "You cannot modify a public query." + can_only_be_modified_by_owner: "查询只能由其所有者修改" + need_permission_to_modify_public_query: "您不能修改公开查询" filters: custom_fields: inexistent: "过滤器没有自定义字段" @@ -957,14 +956,14 @@ zh-CN: base: working_days_are_missing: "每周必须至少有一天定义为工作日。" previous_working_day_changes_unprocessed: "先前对工作日配置的更改尚未应用。" - hours_per_day_are_missing: "The number of hours per day must be defined." - days_per_week_are_missing: "The number of days per week must be defined." - days_per_month_are_missing: "The number of days per month must be defined." - durations_are_not_positive_numbers: "The durations must be positive numbers." - hours_per_day_is_out_of_bounds: "Hours per day can't be more than 24" - days_per_week_is_out_of_bounds: "Days per week can't be more than 7" - days_per_month_is_out_of_bounds: "Days per month can't be more than 31" - days_per_week_and_days_per_month_are_inconsistent: "The number of days per week and the number of days per month must be consistent." + hours_per_day_are_missing: "必须定义每天的小时数" + days_per_week_are_missing: "必须定义每周的天数" + days_per_month_are_missing: "必须定义每月的天数" + durations_are_not_positive_numbers: "持续时间必须是正数" + hours_per_day_is_out_of_bounds: "每天小时数不能超过24" + days_per_week_is_out_of_bounds: "每周天数不能超过7" + days_per_month_is_out_of_bounds: "每月天数不能超过31" + days_per_week_and_days_per_month_are_inconsistent: "每周天数及每月天数必须保持一致" time_entry: attributes: hours: @@ -1141,18 +1140,6 @@ zh-CN: other: "%{count} 小时" updated: "从 %{old_value} 更改为 %{value}" logged_for: "已登录" - meeting_agenda_item: - duration: - added: "设为 %{value}" - added_html: "设为 %{value}" - removed: "已删除" - updated: "从 %{old_value} 更改为 %{value}" - updated_html: "从 %{old_value}改为 %{value}" - position: - updated: "重新排序" - work_package: - updated: "从 %{old_value} 更改为 %{value}" - updated_html: "从 %{old_value}改为 %{value}" filter: changeset: "更改集" message: "论坛" @@ -1331,8 +1318,8 @@ zh-CN: button_revoke_access: "撤消访问权限" button_revoke_all: "全部撤销" button_revoke_only: "仅撤销 %{shared_role_name}" - button_publish: "Make public" - button_unpublish: "Make private" + button_publish: "设为公开" + button_unpublish: "设为私有" consent: checkbox_label: 我已注意到并同意上述情况。 failure_message: 同意失败, 无法继续。 @@ -1638,7 +1625,7 @@ zh-CN: dates_changed: "日期已更改" default_attribute_written: "已写入只读属性" progress_mode_changed_to_status_based: "更新进度计算" - status_changed: "Status '%{status_name}'" + status_changed: "状态 '%{status_name}'" system_update: "OpenProject 系统更新:" cause_descriptions: work_package_predecessor_changed_times: 根据前置任务 %{link}的更改 @@ -1655,9 +1642,9 @@ zh-CN: working: "%{date}现在是工作日" non_working: "%{date}现在是非工作日" progress_mode_changed_to_status_based: 进度计算模式设置为基于状态 - status_excluded_from_totals_set_to_false_message: now included in hierarchy totals - status_excluded_from_totals_set_to_true_message: now excluded from hierarchy totals - status_percent_complete_changed: "% complete changed from %{old_value}% to %{new_value}%" + status_excluded_from_totals_set_to_false_message: 现在包含在层次结构总计中 + status_excluded_from_totals_set_to_true_message: 现在不包含在层次结构总计中 + status_percent_complete_changed: "完成百分比从 %{old_value}% 变为 %{new_value}%" system_update: file_links_journal: > 从现在开始,与文件链接(存储在外部存储器中的文件)相关的活动将出现在“活动”选项卡中。以下是与已经存在的链接相关的活动的表示: @@ -2314,7 +2301,7 @@ zh-CN: label_workflow: "工作流" label_workflow_plural: "工作流" label_workflow_summary: "摘要" - label_working_days_and_hours: "Working days and hours" + label_working_days_and_hours: "工作日和工作小时" label_x_closed_work_packages_abbr: one: "1 个已关闭" other: "%{count} 个已关闭" @@ -2692,7 +2679,7 @@ zh-CN: permission_save_bcf_queries: "保存 BCF 查询" permission_manage_public_bcf_queries: "管理公开的 BCF 查询" permission_edit_attribute_help_texts: "编辑属性帮助文本" - permission_manage_public_project_queries: "Manage public project lists" + permission_manage_public_project_queries: "管理公开项目列表" placeholders: default: "-" project: @@ -2906,9 +2893,9 @@ zh-CN: setting_cross_project_work_package_relations: "允许跨项目工作包关系" setting_first_week_of_year: "全年首周包含" setting_date_format: "日期" - setting_days_per_month: "Days per month" + setting_days_per_month: "每月天数" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "默认语言" setting_default_projects_modules: "新项目的默认启用模块" setting_default_projects_public: "新项目默认公开" @@ -2924,12 +2911,12 @@ zh-CN: setting_feeds_limit: "Feed 内容限制" setting_file_max_size_displayed: "内联显示的文本文件的最大大小" setting_host_name: "主机名" - setting_hours_per_day: "Hours per day" + setting_hours_per_day: "每日小时数" setting_hours_per_day_explanation: >- - This will define what is considered a "day" when displaying duration in a more natural way (for example, if a day is 8 hours, 32 hours would be 4 days). - setting_days_per_week: "Days per week" + 这将以更自然的方式在显示持续时间时定义什么是 "一天"(例如,如果一天是8小时,32小时就是4天)。 + setting_days_per_week: "每周天数" setting_days_per_week_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a week is 5 days, 15 days would be 3 weeks). + 这将以更自然的方式在显示持续时间时定义什么是 "一周"(例如,如果一周是5天,15天就是3周)。 setting_invitation_expiration_days: "激活电子邮件将在此时间后过期" setting_work_package_done_ratio: "进度计算" setting_work_package_done_ratio_field: "基于工时" @@ -3369,12 +3356,12 @@ zh-CN: additional_privileges_project_or_group: "可能有额外的权限(作为项目成员或组成员)" working_days: info: > - Days that are not selected are skipped when scheduling work packages (and not included in the day count). These can be overridden at a work-package level. + 在安排工作包时,未选择的日期将被跳过(且不计入天数)。可以在工作包级别覆盖这些选项。 instance_wide_info: > 添加到以下列表的日期被视为非工作日,在安排工作包时将被跳过。 change_button: "更改工作日" warning: > - Changing which days of the week are considered working days or non-working days can affect the start and finish days of all work packages in all projects in this instance. + 在这种情况下,更改一周中哪些天被视为工作日或非工作日,会影响所有项目中所有工作包的开始和结束日期。 journal_note: changed: _**工作日**已更改(%{changes})。_ days: diff --git a/config/locales/crowdin/zh-TW.yml b/config/locales/crowdin/zh-TW.yml index 8990383715f4..0735b7fac8ef 100644 --- a/config/locales/crowdin/zh-TW.yml +++ b/config/locales/crowdin/zh-TW.yml @@ -1144,18 +1144,6 @@ zh-TW: other: "%{count} hours" updated: "從 %{old_value} 更改至 %{value}" logged_for: "Logged for" - meeting_agenda_item: - duration: - added: "set to %{value}" - added_html: "set to %{value}" - removed: "removed" - updated: "從 %{old_value} 更改至 %{value}" - updated_html: "從 %{old_value} 更改至 %{value}" - position: - updated: "重新排列" - work_package: - updated: "從 %{old_value} 更改至 %{value}" - updated_html: "從 %{old_value} 更改至 %{value}" filter: changeset: "變更集" message: "討論區" @@ -2916,7 +2904,7 @@ zh-TW: setting_date_format: "日期" setting_days_per_month: "Days per month" setting_days_per_month_explanation: >- - This will define what is considered a "week" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. setting_default_language: "預設語言" setting_default_projects_modules: "新專案預設啟用的模組" setting_default_projects_public: "新專案預設為公開" diff --git a/modules/boards/config/locales/crowdin/no.yml b/modules/boards/config/locales/crowdin/no.yml index e233de4921c3..4910340d70cc 100644 --- a/modules/boards/config/locales/crowdin/no.yml +++ b/modules/boards/config/locales/crowdin/no.yml @@ -15,7 +15,7 @@ free: Enkel action: "Handlingstavle (%{attribute})" board_type_attributes: - assignee: Deltaker + assignee: Utførende status: Status version: Versjon subproject: Underprosjekt diff --git a/modules/ldap_groups/config/locales/crowdin/no.yml b/modules/ldap_groups/config/locales/crowdin/no.yml index 18e5f1dca1d9..41fbca9d63d9 100644 --- a/modules/ldap_groups/config/locales/crowdin/no.yml +++ b/modules/ldap_groups/config/locales/crowdin/no.yml @@ -66,7 +66,7 @@ form: auth_source_text: 'Velg hvilken LDAP-tilkobling som skal brukes.' sync_users_text: > - Hvis du aktiverer dette valget, vil funnede brukere automatisk bli opprettet i OpenProject. Uten dette vil bare eksisterende kontoer i OpenProject bli lagt til i grupper. + Hvis du aktiverer dette valget, vil relevante brukere automatisk bli opprettet i OpenProject. Uten dette vil bare eksisterende kontoer i OpenProject bli lagt til i grupper. dn_text: 'Skriv inn hele DN for gruppen i LDAP' group_text: 'Velg en eksisterende OpenProject gruppe som medlemmene i LDAP-gruppen skal synkroniseres med' upsale: diff --git a/modules/meeting/config/locales/crowdin/af.yml b/modules/meeting/config/locales/crowdin/af.yml index ffa8f6202ced..9185cff97822 100644 --- a/modules/meeting/config/locales/crowdin/af.yml +++ b/modules/meeting/config/locales/crowdin/af.yml @@ -58,9 +58,23 @@ af: meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Minutes" + meeting_section: "Section" activity: filter: meeting: "Meetings" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "attended" description_invite: "invited" events: diff --git a/modules/meeting/config/locales/crowdin/ar.yml b/modules/meeting/config/locales/crowdin/ar.yml index 74f72c1e6950..75f366088113 100644 --- a/modules/meeting/config/locales/crowdin/ar.yml +++ b/modules/meeting/config/locales/crowdin/ar.yml @@ -62,9 +62,23 @@ ar: meeting_agenda_item: "Agenda item" meeting_agenda: "جدول الأعمال" meeting_minutes: "محضر الجلسة" + meeting_section: "Section" activity: filter: meeting: "الاجتماعات" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "حَضَر" description_invite: "دعا" events: diff --git a/modules/meeting/config/locales/crowdin/az.yml b/modules/meeting/config/locales/crowdin/az.yml index 13e1e5d1f1d3..32564f39a60e 100644 --- a/modules/meeting/config/locales/crowdin/az.yml +++ b/modules/meeting/config/locales/crowdin/az.yml @@ -58,9 +58,23 @@ az: meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Minutes" + meeting_section: "Section" activity: filter: meeting: "Meetings" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "attended" description_invite: "invited" events: diff --git a/modules/meeting/config/locales/crowdin/be.yml b/modules/meeting/config/locales/crowdin/be.yml index daf6b5d2ccd6..a199dcd61cb7 100644 --- a/modules/meeting/config/locales/crowdin/be.yml +++ b/modules/meeting/config/locales/crowdin/be.yml @@ -60,9 +60,23 @@ be: meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Minutes" + meeting_section: "Section" activity: filter: meeting: "Meetings" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "attended" description_invite: "invited" events: diff --git a/modules/meeting/config/locales/crowdin/bg.yml b/modules/meeting/config/locales/crowdin/bg.yml index cd9bdd5cb7ee..710db69a4fa2 100644 --- a/modules/meeting/config/locales/crowdin/bg.yml +++ b/modules/meeting/config/locales/crowdin/bg.yml @@ -58,9 +58,23 @@ bg: meeting_agenda_item: "Agenda item" meeting_agenda: "Дневен ред" meeting_minutes: "Минути" + meeting_section: "Section" activity: filter: meeting: "Meetings" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "присъства" description_invite: "invited" events: diff --git a/modules/meeting/config/locales/crowdin/ca.yml b/modules/meeting/config/locales/crowdin/ca.yml index 6c9a0b22c442..7505ff74884a 100644 --- a/modules/meeting/config/locales/crowdin/ca.yml +++ b/modules/meeting/config/locales/crowdin/ca.yml @@ -58,9 +58,23 @@ ca: meeting_agenda_item: "Element d'agenda" meeting_agenda: "Agenda" meeting_minutes: "Acta" + meeting_section: "Section" activity: filter: meeting: "Reunions" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "eliminat" + updated: "canviat de %{old_value} a %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordenat" + work_package: + updated: "canviat de %{old_value} a %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "hi vaig assistir" description_invite: "convidat" events: diff --git a/modules/meeting/config/locales/crowdin/ckb-IR.yml b/modules/meeting/config/locales/crowdin/ckb-IR.yml index 86a56ba4eba7..b5275043361e 100644 --- a/modules/meeting/config/locales/crowdin/ckb-IR.yml +++ b/modules/meeting/config/locales/crowdin/ckb-IR.yml @@ -58,9 +58,23 @@ ckb-IR: meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Minutes" + meeting_section: "Section" activity: filter: meeting: "Meetings" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "attended" description_invite: "invited" events: diff --git a/modules/meeting/config/locales/crowdin/cs.yml b/modules/meeting/config/locales/crowdin/cs.yml index 5c7adda9a778..c585e54808cd 100644 --- a/modules/meeting/config/locales/crowdin/cs.yml +++ b/modules/meeting/config/locales/crowdin/cs.yml @@ -60,9 +60,23 @@ cs: meeting_agenda_item: "Pořad jednání" meeting_agenda: "Agenda" meeting_minutes: "Zápis" + meeting_section: "Section" activity: filter: meeting: "Schůzky" + item: + meeting_agenda_item: + duration: + added: "nastavit na %{value}" + added_html: "nastavit na %{value}" + removed: "odstraněno" + updated: "změněno z %{old_value} na %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "změněno z %{old_value} na %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "zúčastněn" description_invite: "pozván" events: diff --git a/modules/meeting/config/locales/crowdin/da.yml b/modules/meeting/config/locales/crowdin/da.yml index e18d4d779e1f..9233250249bb 100644 --- a/modules/meeting/config/locales/crowdin/da.yml +++ b/modules/meeting/config/locales/crowdin/da.yml @@ -58,9 +58,23 @@ da: meeting_agenda_item: "Agenda item" meeting_agenda: "Dagsorden" meeting_minutes: "Referat" + meeting_section: "Section" activity: filter: meeting: "Møder" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "tilsluttede" description_invite: "inviteret" events: diff --git a/modules/meeting/config/locales/crowdin/de.yml b/modules/meeting/config/locales/crowdin/de.yml index 00db26ef47d3..672ce0be8056 100644 --- a/modules/meeting/config/locales/crowdin/de.yml +++ b/modules/meeting/config/locales/crowdin/de.yml @@ -58,9 +58,23 @@ de: meeting_agenda_item: "Tagesordnungspunkt" meeting_agenda: "Agenda" meeting_minutes: "Protokoll" + meeting_section: "Section" activity: filter: meeting: "Besprechungen" + item: + meeting_agenda_item: + duration: + added: "auf %{value} eingestellt" + added_html: "auf %{value} eingestellt" + removed: "entfernt" + updated: "von %{old_value} zu %{value} geändert" + updated_html: "von %{old_value} zu %{value} geändert" + position: + updated: "neu geordnet" + work_package: + updated: "von %{old_value} zu %{value} geändert" + updated_html: "von %{old_value} zu %{value} geändert" description_attended: "teilgenommen" description_invite: "eingeladen" events: diff --git a/modules/meeting/config/locales/crowdin/el.yml b/modules/meeting/config/locales/crowdin/el.yml index b0fcf9dc47a6..2fe2e0058a7f 100644 --- a/modules/meeting/config/locales/crowdin/el.yml +++ b/modules/meeting/config/locales/crowdin/el.yml @@ -58,9 +58,23 @@ el: meeting_agenda_item: "Agenda item" meeting_agenda: "Ατζέντα" meeting_minutes: "Πρακτικά" + meeting_section: "Section" activity: filter: meeting: "Συναντήσεις" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "παρευρέθηκε" description_invite: "προσκεκλημένος" events: diff --git a/modules/meeting/config/locales/crowdin/eo.yml b/modules/meeting/config/locales/crowdin/eo.yml index 47a5374cba34..638355c6aa09 100644 --- a/modules/meeting/config/locales/crowdin/eo.yml +++ b/modules/meeting/config/locales/crowdin/eo.yml @@ -58,9 +58,23 @@ eo: meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Minutes" + meeting_section: "Section" activity: filter: meeting: "Meetings" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "attended" description_invite: "invited" events: diff --git a/modules/meeting/config/locales/crowdin/es.yml b/modules/meeting/config/locales/crowdin/es.yml index 58bc32b3ba2b..0534701eb97c 100644 --- a/modules/meeting/config/locales/crowdin/es.yml +++ b/modules/meeting/config/locales/crowdin/es.yml @@ -58,9 +58,23 @@ es: meeting_agenda_item: "Puntos de Agenda" meeting_agenda: "Agenda" meeting_minutes: "Minutas" + meeting_section: "Section" activity: filter: meeting: "Reuniones" + item: + meeting_agenda_item: + duration: + added: "fijado en %{value}" + added_html: "fijado en %{value}" + removed: "eliminado" + updated: "cambiado de %{old_value} a %{value}" + updated_html: "cambiado de %{old_value} a %{value}" + position: + updated: "reordenado" + work_package: + updated: "cambiado de %{old_value} a %{value}" + updated_html: "cambiado de %{old_value} a %{value}" description_attended: "ha asistido" description_invite: "invitado" events: diff --git a/modules/meeting/config/locales/crowdin/et.yml b/modules/meeting/config/locales/crowdin/et.yml index 2bcec63a168b..a38c1e645212 100644 --- a/modules/meeting/config/locales/crowdin/et.yml +++ b/modules/meeting/config/locales/crowdin/et.yml @@ -58,9 +58,23 @@ et: meeting_agenda_item: "Agenda item" meeting_agenda: "Päevakava" meeting_minutes: "Minutit" + meeting_section: "Section" activity: filter: meeting: "Koosolekud" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "osales" description_invite: "ktsutud" events: diff --git a/modules/meeting/config/locales/crowdin/eu.yml b/modules/meeting/config/locales/crowdin/eu.yml index da0859fdd9e1..2af65e54def8 100644 --- a/modules/meeting/config/locales/crowdin/eu.yml +++ b/modules/meeting/config/locales/crowdin/eu.yml @@ -58,9 +58,23 @@ eu: meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Aktak" + meeting_section: "Section" activity: filter: meeting: "Hitzorduak" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "Egon da" description_invite: "Gonbidatua izan da" events: diff --git a/modules/meeting/config/locales/crowdin/fa.yml b/modules/meeting/config/locales/crowdin/fa.yml index 356dc4f999f7..9f2173818213 100644 --- a/modules/meeting/config/locales/crowdin/fa.yml +++ b/modules/meeting/config/locales/crowdin/fa.yml @@ -58,9 +58,23 @@ fa: meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "دقیقه ها" + meeting_section: "Section" activity: filter: meeting: "جلسات" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "attended" description_invite: "invited" events: diff --git a/modules/meeting/config/locales/crowdin/fi.yml b/modules/meeting/config/locales/crowdin/fi.yml index 9472447d4ffa..91bcdf289f5c 100644 --- a/modules/meeting/config/locales/crowdin/fi.yml +++ b/modules/meeting/config/locales/crowdin/fi.yml @@ -58,9 +58,23 @@ fi: meeting_agenda_item: "Agenda item" meeting_agenda: "Esityslista" meeting_minutes: "Pöytäkirja" + meeting_section: "Section" activity: filter: meeting: "Kokoukset" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "osallistunut" description_invite: "kutsuttu" events: diff --git a/modules/meeting/config/locales/crowdin/fil.yml b/modules/meeting/config/locales/crowdin/fil.yml index 141931601ee3..a7db74607ffc 100644 --- a/modules/meeting/config/locales/crowdin/fil.yml +++ b/modules/meeting/config/locales/crowdin/fil.yml @@ -58,9 +58,23 @@ fil: meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Minutes" + meeting_section: "Section" activity: filter: meeting: "Mga Pagpupulong" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "dumalo" description_invite: "maimbitahan" events: diff --git a/modules/meeting/config/locales/crowdin/fr.yml b/modules/meeting/config/locales/crowdin/fr.yml index 6acf46548fa4..ae5e5ef72891 100644 --- a/modules/meeting/config/locales/crowdin/fr.yml +++ b/modules/meeting/config/locales/crowdin/fr.yml @@ -58,9 +58,23 @@ fr: meeting_agenda_item: "" meeting_agenda: "Ordre du jour" meeting_minutes: "Compte-rendu" + meeting_section: "Section" activity: filter: meeting: "Réunions" + item: + meeting_agenda_item: + duration: + added: "défini sur %{value}" + added_html: "défini sur %{value}" + removed: "supprimé" + updated: "modifié de %{old_value} à %{value}" + updated_html: "modifié de %{old_value} à %{value}" + position: + updated: "réorganisé" + work_package: + updated: "modifié de %{old_value} à %{value}" + updated_html: "modifié de %{old_value} à %{value}" description_attended: "ont participé" description_invite: "invité" events: diff --git a/modules/meeting/config/locales/crowdin/he.yml b/modules/meeting/config/locales/crowdin/he.yml index a6975c1e4a4a..8fec1974c3aa 100644 --- a/modules/meeting/config/locales/crowdin/he.yml +++ b/modules/meeting/config/locales/crowdin/he.yml @@ -60,9 +60,23 @@ he: meeting_agenda_item: "Agenda item" meeting_agenda: "סדר היום" meeting_minutes: "דקות" + meeting_section: "Section" activity: filter: meeting: "פגישות" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "נכחו" description_invite: "הוזמנו" events: diff --git a/modules/meeting/config/locales/crowdin/hi.yml b/modules/meeting/config/locales/crowdin/hi.yml index 0bb23b1a2c1b..3a4239a5ab3a 100644 --- a/modules/meeting/config/locales/crowdin/hi.yml +++ b/modules/meeting/config/locales/crowdin/hi.yml @@ -58,9 +58,23 @@ hi: meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Minutes" + meeting_section: "Section" activity: filter: meeting: "Meetings" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "attended" description_invite: "invited" events: diff --git a/modules/meeting/config/locales/crowdin/hr.yml b/modules/meeting/config/locales/crowdin/hr.yml index ca98b0420163..4d12a58be53e 100644 --- a/modules/meeting/config/locales/crowdin/hr.yml +++ b/modules/meeting/config/locales/crowdin/hr.yml @@ -59,9 +59,23 @@ hr: meeting_agenda_item: "Agenda item" meeting_agenda: "Dnevni red" meeting_minutes: "Minute" + meeting_section: "Section" activity: filter: meeting: "Sastanci" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "prisustvovali su" description_invite: "pozvani" events: diff --git a/modules/meeting/config/locales/crowdin/hu.yml b/modules/meeting/config/locales/crowdin/hu.yml index 4f497df998d8..79445029b3e2 100644 --- a/modules/meeting/config/locales/crowdin/hu.yml +++ b/modules/meeting/config/locales/crowdin/hu.yml @@ -58,9 +58,23 @@ hu: meeting_agenda_item: "Napirendi pont" meeting_agenda: "Napirend" meeting_minutes: "Jegyzőkönyv" + meeting_section: "Section" activity: filter: meeting: "Megbeszélések" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "részt vett" description_invite: "meghívott" events: diff --git a/modules/meeting/config/locales/crowdin/id.yml b/modules/meeting/config/locales/crowdin/id.yml index ec6afd53f76d..a798145696b1 100644 --- a/modules/meeting/config/locales/crowdin/id.yml +++ b/modules/meeting/config/locales/crowdin/id.yml @@ -57,9 +57,23 @@ id: meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Laporan" + meeting_section: "Section" activity: filter: meeting: "Rapat" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "diubah dari %{old_value} menjadi %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "diubah dari %{old_value} menjadi %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "hadir" description_invite: "diundang" events: diff --git a/modules/meeting/config/locales/crowdin/it.yml b/modules/meeting/config/locales/crowdin/it.yml index 97b03c3d7d46..0f65741c2f62 100644 --- a/modules/meeting/config/locales/crowdin/it.yml +++ b/modules/meeting/config/locales/crowdin/it.yml @@ -58,9 +58,23 @@ it: meeting_agenda_item: "Attività" meeting_agenda: "Ordine del giorno" meeting_minutes: "Verbali" + meeting_section: "Section" activity: filter: meeting: "Riunioni" + item: + meeting_agenda_item: + duration: + added: "impostato a %{value}" + added_html: "impostato a %{value}" + removed: "rimosso" + updated: "modificato da %{old_value} a %{value}" + updated_html: "modificato da %{old_value} a %{value}" + position: + updated: "riordinato" + work_package: + updated: "modificato da %{old_value} a %{value}" + updated_html: "modificato da %{old_value} a %{value}" description_attended: "ha partecipato" description_invite: "invitato" events: diff --git a/modules/meeting/config/locales/crowdin/ja.yml b/modules/meeting/config/locales/crowdin/ja.yml index 13387f19f16c..c92a632d1192 100644 --- a/modules/meeting/config/locales/crowdin/ja.yml +++ b/modules/meeting/config/locales/crowdin/ja.yml @@ -57,9 +57,23 @@ ja: meeting_agenda_item: "Agenda item" meeting_agenda: "アジェンダ" meeting_minutes: "議事録" + meeting_section: "Section" activity: filter: meeting: "会議" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "出席した" description_invite: "招待済み" events: diff --git a/modules/meeting/config/locales/crowdin/ka.yml b/modules/meeting/config/locales/crowdin/ka.yml index ee3c5a643fc4..2361f0940c55 100644 --- a/modules/meeting/config/locales/crowdin/ka.yml +++ b/modules/meeting/config/locales/crowdin/ka.yml @@ -58,9 +58,23 @@ ka: meeting_agenda_item: "განრიგის პუნქტი" meeting_agenda: "დღის განრიგი" meeting_minutes: "წუთი" + meeting_section: "Section" activity: filter: meeting: "შეხვედრები" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "დაესწრო" description_invite: "მოწვეულია" events: diff --git a/modules/meeting/config/locales/crowdin/kk.yml b/modules/meeting/config/locales/crowdin/kk.yml index 24b815bb33f2..c1312f0bacbf 100644 --- a/modules/meeting/config/locales/crowdin/kk.yml +++ b/modules/meeting/config/locales/crowdin/kk.yml @@ -58,9 +58,23 @@ kk: meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Minutes" + meeting_section: "Section" activity: filter: meeting: "Meetings" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "attended" description_invite: "invited" events: diff --git a/modules/meeting/config/locales/crowdin/ko.yml b/modules/meeting/config/locales/crowdin/ko.yml index c03f9ae280e4..3ead8c74fde5 100644 --- a/modules/meeting/config/locales/crowdin/ko.yml +++ b/modules/meeting/config/locales/crowdin/ko.yml @@ -57,9 +57,23 @@ ko: meeting_agenda_item: "의제 항목" meeting_agenda: "의제" meeting_minutes: "의사록" + meeting_section: "Section" activity: filter: meeting: "미팅" + item: + meeting_agenda_item: + duration: + added: "%{value}(으)로 설정됨" + added_html: "%{value}(으)로 설정됨" + removed: "제거됨" + updated: "%{old_value}에서 %{value}(으)로 변경됨" + updated_html: "%{old_value}에서 %{value}(으)로 변경됨" + position: + updated: "재정렬됨" + work_package: + updated: "%{old_value}에서 %{value}(으)로 변경됨" + updated_html: "%{old_value}에서 %{value}(으)로 변경됨" description_attended: "참석함" description_invite: "초대됨" events: diff --git a/modules/meeting/config/locales/crowdin/lt.yml b/modules/meeting/config/locales/crowdin/lt.yml index 035789fb594f..a5b28bf32b5e 100644 --- a/modules/meeting/config/locales/crowdin/lt.yml +++ b/modules/meeting/config/locales/crowdin/lt.yml @@ -60,9 +60,23 @@ lt: meeting_agenda_item: "Darbotvarkės punktas" meeting_agenda: "Dienotvarkė" meeting_minutes: "Minutės" + meeting_section: "Section" activity: filter: meeting: "Susitikimai" + item: + meeting_agenda_item: + duration: + added: "nustatyti %{value}" + added_html: "nustatyti %{value}" + removed: "išimta" + updated: "pakeitė iš %{old_value} į %{value}" + updated_html: "pakeista iš %{old_value} į %{value}" + position: + updated: "perrikiuota" + work_package: + updated: "pakeista iš %{old_value} į %{value}" + updated_html: "pakeista iš %{old_value} į %{value}" description_attended: "būtinai dalyvavo" description_invite: "pakviesta" events: diff --git a/modules/meeting/config/locales/crowdin/lv.yml b/modules/meeting/config/locales/crowdin/lv.yml index 3e7c01f486e9..e4038e4ea1c6 100644 --- a/modules/meeting/config/locales/crowdin/lv.yml +++ b/modules/meeting/config/locales/crowdin/lv.yml @@ -59,9 +59,23 @@ lv: meeting_agenda_item: "Darba kārtības punkts" meeting_agenda: "Darba kārtība" meeting_minutes: "Protokols" + meeting_section: "Section" activity: filter: meeting: "Sanāksmes" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "apmeklēja" description_invite: "uzaicināts" events: diff --git a/modules/meeting/config/locales/crowdin/mn.yml b/modules/meeting/config/locales/crowdin/mn.yml index 5ecd378b9ba4..f58454cacdd7 100644 --- a/modules/meeting/config/locales/crowdin/mn.yml +++ b/modules/meeting/config/locales/crowdin/mn.yml @@ -58,9 +58,23 @@ mn: meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Minutes" + meeting_section: "Section" activity: filter: meeting: "Meetings" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "attended" description_invite: "invited" events: diff --git a/modules/meeting/config/locales/crowdin/ms.yml b/modules/meeting/config/locales/crowdin/ms.yml index d7917b6f4d30..cd3f4b60a5d4 100644 --- a/modules/meeting/config/locales/crowdin/ms.yml +++ b/modules/meeting/config/locales/crowdin/ms.yml @@ -57,9 +57,23 @@ ms: meeting_agenda_item: "Item agenda" meeting_agenda: "Agenda" meeting_minutes: "Minit mesyuarat" + meeting_section: "Section" activity: filter: meeting: "Mesyuarat" + item: + meeting_agenda_item: + duration: + added: "ditetapkan kepada %{value}" + added_html: "ditetapkan kepada %{value}" + removed: "dikeluarkan" + updated: "ditukar dari %{old_value} kepada %{value}" + updated_html: "ditukar dari %{old_value} kepada %{value}" + position: + updated: "disusun semula" + work_package: + updated: "ditukar dari %{old_value} kepada %{value}" + updated_html: "ditukar dari %{old_value} kepada %{value}" description_attended: "dihadiri" description_invite: "dijemput" events: diff --git a/modules/meeting/config/locales/crowdin/ne.yml b/modules/meeting/config/locales/crowdin/ne.yml index af194d691aa6..e0517d4e1c60 100644 --- a/modules/meeting/config/locales/crowdin/ne.yml +++ b/modules/meeting/config/locales/crowdin/ne.yml @@ -58,9 +58,23 @@ ne: meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Minutes" + meeting_section: "Section" activity: filter: meeting: "Meetings" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "attended" description_invite: "invited" events: diff --git a/modules/meeting/config/locales/crowdin/nl.yml b/modules/meeting/config/locales/crowdin/nl.yml index f0abbb1bb3f3..166c861c534e 100644 --- a/modules/meeting/config/locales/crowdin/nl.yml +++ b/modules/meeting/config/locales/crowdin/nl.yml @@ -58,9 +58,23 @@ nl: meeting_agenda_item: "Agendapunt" meeting_agenda: "Agenda" meeting_minutes: "Minuten" + meeting_section: "Section" activity: filter: meeting: "Vergaderingen" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "veranderd van %{old_value} naar %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "veranderd van %{old_value} naar %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "bijgewoond" description_invite: "uitgenodigd" events: diff --git a/modules/meeting/config/locales/crowdin/no.yml b/modules/meeting/config/locales/crowdin/no.yml index cac6c4f429d8..2710e1d82c8c 100644 --- a/modules/meeting/config/locales/crowdin/no.yml +++ b/modules/meeting/config/locales/crowdin/no.yml @@ -58,9 +58,23 @@ meeting_agenda_item: "Dagsorden element" meeting_agenda: "Saksliste" meeting_minutes: "Referat" + meeting_section: "Section" activity: filter: meeting: "Møter" + item: + meeting_agenda_item: + duration: + added: "satt til %{value}" + added_html: "satt til %{value}" + removed: "fjernet" + updated: "endret fra %{old_value} til %{value}" + updated_html: "endret fra %{old_value} til %{value}" + position: + updated: "omsortert" + work_package: + updated: "endret fra %{old_value} til %{value}" + updated_html: "endret fra %{old_value} til %{value}" description_attended: "deltok" description_invite: "invitert" events: diff --git a/modules/meeting/config/locales/crowdin/pl.yml b/modules/meeting/config/locales/crowdin/pl.yml index 3ddf8efaa7ed..1bc94b95ace0 100644 --- a/modules/meeting/config/locales/crowdin/pl.yml +++ b/modules/meeting/config/locales/crowdin/pl.yml @@ -60,9 +60,23 @@ pl: meeting_agenda_item: "Punkt programu" meeting_agenda: "Plan spotkania" meeting_minutes: "Protokół ze spotkania" + meeting_section: "Section" activity: filter: meeting: "Spotkania" + item: + meeting_agenda_item: + duration: + added: "ustawiono na %{value}" + added_html: "ustawiono na %{value}" + removed: "usunięto" + updated: "zmieniono z %{old_value} na %{value}" + updated_html: "zmieniono z %{old_value} na %{value}" + position: + updated: "zmieniono kolejność" + work_package: + updated: "zmieniono z %{old_value} na %{value}" + updated_html: "zmieniono z %{old_value} na %{value}" description_attended: "Obecny" description_invite: "Zaproszony" events: diff --git a/modules/meeting/config/locales/crowdin/pt-BR.yml b/modules/meeting/config/locales/crowdin/pt-BR.yml index c54203ff864c..4ee36b373c64 100644 --- a/modules/meeting/config/locales/crowdin/pt-BR.yml +++ b/modules/meeting/config/locales/crowdin/pt-BR.yml @@ -58,9 +58,23 @@ pt-BR: meeting_agenda_item: "Item da agenda" meeting_agenda: "Agenda" meeting_minutes: "Atas" + meeting_section: "Section" activity: filter: meeting: "Reuniões" + item: + meeting_agenda_item: + duration: + added: "definido como %{value}" + added_html: "definido como %{value}" + removed: "removido" + updated: "alterado de %{old_value} para %{value}" + updated_html: "alterado de %{old_value} para %{value}" + position: + updated: "reorganizado" + work_package: + updated: "alterado de %{old_value} para %{value}" + updated_html: "alterado de %{old_value} para %{value}" description_attended: "compareceu" description_invite: "convidado" events: diff --git a/modules/meeting/config/locales/crowdin/pt-PT.yml b/modules/meeting/config/locales/crowdin/pt-PT.yml index ee16f445e43a..c1359db8c076 100644 --- a/modules/meeting/config/locales/crowdin/pt-PT.yml +++ b/modules/meeting/config/locales/crowdin/pt-PT.yml @@ -58,9 +58,23 @@ pt-PT: meeting_agenda_item: "Pontos da ordem de trabalhos" meeting_agenda: "Agenda" meeting_minutes: "Minutos" + meeting_section: "Section" activity: filter: meeting: "Reuniões" + item: + meeting_agenda_item: + duration: + added: "definido como %{value}" + added_html: "definido como %{value}" + removed: "removido" + updated: "alterado de %{old_value} para %{value}" + updated_html: "alterado de %{old_value} para %{value}" + position: + updated: "reordenado" + work_package: + updated: "alterado de %{old_value} para %{value}" + updated_html: "alterado de %{old_value} para %{value}" description_attended: "participantes" description_invite: "convidados" events: diff --git a/modules/meeting/config/locales/crowdin/ro.yml b/modules/meeting/config/locales/crowdin/ro.yml index f28d9bf5b257..fe513c9db315 100644 --- a/modules/meeting/config/locales/crowdin/ro.yml +++ b/modules/meeting/config/locales/crowdin/ro.yml @@ -59,9 +59,23 @@ ro: meeting_agenda_item: "Agenda item" meeting_agenda: "Agendă" meeting_minutes: "Concluzii" + meeting_section: "Section" activity: filter: meeting: "Reuniuni" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "a participat" description_invite: "a fost invitat" events: diff --git a/modules/meeting/config/locales/crowdin/ru.yml b/modules/meeting/config/locales/crowdin/ru.yml index 25deae587d4f..7daf66122b3f 100644 --- a/modules/meeting/config/locales/crowdin/ru.yml +++ b/modules/meeting/config/locales/crowdin/ru.yml @@ -60,9 +60,23 @@ ru: meeting_agenda_item: "Пункт повестки" meeting_agenda: "Повестка дня" meeting_minutes: "Протокол(-ы)" + meeting_section: "Section" activity: filter: meeting: "Совещания" + item: + meeting_agenda_item: + duration: + added: "установлено в %{value}" + added_html: "установлено в %{value}" + removed: "удалено" + updated: "изменено с %{old_value} на %{value}" + updated_html: "изменено с %{old_value} на %{value}" + position: + updated: "переупорядочено" + work_package: + updated: "изменено с %{old_value} на %{value}" + updated_html: "изменено с %{old_value} на %{value}" description_attended: "участие" description_invite: "приглашено" events: diff --git a/modules/meeting/config/locales/crowdin/rw.yml b/modules/meeting/config/locales/crowdin/rw.yml index 8d5264a8fed9..c159f79e031d 100644 --- a/modules/meeting/config/locales/crowdin/rw.yml +++ b/modules/meeting/config/locales/crowdin/rw.yml @@ -58,9 +58,23 @@ rw: meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Minutes" + meeting_section: "Section" activity: filter: meeting: "Meetings" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "attended" description_invite: "invited" events: diff --git a/modules/meeting/config/locales/crowdin/si.yml b/modules/meeting/config/locales/crowdin/si.yml index 7431700c0458..7a0a5654b5f7 100644 --- a/modules/meeting/config/locales/crowdin/si.yml +++ b/modules/meeting/config/locales/crowdin/si.yml @@ -58,9 +58,23 @@ si: meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Minutes" + meeting_section: "Section" activity: filter: meeting: "Meetings" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "attended" description_invite: "ආරාධනා" events: diff --git a/modules/meeting/config/locales/crowdin/sk.yml b/modules/meeting/config/locales/crowdin/sk.yml index 37d36fb3d8de..baed2b580f72 100644 --- a/modules/meeting/config/locales/crowdin/sk.yml +++ b/modules/meeting/config/locales/crowdin/sk.yml @@ -60,9 +60,23 @@ sk: meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Zápisnica" + meeting_section: "Section" activity: filter: meeting: "Stretnutia" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "sa zúčastnil" description_invite: "pozvaní" events: diff --git a/modules/meeting/config/locales/crowdin/sl.yml b/modules/meeting/config/locales/crowdin/sl.yml index 241521cc2e97..8ecaf19a311c 100644 --- a/modules/meeting/config/locales/crowdin/sl.yml +++ b/modules/meeting/config/locales/crowdin/sl.yml @@ -60,9 +60,23 @@ sl: meeting_agenda_item: "Agenda item" meeting_agenda: "Dnevni red" meeting_minutes: "Zapisnik" + meeting_section: "Section" activity: filter: meeting: "Sestanki" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "se je udeležil/a" description_invite: "Povabljen" events: diff --git a/modules/meeting/config/locales/crowdin/sr.yml b/modules/meeting/config/locales/crowdin/sr.yml index c86b311833e1..b686dd309a1c 100644 --- a/modules/meeting/config/locales/crowdin/sr.yml +++ b/modules/meeting/config/locales/crowdin/sr.yml @@ -59,9 +59,23 @@ sr: meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Minutes" + meeting_section: "Section" activity: filter: meeting: "Meetings" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "attended" description_invite: "invited" events: diff --git a/modules/meeting/config/locales/crowdin/sv.yml b/modules/meeting/config/locales/crowdin/sv.yml index b7fdbfa4a8ea..45e376dc0c87 100644 --- a/modules/meeting/config/locales/crowdin/sv.yml +++ b/modules/meeting/config/locales/crowdin/sv.yml @@ -58,9 +58,23 @@ sv: meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Protokoll" + meeting_section: "Section" activity: filter: meeting: "Möten" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "deltog" description_invite: "inbjudna" events: diff --git a/modules/meeting/config/locales/crowdin/th.yml b/modules/meeting/config/locales/crowdin/th.yml index edaf097b87e7..2729b7aa0f27 100644 --- a/modules/meeting/config/locales/crowdin/th.yml +++ b/modules/meeting/config/locales/crowdin/th.yml @@ -57,9 +57,23 @@ th: meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Minutes" + meeting_section: "Section" activity: filter: meeting: "ประชุม" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "attended" description_invite: "invited" events: diff --git a/modules/meeting/config/locales/crowdin/tr.yml b/modules/meeting/config/locales/crowdin/tr.yml index 7889c4169090..8aa974ac5b9e 100644 --- a/modules/meeting/config/locales/crowdin/tr.yml +++ b/modules/meeting/config/locales/crowdin/tr.yml @@ -58,9 +58,23 @@ tr: meeting_agenda_item: "Ajanda öğesi" meeting_agenda: "Ajanda" meeting_minutes: "Dakika" + meeting_section: "Section" activity: filter: meeting: "Toplantılar" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "katıldı" description_invite: "davet et" events: diff --git a/modules/meeting/config/locales/crowdin/uk.yml b/modules/meeting/config/locales/crowdin/uk.yml index 661b8fd35e56..c39410201798 100644 --- a/modules/meeting/config/locales/crowdin/uk.yml +++ b/modules/meeting/config/locales/crowdin/uk.yml @@ -60,9 +60,23 @@ uk: meeting_agenda_item: "Порядок денний" meeting_agenda: "Порядок денний" meeting_minutes: "Хвилини" + meeting_section: "Section" activity: filter: meeting: "Наради" + item: + meeting_agenda_item: + duration: + added: "встановлено значення %{value}" + added_html: "встановлено значення %{value}" + removed: "вилучено" + updated: "змінено %{old_value} на %{value}" + updated_html: "змінено з %{old_value} на %{value}" + position: + updated: "перевпорядковано" + work_package: + updated: "змінено з %{old_value} на %{value}" + updated_html: "змінено з %{old_value} на %{value}" description_attended: "Участь" description_invite: "Запрошені" events: diff --git a/modules/meeting/config/locales/crowdin/uz.yml b/modules/meeting/config/locales/crowdin/uz.yml index 4c33c93d20cc..fc63d672201c 100644 --- a/modules/meeting/config/locales/crowdin/uz.yml +++ b/modules/meeting/config/locales/crowdin/uz.yml @@ -58,9 +58,23 @@ uz: meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Minutes" + meeting_section: "Section" activity: filter: meeting: "Meetings" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "attended" description_invite: "invited" events: diff --git a/modules/meeting/config/locales/crowdin/vi.yml b/modules/meeting/config/locales/crowdin/vi.yml index 01da88f967e0..f3e0ac9e1209 100644 --- a/modules/meeting/config/locales/crowdin/vi.yml +++ b/modules/meeting/config/locales/crowdin/vi.yml @@ -57,9 +57,23 @@ vi: meeting_agenda_item: "Agenda item" meeting_agenda: "Các ý chính" meeting_minutes: "Phút" + meeting_section: "Section" activity: filter: meeting: "Những cuộc họp" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" + position: + updated: "reordered" + work_package: + updated: "changed from %{old_value} to %{value}" + updated_html: "changed from %{old_value} to %{value}" description_attended: "Đã tham dự" description_invite: "invited" events: diff --git a/modules/meeting/config/locales/crowdin/zh-CN.yml b/modules/meeting/config/locales/crowdin/zh-CN.yml index fc0170413aba..358f5f80bffa 100644 --- a/modules/meeting/config/locales/crowdin/zh-CN.yml +++ b/modules/meeting/config/locales/crowdin/zh-CN.yml @@ -57,9 +57,23 @@ zh-CN: meeting_agenda_item: "议程项目" meeting_agenda: "议程" meeting_minutes: "会议记录" + meeting_section: "Section" activity: filter: meeting: "会议" + item: + meeting_agenda_item: + duration: + added: "设为 %{value}" + added_html: "设为 %{value}" + removed: "已删除" + updated: "从 %{old_value} 更改为 %{value}" + updated_html: "从 %{old_value}改为 %{value}" + position: + updated: "重新排序" + work_package: + updated: "从 %{old_value} 更改为 %{value}" + updated_html: "从 %{old_value}改为 %{value}" description_attended: "已出席" description_invite: "已邀请" events: diff --git a/modules/meeting/config/locales/crowdin/zh-TW.yml b/modules/meeting/config/locales/crowdin/zh-TW.yml index a8a6a344c74e..fa238a3ac855 100644 --- a/modules/meeting/config/locales/crowdin/zh-TW.yml +++ b/modules/meeting/config/locales/crowdin/zh-TW.yml @@ -57,9 +57,23 @@ zh-TW: meeting_agenda_item: "議程項目" meeting_agenda: "會議大綱" meeting_minutes: "會議記錄" + meeting_section: "Section" activity: filter: meeting: "會議" + item: + meeting_agenda_item: + duration: + added: "set to %{value}" + added_html: "set to %{value}" + removed: "removed" + updated: "從 %{old_value} 更改至 %{value}" + updated_html: "從 %{old_value} 更改至 %{value}" + position: + updated: "重新排列" + work_package: + updated: "從 %{old_value} 更改至 %{value}" + updated_html: "從 %{old_value} 更改至 %{value}" description_attended: "出席人員" description_invite: "已邀請" events: diff --git a/modules/openid_connect/config/locales/crowdin/no.yml b/modules/openid_connect/config/locales/crowdin/no.yml index a6aaeb100ef3..b019b1bda92b 100644 --- a/modules/openid_connect/config/locales/crowdin/no.yml +++ b/modules/openid_connect/config/locales/crowdin/no.yml @@ -1,7 +1,7 @@ "no": plugin_openproject_openid_connect: name: "OpenProject OpenID tilkobling" - description: "Legger til OmniAuth OpenID Connect strategileverandører til Openproject." + description: "Legger til strategileverandører for OmniAuth OpenID Connect til OpenProject." logout_warning: > Du har blitt logget ut. Innholdet kan gå tapt. Vennligst [logg in]. activemodel: @@ -10,23 +10,23 @@ name: Navn display_name: Visningsnavn identifier: Identifikator - secret: Hemmelig + secret: Hemmelig nøkkel scope: Omfang limit_self_registration: Begrens egenregistrering openid_connect: - menu_title: OpenID leverandører + menu_title: OpenID-leverandører providers: label_add_new: Legg til ny OpenID-leverandør label_edit: Rediger OpenID-leverandør %{name} no_results_table: Ingen leverandører har blitt definert ennå. - plural: OpenID leverandører + plural: OpenID-leverandører singular: OpenID-leverandør setting_instructions: azure_deprecation_warning: > - Den konfigurerte Asur-appen peker på et utdatert API fra Azure. Vennligst lag en ny Azure app for å sikre funksjonaliteten i fremtiden. + Den konfigurerte Azure-appen peker på et utdatert API fra Azure. Vennligst lag en ny Azure-app for å sikre funksjonaliteten i fremtiden. azure_graph_api: > Bruk «graph.microsoft.com»-brukerinfo til å be om brukerdata. Dette skal være standard med mindre du har en eldre Azure-applikasjon. azure_tenant_html: > - Sett leverandøren av ditt azure endepunkt. Dette vil kontrollere hvem som får tilgang til OpenProject instansen. For mer informasjon, se vår brukerveiledning på Azure OpenID tilkobling. + Sett leverandøren av ditt Azure-endepunkt. Dette vil kontrollere hvem som får tilgang til OpenProject-instansen. For mer informasjon, se vår brukerveiledning på Azure OpenID-tilkobling. limit_self_registration: > Hvis aktivert kan brukere bare registrere seg ved hjelp av denne leverandøren hvis selvregistreringsinnstillingen tillater det. diff --git a/modules/webhooks/config/locales/crowdin/no.yml b/modules/webhooks/config/locales/crowdin/no.yml index 796eb300644c..47bc3bb3c2fe 100644 --- a/modules/webhooks/config/locales/crowdin/no.yml +++ b/modules/webhooks/config/locales/crowdin/no.yml @@ -5,14 +5,14 @@ activerecord: attributes: webhooks/webhook: - url: 'Nyttelast URL' - secret: 'Hemmelig signatur' + url: 'Nyttelast-URL' + secret: 'Hemmelig signaturnøkkel' events: 'Hendelser' projects: 'Aktiverte prosjekter' webhooks/log: event_name: 'Navn på hendelse' - url: 'Nyttelast URL' - response_code: 'Svar kode' + url: 'Nyttelast-URL' + response_code: 'Svarkode' response_body: 'Svar' models: webhooks/outgoing_webhook: "Utgående webhook" @@ -21,26 +21,26 @@ plural: Webhooks resources: time_entry: - name: "Tid oppføring" + name: "Timeføring" outgoing: no_results_table: Ingen webhooks har blitt definert ennå. label_add_new: Legg til ny webhook label_edit: Rediger webhook - label_event_resources: Event ressurser + label_event_resources: Hendelsesressurser events: created: "Opprettet" updated: "Oppdatert" explanation: text: > - Ved forekomst av en hendelse som oppretting av en arbeidspakke eller en oppdatering fra et prosjekt, OpenProject vil sende en POST-forespørsel til de konfigurerte nettendepunktene. Ofte blir arrangementet sendt etter at %{link} er godkjent. + Ved forekomst av en hendelse som oppretting av en arbeidspakke eller en oppdatering fra et prosjekt, vil OpenProject sende en POST-forespørsel til de konfigurerte nettendepunktene. Ofte blir hendelsen sendt etter at %{link} er godkjent. link: konfigurert summeringsperiode status: - enabled: 'Webhooks aktivert' - disabled: 'Webhooks er deaktivert' - enabled_text: 'webhooken sender ut nyttelaster for de definerte hendelsene nedenfor.' + enabled: 'Webhook er aktivert' + disabled: 'Webhook er deaktivert' + enabled_text: 'Webhooken sender ut nyttelaster for de definerte hendelsene nedenfor.' disabled_text: 'Klikk på rediger-knappen for å aktivere webhook.' deliveries: - no_results_table: Ingen leveranser er gjennomført for dette webhooket de siste dagene. + no_results_table: Ingen leveranser er gjennomført for denne webhooken de siste dagene. title: 'Nylige leveranser' time: 'Tid for levering' form: @@ -51,7 +51,7 @@ placeholder: 'Valgfri beskrivelse for webhook.' enabled: description: > - Når merket av, vil webhook utløse på de valgte hendelsene. Fjern avmerkingen for å deaktivere webhook. + Når merket av, vil webhooken utløses for de valgte hendelsene. Fjern merkingen for å deaktivere webhooken. events: title: 'Aktiverte hendelser' project_ids: @@ -63,4 +63,4 @@ title: 'Valgte prosjekter' secret: description: > - Hvis angitt, brukes denne hemmelige verdien av OpenProject for å signere webhook nyttelasten. + Hvis angitt, brukes denne hemmelige verdien av OpenProject for å signere webhook-nyttelasten. From 2420e2308f67e0a3cf685977eda74b991dd2db36 Mon Sep 17 00:00:00 2001 From: OpenProject Actions CI Date: Wed, 5 Jun 2024 03:14:23 +0000 Subject: [PATCH 145/176] update locales from crowdin [ci skip] --- config/locales/crowdin/js-ru.yml | 8 +++--- config/locales/crowdin/js-zh-CN.yml | 4 +-- config/locales/crowdin/ms.yml | 20 +++++++------- config/locales/crowdin/ru.yml | 4 +-- modules/boards/config/locales/crowdin/no.yml | 2 +- .../ldap_groups/config/locales/crowdin/no.yml | 2 +- .../config/locales/crowdin/no.yml | 12 ++++----- .../webhooks/config/locales/crowdin/no.yml | 26 +++++++++---------- 8 files changed, 39 insertions(+), 39 deletions(-) diff --git a/config/locales/crowdin/js-ru.yml b/config/locales/crowdin/js-ru.yml index dd7fbe0715e8..69a70a3f2c50 100644 --- a/config/locales/crowdin/js-ru.yml +++ b/config/locales/crowdin/js-ru.yml @@ -375,7 +375,7 @@ ru: ical_generation_error_text: "Произошла ошибка при генерации URL-адреса календаря." success_message: 'URL-адрес "%{name}" был успешно скопирован в ваш буфер обмена. Вставьте его в свой клиент календаря, чтобы завершить подписку.' label_activate: "Активировать" - label_assignee: "Ответственный" + label_assignee: "Назначенный" label_add_column_after: "Добавить столбец после" label_add_column_before: "Добавить столбец перед" label_add_columns: "Добавить столбец" @@ -612,7 +612,7 @@ ru: mentioned: "упомянутый" watched: "наблюдатель" assigned: "назначенный" - responsible: "подотчетный" + responsible: "ответственный" created: "создано" scheduled: "запланировано" commented: "прокомментировано" @@ -659,7 +659,7 @@ ru: message: "Есть новые уведомления." link_text: "Нажмите здесь, чтобы загрузить их." menu: - accountable: "Подотчетный" + accountable: "Ответственный" by_project: "Непрочитано по проекту" by_reason: "Причина" inbox: "Входящие" @@ -688,7 +688,7 @@ ru: title: "Упомянутые" description: "Получать уведомления каждый раз, когда кто-то упоминает меня" assignee: "Назначенный" - responsible: "Подотчетный" + responsible: "Ответственный" shared: "Общий доступ" watched: "Наблюдатель" work_package_commented: "Все новые комментарии" diff --git a/config/locales/crowdin/js-zh-CN.yml b/config/locales/crowdin/js-zh-CN.yml index f862785208d3..079e463bec88 100644 --- a/config/locales/crowdin/js-zh-CN.yml +++ b/config/locales/crowdin/js-zh-CN.yml @@ -1341,9 +1341,9 @@ zh-CN: Close: "关闭" open_project_storage_modal: waiting_title: - timeout: "Timeout" + timeout: "超时" waiting_subtitle: network_off: "网络有问题。" network_on: "网络已恢复。我们正在努力。" timeout: > - OpenProject could not provide you access to the project folder within the expected period of time. Please, try once again.

    If that problem persists please contact you OpenProject administrator to check the health status of the file storage setup. + OpenProject无法让您在预期时间内访问项目文件夹。请再试一次。

    如果问题仍然存在,请联系OpenProject管理员检查文件存储设置的运行状况。 diff --git a/config/locales/crowdin/ms.yml b/config/locales/crowdin/ms.yml index dd3bf0aeffa9..f27ee892a5a3 100644 --- a/config/locales/crowdin/ms.yml +++ b/config/locales/crowdin/ms.yml @@ -3266,10 +3266,10 @@ ms: menu_item: "Item menu" menu_item_setting: "Keterlihatan" wiki_menu_item_for: 'Item menu untuk halaman wiki "%{title}"' - wiki_menu_item_setting: "Penglihatan" + wiki_menu_item_setting: "Keterlihatan" wiki_menu_item_new_main_item_explanation: > - Anda sedang memadam item menu utama wiki yang tunggal. Anda kini perlu memilih halaman wiki di mana item menu baharu akan dijanakan. Untuk memadamkan modul wiki tersebut, ianya boleh dinyahaktifkan oleh pentadbir projek. - wiki_menu_item_delete_not_permitted: Item menu wiki bagi halaman wiki tunggal tidak boleh dipadam. + Anda sedang memadam satu-satunya item menu utama wiki. Anda kini perlu memilih halaman wiki di mana item menu baharu akan dijanakan. Untuk memadamkan modul wiki tersebut, ianya boleh dinyahaktifkan oleh pentadbir projek. + wiki_menu_item_delete_not_permitted: Item menu wiki bagi satu-satunya halaman wiki tidak boleh dipadam. #TODO: merge with work_packages top level key work_package: updated_automatically_by_child_changes: | @@ -3280,9 +3280,9 @@ ms: progress: label_note: "Perhatian:" modal: - work_based_help_text: "% Lengkap secara automatik diperolehi daripada Kerja dan Kerja yang berbaki." - status_based_help_text: "% Lengkap ditetapkan oleh status pakej kerja." - migration_warning_text: "Dalam mod pengiraan perkembangan berdasarkan kerja, % Lengkap tidak boleh ditetapkan secara manual dan ianya terikat dengan Kerja. Nilai sedia ada tersebut telah disimpan tetapi tidak boleh diedit. Sila input Kerja dahulu." + work_based_help_text: "% Selesai secara automatik diperolehi daripada Kerja dan Kerja yang berbaki." + status_based_help_text: "% Selesai ditetapkan oleh status pakej kerja." + migration_warning_text: "Dalam mod pengiraan perkembangan berdasarkan kerja, % Selesai tidak boleh ditetapkan secara manual dan ianya terikat kepada Kerja. Nilai sedia ada tersebut telah disimpan tetapi tidak boleh diedit. Sila input Kerja dahulu." sharing: count: zero: "0 pengguna" @@ -3300,7 +3300,7 @@ ms: label_toggle_all: "Tukar semua perkongsian" permissions: comment: "Komen" - comment_description: "Boleh lihat dan komen tentang pakej kerja ini." + comment_description: "Boleh lihat dan komen berkenaan pakej kerja ini." denied: "Anda tidak mempunyai kebenaran untuk berkongsi pakej kerja." edit: "Edit" edit_description: "Boleh lihat, komen dan edit pakej kerja ini." @@ -3313,7 +3313,7 @@ ms: text_empty_state_description: "Pakej kerja masih belum dikongsikan dengan sesiapa lagi." text_empty_state_header: "Tidak dikongsikan" text_user_limit_reached: "Menambah pengguna tambahan akan melebihi had semasa. Sila hubungi pentadbir untuk meningkatkan had pengguna bagi memastikan pengguna luaran dapat mengakses pakej kerja ini." - text_user_limit_reached_admins: 'Menambah pengguna tambahan akan melebihi had semasa. Sila naik taraf pelan anda untuk dapat menambah lebih banyak pengguna.' + text_user_limit_reached_admins: 'Menambah pengguna tambahan akan melebihi had semasa. Sila naik taraf pelan anda untuk membolehkan untuk menambah lebih banyak pengguna.' warning_user_limit_reached: > Menambah pengguna tambahan akan melebihi had semasa. Sila hubungi pentadbir untuk meningkatkan had pengguna bagi memastikan pengguna luaran dapat mengakses pakej kerja ini. warning_user_limit_reached_admin: > @@ -3335,7 +3335,7 @@ ms: info: > Hari yang tidak dipilih akan dilangkau semasa penjadualan pakej kerja (dan tidak disertakan dalam jumlah hari). Ini boleh digantikan pada peringkat pakej kerja. instance_wide_info: > - Tarikh yang ditambah ke senarai dibawah diterima sebagai tidak berfungsi dan dilangkau semasa menjadualkan pakej kerja. + Tarikh yang ditambah ke senarai dibawah diterima sebagai tidak berfungsi dan dilangkau semasa penjadualan pakej kerja. change_button: "Tukar hari bekerja" warning: > Menukar hari mana dalam seminggu dianggap hari bekerja atau hari tidak bekerja boleh memberi kesan kepada hari mula dan tamat bagi semua pakej kerja dalam semua projek dalam kejadian ini.
    Sila ambil perhatian bahawa perubahan hanya dilaksanakan selepas anda klik butang terapkan perubahan. @@ -3375,7 +3375,7 @@ ms: invalid_relation: "Hubungan tersebut adalah tidak sah." invalid_resource: "Untuk ciri-ciri '%{property}' sebuah pautan seperti '%{expected}' dijangkakan, tetapi mendapat '%{actual}'." invalid_signal: - embed: "Permintaan menyemat %{invalid} tidak disokong. Penyematan yang disokong adalah %{supported}." + embed: "Permintaan menyemat %{invalid} tidak disokong. Penyematan yang disokong ialah %{supported}." select: "Permintaan %{invalid} yang dipilih tidak disokong. Pilihan yang disokong ialah %{supported}." invalid_user_status_transition: "Status akaun pengguna semasa tidak membenarkan operasi ini." missing_content_type: "tidak ditentukan" diff --git a/config/locales/crowdin/ru.yml b/config/locales/crowdin/ru.yml index 056a4baa31f8..3a0d4c59290b 100644 --- a/config/locales/crowdin/ru.yml +++ b/config/locales/crowdin/ru.yml @@ -1224,7 +1224,7 @@ ru: password: "Пароль" priority: "Приоритет" project: "Проект" - responsible: "Подотчетный" + responsible: "Ответственный" role: "Роль" roles: "Роли" start_date: "Дата начала" @@ -2465,7 +2465,7 @@ ru: reason: watched: "Просмотрено" assigned: "Назначено" - responsible: "Подотчетный" + responsible: "Ответственный" mentioned: "Упомянутые" shared: "Общий доступ" subscribed: "все" diff --git a/modules/boards/config/locales/crowdin/no.yml b/modules/boards/config/locales/crowdin/no.yml index e233de4921c3..4910340d70cc 100644 --- a/modules/boards/config/locales/crowdin/no.yml +++ b/modules/boards/config/locales/crowdin/no.yml @@ -15,7 +15,7 @@ free: Enkel action: "Handlingstavle (%{attribute})" board_type_attributes: - assignee: Deltaker + assignee: Utførende status: Status version: Versjon subproject: Underprosjekt diff --git a/modules/ldap_groups/config/locales/crowdin/no.yml b/modules/ldap_groups/config/locales/crowdin/no.yml index 18e5f1dca1d9..41fbca9d63d9 100644 --- a/modules/ldap_groups/config/locales/crowdin/no.yml +++ b/modules/ldap_groups/config/locales/crowdin/no.yml @@ -66,7 +66,7 @@ form: auth_source_text: 'Velg hvilken LDAP-tilkobling som skal brukes.' sync_users_text: > - Hvis du aktiverer dette valget, vil funnede brukere automatisk bli opprettet i OpenProject. Uten dette vil bare eksisterende kontoer i OpenProject bli lagt til i grupper. + Hvis du aktiverer dette valget, vil relevante brukere automatisk bli opprettet i OpenProject. Uten dette vil bare eksisterende kontoer i OpenProject bli lagt til i grupper. dn_text: 'Skriv inn hele DN for gruppen i LDAP' group_text: 'Velg en eksisterende OpenProject gruppe som medlemmene i LDAP-gruppen skal synkroniseres med' upsale: diff --git a/modules/openid_connect/config/locales/crowdin/no.yml b/modules/openid_connect/config/locales/crowdin/no.yml index a6aaeb100ef3..b019b1bda92b 100644 --- a/modules/openid_connect/config/locales/crowdin/no.yml +++ b/modules/openid_connect/config/locales/crowdin/no.yml @@ -1,7 +1,7 @@ "no": plugin_openproject_openid_connect: name: "OpenProject OpenID tilkobling" - description: "Legger til OmniAuth OpenID Connect strategileverandører til Openproject." + description: "Legger til strategileverandører for OmniAuth OpenID Connect til OpenProject." logout_warning: > Du har blitt logget ut. Innholdet kan gå tapt. Vennligst [logg in]. activemodel: @@ -10,23 +10,23 @@ name: Navn display_name: Visningsnavn identifier: Identifikator - secret: Hemmelig + secret: Hemmelig nøkkel scope: Omfang limit_self_registration: Begrens egenregistrering openid_connect: - menu_title: OpenID leverandører + menu_title: OpenID-leverandører providers: label_add_new: Legg til ny OpenID-leverandør label_edit: Rediger OpenID-leverandør %{name} no_results_table: Ingen leverandører har blitt definert ennå. - plural: OpenID leverandører + plural: OpenID-leverandører singular: OpenID-leverandør setting_instructions: azure_deprecation_warning: > - Den konfigurerte Asur-appen peker på et utdatert API fra Azure. Vennligst lag en ny Azure app for å sikre funksjonaliteten i fremtiden. + Den konfigurerte Azure-appen peker på et utdatert API fra Azure. Vennligst lag en ny Azure-app for å sikre funksjonaliteten i fremtiden. azure_graph_api: > Bruk «graph.microsoft.com»-brukerinfo til å be om brukerdata. Dette skal være standard med mindre du har en eldre Azure-applikasjon. azure_tenant_html: > - Sett leverandøren av ditt azure endepunkt. Dette vil kontrollere hvem som får tilgang til OpenProject instansen. For mer informasjon, se vår brukerveiledning på Azure OpenID tilkobling. + Sett leverandøren av ditt Azure-endepunkt. Dette vil kontrollere hvem som får tilgang til OpenProject-instansen. For mer informasjon, se vår brukerveiledning på Azure OpenID-tilkobling. limit_self_registration: > Hvis aktivert kan brukere bare registrere seg ved hjelp av denne leverandøren hvis selvregistreringsinnstillingen tillater det. diff --git a/modules/webhooks/config/locales/crowdin/no.yml b/modules/webhooks/config/locales/crowdin/no.yml index 796eb300644c..47bc3bb3c2fe 100644 --- a/modules/webhooks/config/locales/crowdin/no.yml +++ b/modules/webhooks/config/locales/crowdin/no.yml @@ -5,14 +5,14 @@ activerecord: attributes: webhooks/webhook: - url: 'Nyttelast URL' - secret: 'Hemmelig signatur' + url: 'Nyttelast-URL' + secret: 'Hemmelig signaturnøkkel' events: 'Hendelser' projects: 'Aktiverte prosjekter' webhooks/log: event_name: 'Navn på hendelse' - url: 'Nyttelast URL' - response_code: 'Svar kode' + url: 'Nyttelast-URL' + response_code: 'Svarkode' response_body: 'Svar' models: webhooks/outgoing_webhook: "Utgående webhook" @@ -21,26 +21,26 @@ plural: Webhooks resources: time_entry: - name: "Tid oppføring" + name: "Timeføring" outgoing: no_results_table: Ingen webhooks har blitt definert ennå. label_add_new: Legg til ny webhook label_edit: Rediger webhook - label_event_resources: Event ressurser + label_event_resources: Hendelsesressurser events: created: "Opprettet" updated: "Oppdatert" explanation: text: > - Ved forekomst av en hendelse som oppretting av en arbeidspakke eller en oppdatering fra et prosjekt, OpenProject vil sende en POST-forespørsel til de konfigurerte nettendepunktene. Ofte blir arrangementet sendt etter at %{link} er godkjent. + Ved forekomst av en hendelse som oppretting av en arbeidspakke eller en oppdatering fra et prosjekt, vil OpenProject sende en POST-forespørsel til de konfigurerte nettendepunktene. Ofte blir hendelsen sendt etter at %{link} er godkjent. link: konfigurert summeringsperiode status: - enabled: 'Webhooks aktivert' - disabled: 'Webhooks er deaktivert' - enabled_text: 'webhooken sender ut nyttelaster for de definerte hendelsene nedenfor.' + enabled: 'Webhook er aktivert' + disabled: 'Webhook er deaktivert' + enabled_text: 'Webhooken sender ut nyttelaster for de definerte hendelsene nedenfor.' disabled_text: 'Klikk på rediger-knappen for å aktivere webhook.' deliveries: - no_results_table: Ingen leveranser er gjennomført for dette webhooket de siste dagene. + no_results_table: Ingen leveranser er gjennomført for denne webhooken de siste dagene. title: 'Nylige leveranser' time: 'Tid for levering' form: @@ -51,7 +51,7 @@ placeholder: 'Valgfri beskrivelse for webhook.' enabled: description: > - Når merket av, vil webhook utløse på de valgte hendelsene. Fjern avmerkingen for å deaktivere webhook. + Når merket av, vil webhooken utløses for de valgte hendelsene. Fjern merkingen for å deaktivere webhooken. events: title: 'Aktiverte hendelser' project_ids: @@ -63,4 +63,4 @@ title: 'Valgte prosjekter' secret: description: > - Hvis angitt, brukes denne hemmelige verdien av OpenProject for å signere webhook nyttelasten. + Hvis angitt, brukes denne hemmelige verdien av OpenProject for å signere webhook-nyttelasten. From 6d31291aac41c01ba2669d1a71bff39a17543a5d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Jun 2024 05:24:53 +0000 Subject: [PATCH 146/176] Bump the fullcalendar group in /frontend with 8 updates Bumps the fullcalendar group in /frontend with 8 updates: | Package | From | To | | --- | --- | --- | | [@fullcalendar/angular](https://github.com/fullcalendar/fullcalendar-angular) | `6.1.13` | `6.1.14` | | [@fullcalendar/core](https://github.com/fullcalendar/fullcalendar/tree/HEAD/packages/core) | `6.1.13` | `6.1.14` | | [@fullcalendar/daygrid](https://github.com/fullcalendar/fullcalendar/tree/HEAD/packages/daygrid) | `6.1.13` | `6.1.14` | | [@fullcalendar/interaction](https://github.com/fullcalendar/fullcalendar/tree/HEAD/packages/interaction) | `6.1.13` | `6.1.14` | | [@fullcalendar/list](https://github.com/fullcalendar/fullcalendar/tree/HEAD/packages/list) | `6.1.13` | `6.1.14` | | [@fullcalendar/resource](https://github.com/fullcalendar/fullcalendar-workspace/tree/HEAD/premium/packages/resource) | `6.1.13` | `6.1.14` | | [@fullcalendar/resource-timeline](https://github.com/fullcalendar/fullcalendar-workspace/tree/HEAD/premium/packages/resource-timeline) | `6.1.13` | `6.1.14` | | [@fullcalendar/timegrid](https://github.com/fullcalendar/fullcalendar/tree/HEAD/packages/timegrid) | `6.1.13` | `6.1.14` | Updates `@fullcalendar/angular` from 6.1.13 to 6.1.14 - [Release notes](https://github.com/fullcalendar/fullcalendar-angular/releases) - [Changelog](https://github.com/fullcalendar/fullcalendar-angular/blob/main/CHANGELOG.md) - [Commits](https://github.com/fullcalendar/fullcalendar-angular/compare/v6.1.13...v6.1.14) Updates `@fullcalendar/core` from 6.1.13 to 6.1.14 - [Release notes](https://github.com/fullcalendar/fullcalendar/releases) - [Changelog](https://github.com/fullcalendar/fullcalendar/blob/main/CHANGELOG.md) - [Commits](https://github.com/fullcalendar/fullcalendar/commits/v6.1.14/packages/core) Updates `@fullcalendar/daygrid` from 6.1.13 to 6.1.14 - [Release notes](https://github.com/fullcalendar/fullcalendar/releases) - [Changelog](https://github.com/fullcalendar/fullcalendar/blob/main/CHANGELOG.md) - [Commits](https://github.com/fullcalendar/fullcalendar/commits/v6.1.14/packages/daygrid) Updates `@fullcalendar/interaction` from 6.1.13 to 6.1.14 - [Release notes](https://github.com/fullcalendar/fullcalendar/releases) - [Changelog](https://github.com/fullcalendar/fullcalendar/blob/main/CHANGELOG.md) - [Commits](https://github.com/fullcalendar/fullcalendar/commits/v6.1.14/packages/interaction) Updates `@fullcalendar/list` from 6.1.13 to 6.1.14 - [Release notes](https://github.com/fullcalendar/fullcalendar/releases) - [Changelog](https://github.com/fullcalendar/fullcalendar/blob/main/CHANGELOG.md) - [Commits](https://github.com/fullcalendar/fullcalendar/commits/v6.1.14/packages/list) Updates `@fullcalendar/resource` from 6.1.13 to 6.1.14 - [Release notes](https://github.com/fullcalendar/fullcalendar-workspace/releases) - [Commits](https://github.com/fullcalendar/fullcalendar-workspace/commits/v6.1.14/premium/packages/resource) Updates `@fullcalendar/resource-timeline` from 6.1.13 to 6.1.14 - [Release notes](https://github.com/fullcalendar/fullcalendar-workspace/releases) - [Commits](https://github.com/fullcalendar/fullcalendar-workspace/commits/v6.1.14/premium/packages/resource-timeline) Updates `@fullcalendar/timegrid` from 6.1.13 to 6.1.14 - [Release notes](https://github.com/fullcalendar/fullcalendar/releases) - [Changelog](https://github.com/fullcalendar/fullcalendar/blob/main/CHANGELOG.md) - [Commits](https://github.com/fullcalendar/fullcalendar/commits/v6.1.14/packages/timegrid) --- updated-dependencies: - dependency-name: "@fullcalendar/angular" dependency-type: direct:production update-type: version-update:semver-patch dependency-group: fullcalendar - dependency-name: "@fullcalendar/core" dependency-type: direct:production update-type: version-update:semver-patch dependency-group: fullcalendar - dependency-name: "@fullcalendar/daygrid" dependency-type: direct:production update-type: version-update:semver-patch dependency-group: fullcalendar - dependency-name: "@fullcalendar/interaction" dependency-type: direct:production update-type: version-update:semver-patch dependency-group: fullcalendar - dependency-name: "@fullcalendar/list" dependency-type: direct:production update-type: version-update:semver-patch dependency-group: fullcalendar - dependency-name: "@fullcalendar/resource" dependency-type: direct:production update-type: version-update:semver-patch dependency-group: fullcalendar - dependency-name: "@fullcalendar/resource-timeline" dependency-type: direct:production update-type: version-update:semver-patch dependency-group: fullcalendar - dependency-name: "@fullcalendar/timegrid" dependency-type: direct:production update-type: version-update:semver-patch dependency-group: fullcalendar ... Signed-off-by: dependabot[bot] --- frontend/package-lock.json | 190 ++++++++++++++++++------------------- 1 file changed, 95 insertions(+), 95 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index f748fe3157f5..a2ead2037376 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -3352,16 +3352,16 @@ "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" }, "node_modules/@fullcalendar/angular": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/@fullcalendar/angular/-/angular-6.1.13.tgz", - "integrity": "sha512-2JxrIUl6xtAAou3a5i/XmovyWwqTMYBmI+6RhyVcx38EhpyFOMlAtx+63m8m2ADJSiph6Nc9nkKFN/A+rR0F7g==", + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/@fullcalendar/angular/-/angular-6.1.14.tgz", + "integrity": "sha512-No6BFb6/KBjj7CMYy5MYq27Q2ycWqZUIupDExpcm5SuJy8c+SwFSnjGzu0Tm4/i0Z48n+ssQ/wjVVSUQcekbZg==", "dependencies": { "tslib": "^2.3.0" }, "peerDependencies": { - "@angular/common": "12 - 17", - "@angular/core": "12 - 17", - "@fullcalendar/core": "~6.1.13" + "@angular/common": "12 - 18", + "@angular/core": "12 - 18", + "@fullcalendar/core": "~6.1.14" } }, "node_modules/@fullcalendar/common": { @@ -3373,54 +3373,54 @@ } }, "node_modules/@fullcalendar/core": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-6.1.13.tgz", - "integrity": "sha512-Cps/hMQan4kwnsBhFf2+m2mijbGoWs6r18ZzxBnAAOkkNHtPmHU8EdR6lF+ZLsiVvb7nsC4H/ZKqnxXWwgpoPw==", + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-6.1.14.tgz", + "integrity": "sha512-hIPRBevm0aMc2aHy1hRIJgXmI1QTvQM1neQa9oxtuqUmF1+ApYC3oAdwcQMTuI7lHHw3pKJDyJFkKLPPnL6HXA==", "dependencies": { "preact": "~10.12.1" } }, "node_modules/@fullcalendar/daygrid": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/@fullcalendar/daygrid/-/daygrid-6.1.13.tgz", - "integrity": "sha512-0I0hL1kgGjkZuc7Qt8mu4jjrqIL5PZzd58bEpTxoXRKI5UBZ9KbshGVMryQSXYANlrRtkPnXVt90VIDrxZbDrA==", + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/@fullcalendar/daygrid/-/daygrid-6.1.14.tgz", + "integrity": "sha512-DSyjiA1dEM8k3bOCrZpZOmAOZu71KGtH02ze+4QKuhxkmn/zQghmmLRdfzpOrcyJg6xGKkoB4pBcO+2lXar8XQ==", "peerDependencies": { - "@fullcalendar/core": "~6.1.13" + "@fullcalendar/core": "~6.1.14" } }, "node_modules/@fullcalendar/interaction": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/@fullcalendar/interaction/-/interaction-6.1.13.tgz", - "integrity": "sha512-r1w+jqCRGZZyxKFquueDSFvbsFhJLhc1BX8Nlyz684lYxS1SiToYJW9Q8X/XkySCzpjO3KOnxEp2jVOn1Usyjg==", + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/@fullcalendar/interaction/-/interaction-6.1.14.tgz", + "integrity": "sha512-rXum5XCjq+WEPNctFeYL/JKZGeU2rlxrElygocdMegcrIBJQW5hnWWVE+i4/1dOmUKF80CbGVlXUyYXoqK2eFg==", "peerDependencies": { - "@fullcalendar/core": "~6.1.13" + "@fullcalendar/core": "~6.1.14" } }, "node_modules/@fullcalendar/list": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/@fullcalendar/list/-/list-6.1.13.tgz", - "integrity": "sha512-bPW4EsgGNwDZh91NtD+q4hqGfS6jEvCXQo7+MNy4JLMwFtdenEURRrzsb6CW3l97L3Vp0E2mSqiXaNESOmXEcQ==", + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/@fullcalendar/list/-/list-6.1.14.tgz", + "integrity": "sha512-eV0/6iCumYfvlPzIUTAONWH17/JlQCyCChUz8m06L4E/sOiNjkHGz8vlVTmZKqXzx9oWOOyV/Nm3pCtHmVZh+Q==", "peerDependencies": { - "@fullcalendar/core": "~6.1.13" + "@fullcalendar/core": "~6.1.14" } }, "node_modules/@fullcalendar/premium-common": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/@fullcalendar/premium-common/-/premium-common-6.1.13.tgz", - "integrity": "sha512-ym68zNPUYGSROsgh/7hcEfIZ56MLCO4ffqF/MABldwKYN0qOIbWfB+EBfr9I6L1nIb5FNKzwhAlTGh9/y/R/BQ==", + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/@fullcalendar/premium-common/-/premium-common-6.1.14.tgz", + "integrity": "sha512-Fw8GZ6mjZtv6toliSr3iHwIqLIjx3+7fdd828OO4LGzX1wcnCd74CfWqR1tvg+9YLUKmRXNEGgQaN4y5j/XpKg==", "peerDependencies": { - "@fullcalendar/core": "~6.1.13" + "@fullcalendar/core": "~6.1.14" } }, "node_modules/@fullcalendar/resource": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/@fullcalendar/resource/-/resource-6.1.13.tgz", - "integrity": "sha512-4s34o4qNbPNY1Zo6EyAXylT1D7uAENcmlvSwWADkzH+Rx0aVyY8wdhCXqzqyTcgYz6jRrD32asRjVyWlXJWD8A==", + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/@fullcalendar/resource/-/resource-6.1.14.tgz", + "integrity": "sha512-iTwFIZ/EMDoUaJArsNXbpIeGjkQLgm1R4lKD7WwJ2bC+FGNwCs3lVDYrWaCwCggt38BoVDewWcSVkDy1lyhd3A==", "dependencies": { - "@fullcalendar/premium-common": "~6.1.13" + "@fullcalendar/premium-common": "~6.1.14" }, "peerDependencies": { - "@fullcalendar/core": "~6.1.13" + "@fullcalendar/core": "~6.1.14" } }, "node_modules/@fullcalendar/resource-common": { @@ -3443,51 +3443,51 @@ } }, "node_modules/@fullcalendar/resource-timeline": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/@fullcalendar/resource-timeline/-/resource-timeline-6.1.13.tgz", - "integrity": "sha512-ASCLiiuJIgViaoUGPxdK1eI2gNo8AwXSnuwZUpGYMPlHPgqYhm5PwGKvZX8pZfhWa9FFIHWr5cDEMyv5UwJxfQ==", + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/@fullcalendar/resource-timeline/-/resource-timeline-6.1.14.tgz", + "integrity": "sha512-YzmGlfIRMiXHnHSJXdHiW9rqNEVgMHNlgBi5dDmd/g5huhJeHa+thZsy0rrFbHorN+ZQWX2m0R5DIhpLtnmGog==", "dependencies": { - "@fullcalendar/premium-common": "~6.1.13", - "@fullcalendar/scrollgrid": "~6.1.13", - "@fullcalendar/timeline": "~6.1.13" + "@fullcalendar/premium-common": "~6.1.14", + "@fullcalendar/scrollgrid": "~6.1.14", + "@fullcalendar/timeline": "~6.1.14" }, "peerDependencies": { - "@fullcalendar/core": "~6.1.13", - "@fullcalendar/resource": "~6.1.13" + "@fullcalendar/core": "~6.1.14", + "@fullcalendar/resource": "~6.1.14" } }, "node_modules/@fullcalendar/scrollgrid": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/@fullcalendar/scrollgrid/-/scrollgrid-6.1.13.tgz", - "integrity": "sha512-gIsEGkOfLPMAqclYiZeSyzWxUM+mzlWCFqv1SnJRN6bsO5Lx3hibqWDJDDYgpTFHwjIQKNKGhuxN89lXsi/P9g==", + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/@fullcalendar/scrollgrid/-/scrollgrid-6.1.14.tgz", + "integrity": "sha512-LVLdjMgzf0uDNWzB7GWOrZAGF61pa/J0ipJHfG3BTO5Ri5qZbOHpVcPuW94LOFnaGZpbaOG2YQlKygrujAAbvA==", "dependencies": { - "@fullcalendar/premium-common": "~6.1.13" + "@fullcalendar/premium-common": "~6.1.14" }, "peerDependencies": { - "@fullcalendar/core": "~6.1.13" + "@fullcalendar/core": "~6.1.14" } }, "node_modules/@fullcalendar/timegrid": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/@fullcalendar/timegrid/-/timegrid-6.1.13.tgz", - "integrity": "sha512-8Ub2mSV+6Mh8WWDKuyCYbj5PKYpmyjSctpJ/21fDBJduE9QFS0WfG9CZZxSJT7CT+srnyk4mX2/5gYN9gYZjUg==", + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/@fullcalendar/timegrid/-/timegrid-6.1.14.tgz", + "integrity": "sha512-ZByc3BVAtxWSVfyaNedROLlg/Tb2NQ43+MZZAfBSrVwVm2xyfQ+Bsx3pJyCXsRsUh2TFFTO07q7nMWe0jet3KQ==", "dependencies": { - "@fullcalendar/daygrid": "~6.1.13" + "@fullcalendar/daygrid": "~6.1.14" }, "peerDependencies": { - "@fullcalendar/core": "~6.1.13" + "@fullcalendar/core": "~6.1.14" } }, "node_modules/@fullcalendar/timeline": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/@fullcalendar/timeline/-/timeline-6.1.13.tgz", - "integrity": "sha512-5lqjZYE1Mu+2xHb1Y9J/E8BlyHsu0FeGzPQoyL3L6rqTwttxv1Dpxy28teWr8KN9NpCGKYQCMFzbADo6DEgHeA==", + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/@fullcalendar/timeline/-/timeline-6.1.14.tgz", + "integrity": "sha512-5UvugmoJsXeinrHwH57hMgFWh77KagWtxOkrSL5DwaRj4DTb2loV/pkYD5GJaMjpsZqZcUW0V8kICUzNbkZXag==", "dependencies": { - "@fullcalendar/premium-common": "~6.1.13", - "@fullcalendar/scrollgrid": "~6.1.13" + "@fullcalendar/premium-common": "~6.1.14", + "@fullcalendar/scrollgrid": "~6.1.14" }, "peerDependencies": { - "@fullcalendar/core": "~6.1.13" + "@fullcalendar/core": "~6.1.14" } }, "node_modules/@github/auto-check-element": { @@ -25183,9 +25183,9 @@ "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" }, "@fullcalendar/angular": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/@fullcalendar/angular/-/angular-6.1.13.tgz", - "integrity": "sha512-2JxrIUl6xtAAou3a5i/XmovyWwqTMYBmI+6RhyVcx38EhpyFOMlAtx+63m8m2ADJSiph6Nc9nkKFN/A+rR0F7g==", + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/@fullcalendar/angular/-/angular-6.1.14.tgz", + "integrity": "sha512-No6BFb6/KBjj7CMYy5MYq27Q2ycWqZUIupDExpcm5SuJy8c+SwFSnjGzu0Tm4/i0Z48n+ssQ/wjVVSUQcekbZg==", "requires": { "tslib": "^2.3.0" } @@ -25199,39 +25199,39 @@ } }, "@fullcalendar/core": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-6.1.13.tgz", - "integrity": "sha512-Cps/hMQan4kwnsBhFf2+m2mijbGoWs6r18ZzxBnAAOkkNHtPmHU8EdR6lF+ZLsiVvb7nsC4H/ZKqnxXWwgpoPw==", + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-6.1.14.tgz", + "integrity": "sha512-hIPRBevm0aMc2aHy1hRIJgXmI1QTvQM1neQa9oxtuqUmF1+ApYC3oAdwcQMTuI7lHHw3pKJDyJFkKLPPnL6HXA==", "requires": { "preact": "~10.12.1" } }, "@fullcalendar/daygrid": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/@fullcalendar/daygrid/-/daygrid-6.1.13.tgz", - "integrity": "sha512-0I0hL1kgGjkZuc7Qt8mu4jjrqIL5PZzd58bEpTxoXRKI5UBZ9KbshGVMryQSXYANlrRtkPnXVt90VIDrxZbDrA==" + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/@fullcalendar/daygrid/-/daygrid-6.1.14.tgz", + "integrity": "sha512-DSyjiA1dEM8k3bOCrZpZOmAOZu71KGtH02ze+4QKuhxkmn/zQghmmLRdfzpOrcyJg6xGKkoB4pBcO+2lXar8XQ==" }, "@fullcalendar/interaction": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/@fullcalendar/interaction/-/interaction-6.1.13.tgz", - "integrity": "sha512-r1w+jqCRGZZyxKFquueDSFvbsFhJLhc1BX8Nlyz684lYxS1SiToYJW9Q8X/XkySCzpjO3KOnxEp2jVOn1Usyjg==" + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/@fullcalendar/interaction/-/interaction-6.1.14.tgz", + "integrity": "sha512-rXum5XCjq+WEPNctFeYL/JKZGeU2rlxrElygocdMegcrIBJQW5hnWWVE+i4/1dOmUKF80CbGVlXUyYXoqK2eFg==" }, "@fullcalendar/list": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/@fullcalendar/list/-/list-6.1.13.tgz", - "integrity": "sha512-bPW4EsgGNwDZh91NtD+q4hqGfS6jEvCXQo7+MNy4JLMwFtdenEURRrzsb6CW3l97L3Vp0E2mSqiXaNESOmXEcQ==" + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/@fullcalendar/list/-/list-6.1.14.tgz", + "integrity": "sha512-eV0/6iCumYfvlPzIUTAONWH17/JlQCyCChUz8m06L4E/sOiNjkHGz8vlVTmZKqXzx9oWOOyV/Nm3pCtHmVZh+Q==" }, "@fullcalendar/premium-common": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/@fullcalendar/premium-common/-/premium-common-6.1.13.tgz", - "integrity": "sha512-ym68zNPUYGSROsgh/7hcEfIZ56MLCO4ffqF/MABldwKYN0qOIbWfB+EBfr9I6L1nIb5FNKzwhAlTGh9/y/R/BQ==" + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/@fullcalendar/premium-common/-/premium-common-6.1.14.tgz", + "integrity": "sha512-Fw8GZ6mjZtv6toliSr3iHwIqLIjx3+7fdd828OO4LGzX1wcnCd74CfWqR1tvg+9YLUKmRXNEGgQaN4y5j/XpKg==" }, "@fullcalendar/resource": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/@fullcalendar/resource/-/resource-6.1.13.tgz", - "integrity": "sha512-4s34o4qNbPNY1Zo6EyAXylT1D7uAENcmlvSwWADkzH+Rx0aVyY8wdhCXqzqyTcgYz6jRrD32asRjVyWlXJWD8A==", + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/@fullcalendar/resource/-/resource-6.1.14.tgz", + "integrity": "sha512-iTwFIZ/EMDoUaJArsNXbpIeGjkQLgm1R4lKD7WwJ2bC+FGNwCs3lVDYrWaCwCggt38BoVDewWcSVkDy1lyhd3A==", "requires": { - "@fullcalendar/premium-common": "~6.1.13" + "@fullcalendar/premium-common": "~6.1.14" } }, "@fullcalendar/resource-common": { @@ -25256,38 +25256,38 @@ } }, "@fullcalendar/resource-timeline": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/@fullcalendar/resource-timeline/-/resource-timeline-6.1.13.tgz", - "integrity": "sha512-ASCLiiuJIgViaoUGPxdK1eI2gNo8AwXSnuwZUpGYMPlHPgqYhm5PwGKvZX8pZfhWa9FFIHWr5cDEMyv5UwJxfQ==", + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/@fullcalendar/resource-timeline/-/resource-timeline-6.1.14.tgz", + "integrity": "sha512-YzmGlfIRMiXHnHSJXdHiW9rqNEVgMHNlgBi5dDmd/g5huhJeHa+thZsy0rrFbHorN+ZQWX2m0R5DIhpLtnmGog==", "requires": { - "@fullcalendar/premium-common": "~6.1.13", - "@fullcalendar/scrollgrid": "~6.1.13", - "@fullcalendar/timeline": "~6.1.13" + "@fullcalendar/premium-common": "~6.1.14", + "@fullcalendar/scrollgrid": "~6.1.14", + "@fullcalendar/timeline": "~6.1.14" } }, "@fullcalendar/scrollgrid": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/@fullcalendar/scrollgrid/-/scrollgrid-6.1.13.tgz", - "integrity": "sha512-gIsEGkOfLPMAqclYiZeSyzWxUM+mzlWCFqv1SnJRN6bsO5Lx3hibqWDJDDYgpTFHwjIQKNKGhuxN89lXsi/P9g==", + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/@fullcalendar/scrollgrid/-/scrollgrid-6.1.14.tgz", + "integrity": "sha512-LVLdjMgzf0uDNWzB7GWOrZAGF61pa/J0ipJHfG3BTO5Ri5qZbOHpVcPuW94LOFnaGZpbaOG2YQlKygrujAAbvA==", "requires": { - "@fullcalendar/premium-common": "~6.1.13" + "@fullcalendar/premium-common": "~6.1.14" } }, "@fullcalendar/timegrid": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/@fullcalendar/timegrid/-/timegrid-6.1.13.tgz", - "integrity": "sha512-8Ub2mSV+6Mh8WWDKuyCYbj5PKYpmyjSctpJ/21fDBJduE9QFS0WfG9CZZxSJT7CT+srnyk4mX2/5gYN9gYZjUg==", + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/@fullcalendar/timegrid/-/timegrid-6.1.14.tgz", + "integrity": "sha512-ZByc3BVAtxWSVfyaNedROLlg/Tb2NQ43+MZZAfBSrVwVm2xyfQ+Bsx3pJyCXsRsUh2TFFTO07q7nMWe0jet3KQ==", "requires": { - "@fullcalendar/daygrid": "~6.1.13" + "@fullcalendar/daygrid": "~6.1.14" } }, "@fullcalendar/timeline": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/@fullcalendar/timeline/-/timeline-6.1.13.tgz", - "integrity": "sha512-5lqjZYE1Mu+2xHb1Y9J/E8BlyHsu0FeGzPQoyL3L6rqTwttxv1Dpxy28teWr8KN9NpCGKYQCMFzbADo6DEgHeA==", + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/@fullcalendar/timeline/-/timeline-6.1.14.tgz", + "integrity": "sha512-5UvugmoJsXeinrHwH57hMgFWh77KagWtxOkrSL5DwaRj4DTb2loV/pkYD5GJaMjpsZqZcUW0V8kICUzNbkZXag==", "requires": { - "@fullcalendar/premium-common": "~6.1.13", - "@fullcalendar/scrollgrid": "~6.1.13" + "@fullcalendar/premium-common": "~6.1.14", + "@fullcalendar/scrollgrid": "~6.1.14" } }, "@github/auto-check-element": { From b063f5539cf9440062d6105cd70859038ea8d4ac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Jun 2024 05:56:58 +0000 Subject: [PATCH 147/176] Bump rails from 7.1.3.3 to 7.1.3.4 Bumps [rails](https://github.com/rails/rails) from 7.1.3.3 to 7.1.3.4. - [Release notes](https://github.com/rails/rails/releases) - [Commits](https://github.com/rails/rails/compare/v7.1.3.3...v7.1.3.4) --- updated-dependencies: - dependency-name: rails dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 116 +++++++++++++++++++++++++-------------------------- 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 33240a7e53fb..37e77dab8df1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -226,35 +226,35 @@ GEM remote: https://rubygems.org/ specs: Ascii85 (1.1.1) - actioncable (7.1.3.3) - actionpack (= 7.1.3.3) - activesupport (= 7.1.3.3) + actioncable (7.1.3.4) + actionpack (= 7.1.3.4) + activesupport (= 7.1.3.4) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (7.1.3.3) - actionpack (= 7.1.3.3) - activejob (= 7.1.3.3) - activerecord (= 7.1.3.3) - activestorage (= 7.1.3.3) - activesupport (= 7.1.3.3) + actionmailbox (7.1.3.4) + actionpack (= 7.1.3.4) + activejob (= 7.1.3.4) + activerecord (= 7.1.3.4) + activestorage (= 7.1.3.4) + activesupport (= 7.1.3.4) mail (>= 2.7.1) net-imap net-pop net-smtp - actionmailer (7.1.3.3) - actionpack (= 7.1.3.3) - actionview (= 7.1.3.3) - activejob (= 7.1.3.3) - activesupport (= 7.1.3.3) + actionmailer (7.1.3.4) + actionpack (= 7.1.3.4) + actionview (= 7.1.3.4) + activejob (= 7.1.3.4) + activesupport (= 7.1.3.4) mail (~> 2.5, >= 2.5.4) net-imap net-pop net-smtp rails-dom-testing (~> 2.2) - actionpack (7.1.3.3) - actionview (= 7.1.3.3) - activesupport (= 7.1.3.3) + actionpack (7.1.3.4) + actionview (= 7.1.3.4) + activesupport (= 7.1.3.4) nokogiri (>= 1.8.5) racc rack (>= 2.2.4) @@ -265,31 +265,31 @@ GEM actionpack-xml_parser (2.0.1) actionpack (>= 5.0) railties (>= 5.0) - actiontext (7.1.3.3) - actionpack (= 7.1.3.3) - activerecord (= 7.1.3.3) - activestorage (= 7.1.3.3) - activesupport (= 7.1.3.3) + actiontext (7.1.3.4) + actionpack (= 7.1.3.4) + activerecord (= 7.1.3.4) + activestorage (= 7.1.3.4) + activesupport (= 7.1.3.4) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.1.3.3) - activesupport (= 7.1.3.3) + actionview (7.1.3.4) + activesupport (= 7.1.3.4) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - activejob (7.1.3.3) - activesupport (= 7.1.3.3) + activejob (7.1.3.4) + activesupport (= 7.1.3.4) globalid (>= 0.3.6) - activemodel (7.1.3.3) - activesupport (= 7.1.3.3) + activemodel (7.1.3.4) + activesupport (= 7.1.3.4) activemodel-serializers-xml (1.0.2) activemodel (> 5.x) activesupport (> 5.x) builder (~> 3.1) - activerecord (7.1.3.3) - activemodel (= 7.1.3.3) - activesupport (= 7.1.3.3) + activerecord (7.1.3.4) + activemodel (= 7.1.3.4) + activesupport (= 7.1.3.4) timeout (>= 0.4.0) activerecord-import (1.7.0) activerecord (>= 4.2) @@ -302,13 +302,13 @@ GEM multi_json (~> 1.11, >= 1.11.2) rack (>= 2.0.8, < 4) railties (>= 6.1) - activestorage (7.1.3.3) - actionpack (= 7.1.3.3) - activejob (= 7.1.3.3) - activerecord (= 7.1.3.3) - activesupport (= 7.1.3.3) + activestorage (7.1.3.4) + actionpack (= 7.1.3.4) + activejob (= 7.1.3.4) + activerecord (= 7.1.3.4) + activesupport (= 7.1.3.4) marcel (~> 1.0) - activesupport (7.1.3.3) + activesupport (7.1.3.4) base64 bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) @@ -424,7 +424,7 @@ GEM rb_sys (~> 0.9) compare-xml (0.66) nokogiri (~> 1.8) - concurrent-ruby (1.2.3) + concurrent-ruby (1.3.1) connection_pool (2.4.1) cookiejar (0.3.4) cose (1.3.0) @@ -724,7 +724,7 @@ GEM mime-types-data (3.2024.0507) mini_magick (4.12.0) mini_mime (1.1.5) - mini_portile2 (2.8.6) + mini_portile2 (2.8.7) minitest (5.23.1) msgpack (1.7.2) multi_json (1.15.0) @@ -735,7 +735,7 @@ GEM mutex_m (0.2.0) net-http (0.4.1) uri - net-imap (0.4.11) + net-imap (0.4.12) date net-protocol net-ldap (0.19.0) @@ -876,20 +876,20 @@ GEM rackup (1.0.0) rack (< 3) webrick - rails (7.1.3.3) - actioncable (= 7.1.3.3) - actionmailbox (= 7.1.3.3) - actionmailer (= 7.1.3.3) - actionpack (= 7.1.3.3) - actiontext (= 7.1.3.3) - actionview (= 7.1.3.3) - activejob (= 7.1.3.3) - activemodel (= 7.1.3.3) - activerecord (= 7.1.3.3) - activestorage (= 7.1.3.3) - activesupport (= 7.1.3.3) + rails (7.1.3.4) + actioncable (= 7.1.3.4) + actionmailbox (= 7.1.3.4) + actionmailer (= 7.1.3.4) + actionpack (= 7.1.3.4) + actiontext (= 7.1.3.4) + actionview (= 7.1.3.4) + activejob (= 7.1.3.4) + activemodel (= 7.1.3.4) + activerecord (= 7.1.3.4) + activestorage (= 7.1.3.4) + activesupport (= 7.1.3.4) bundler (>= 1.15.0) - railties (= 7.1.3.3) + railties (= 7.1.3.4) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) @@ -904,9 +904,9 @@ GEM rails-i18n (7.0.9) i18n (>= 0.7, < 2) railties (>= 6.0.0, < 8) - railties (7.1.3.3) - actionpack (= 7.1.3.3) - activesupport (= 7.1.3.3) + railties (7.1.3.4) + actionpack (= 7.1.3.4) + activesupport (= 7.1.3.4) irb rackup (>= 1.0.0) rake (>= 12.2) @@ -928,7 +928,7 @@ GEM redis-client (0.22.2) connection_pool regexp_parser (2.9.2) - reline (0.5.7) + reline (0.5.8) io-console (~> 0.5) representable (3.2.0) declarative (< 0.1.0) @@ -1153,7 +1153,7 @@ GEM xpath (3.2.0) nokogiri (~> 1.8) yard (0.9.36) - zeitwerk (2.6.14) + zeitwerk (2.6.15) PLATFORMS ruby From 86e259ab1aefd82dee7d348fb135a6ef455a3d0b Mon Sep 17 00:00:00 2001 From: Henriette Darge Date: Wed, 5 Jun 2024 09:27:32 +0200 Subject: [PATCH 148/176] Bump octicons to 19.14.0 and view_components to 0.33.1 --- Gemfile | 6 +++--- Gemfile.lock | 14 ++++++------- frontend/package-lock.json | 42 +++++++++++++++++++------------------- frontend/package.json | 6 +++--- 4 files changed, 34 insertions(+), 34 deletions(-) diff --git a/Gemfile b/Gemfile index 3d2a029227ef..f319e751a1e3 100644 --- a/Gemfile +++ b/Gemfile @@ -386,6 +386,6 @@ gemfiles.each do |file| send(:eval_gemfile, file) if File.readable?(file) end -gem "openproject-octicons", "~>19.13.0" -gem "openproject-octicons_helper", "~>19.13.0" -gem "openproject-primer_view_components", "~>0.32.1" +gem "openproject-octicons", "~>19.14.0" +gem "openproject-octicons_helper", "~>19.14.0" +gem "openproject-primer_view_components", "~>0.33.1" diff --git a/Gemfile.lock b/Gemfile.lock index 33240a7e53fb..7bc4969accb9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -770,12 +770,12 @@ GEM validate_email validate_url webfinger (~> 2.0) - openproject-octicons (19.13.0) - openproject-octicons_helper (19.13.0) + openproject-octicons (19.14.0) + openproject-octicons_helper (19.14.0) actionview - openproject-octicons (= 19.13.0) + openproject-octicons (= 19.14.0) railties - openproject-primer_view_components (0.32.1) + openproject-primer_view_components (0.33.1) actionview (>= 5.0.0) activesupport (>= 5.0.0) openproject-octicons (>= 19.12.0) @@ -1266,10 +1266,10 @@ DEPENDENCIES openproject-job_status! openproject-ldap_groups! openproject-meeting! - openproject-octicons (~> 19.13.0) - openproject-octicons_helper (~> 19.13.0) + openproject-octicons (~> 19.14.0) + openproject-octicons_helper (~> 19.14.0) openproject-openid_connect! - openproject-primer_view_components (~> 0.32.1) + openproject-primer_view_components (~> 0.33.1) openproject-recaptcha! openproject-reporting! openproject-storages! diff --git a/frontend/package-lock.json b/frontend/package-lock.json index a2ead2037376..152a7800cfff 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -46,8 +46,8 @@ "@ng-select/ng-select": "^12.0.7", "@ngneat/content-loader": "^7.0.0", "@ngx-formly/core": "^6.1.4", - "@openproject/octicons-angular": "^19.13.0", - "@openproject/primer-view-components": "^0.32.1", + "@openproject/octicons-angular": "^19.14.0", + "@openproject/primer-view-components": "^0.33.1", "@openproject/reactivestates": "^3.0.1", "@primer/css": "^21.2.2", "@types/hotwired__turbo": "^8.0.1", @@ -4802,9 +4802,9 @@ "integrity": "sha512-jrqoTI8lk5UziDsDPJ2Y+nmXYCcRhmr6uMARr3v/W6AMxRgsnRLWJyWKYr6FjaGMgbyxXG+OkCUPQY4Xl3toGg==" }, "node_modules/@openproject/octicons-angular": { - "version": "19.13.0", - "resolved": "https://registry.npmjs.org/@openproject/octicons-angular/-/octicons-angular-19.13.0.tgz", - "integrity": "sha512-rpqWRFDmtp7N1Baxf4q3hIOAKlzzx0xqMFd3sgpCblJjioOdtDGJlu6coFEEK4bZaQ5AMJdj7iUA0R3F5pQjpA==", + "version": "19.14.0", + "resolved": "https://registry.npmjs.org/@openproject/octicons-angular/-/octicons-angular-19.14.0.tgz", + "integrity": "sha512-26r+Fq5f8ZhWfwH3JwK18eOgK3juzNf9dIidVRRmjFXxTY6oreozclCQf1lqZMlxi3gVUTj9qB35hwINWtMPJQ==", "dependencies": { "tslib": "^2.3.0" }, @@ -4816,9 +4816,9 @@ } }, "node_modules/@openproject/primer-view-components": { - "version": "0.32.1", - "resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.32.1.tgz", - "integrity": "sha512-kaw88/hzmciaac4m4wHfcgGL7hTkus3ihz77hByuQXvKXmVvfuJ0uJS129JPc7dUXaWeUK2R6jshWHPG2z+xFw==", + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.33.1.tgz", + "integrity": "sha512-lOKqObPWYfuscBJnj0fFuyq8Lz/sQYBlXsvFAs3N1Nu0XSDH/Ak97bFcuIIX4lRWxnyGWSj/BREvIjCoyi2BCA==", "dependencies": { "@github/auto-check-element": "^5.2.0", "@github/auto-complete-element": "^3.6.2", @@ -4883,9 +4883,9 @@ }, "node_modules/@primer/view-components": { "name": "@openproject/primer-view-components", - "version": "0.32.1", - "resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.32.1.tgz", - "integrity": "sha512-kaw88/hzmciaac4m4wHfcgGL7hTkus3ihz77hByuQXvKXmVvfuJ0uJS129JPc7dUXaWeUK2R6jshWHPG2z+xFw==", + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.33.1.tgz", + "integrity": "sha512-lOKqObPWYfuscBJnj0fFuyq8Lz/sQYBlXsvFAs3N1Nu0XSDH/Ak97bFcuIIX4lRWxnyGWSj/BREvIjCoyi2BCA==", "dependencies": { "@github/auto-check-element": "^5.2.0", "@github/auto-complete-element": "^3.6.2", @@ -26240,17 +26240,17 @@ "integrity": "sha512-jrqoTI8lk5UziDsDPJ2Y+nmXYCcRhmr6uMARr3v/W6AMxRgsnRLWJyWKYr6FjaGMgbyxXG+OkCUPQY4Xl3toGg==" }, "@openproject/octicons-angular": { - "version": "19.13.0", - "resolved": "https://registry.npmjs.org/@openproject/octicons-angular/-/octicons-angular-19.13.0.tgz", - "integrity": "sha512-rpqWRFDmtp7N1Baxf4q3hIOAKlzzx0xqMFd3sgpCblJjioOdtDGJlu6coFEEK4bZaQ5AMJdj7iUA0R3F5pQjpA==", + "version": "19.14.0", + "resolved": "https://registry.npmjs.org/@openproject/octicons-angular/-/octicons-angular-19.14.0.tgz", + "integrity": "sha512-26r+Fq5f8ZhWfwH3JwK18eOgK3juzNf9dIidVRRmjFXxTY6oreozclCQf1lqZMlxi3gVUTj9qB35hwINWtMPJQ==", "requires": { "tslib": "^2.3.0" } }, "@openproject/primer-view-components": { - "version": "0.32.1", - "resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.32.1.tgz", - "integrity": "sha512-kaw88/hzmciaac4m4wHfcgGL7hTkus3ihz77hByuQXvKXmVvfuJ0uJS129JPc7dUXaWeUK2R6jshWHPG2z+xFw==", + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.33.1.tgz", + "integrity": "sha512-lOKqObPWYfuscBJnj0fFuyq8Lz/sQYBlXsvFAs3N1Nu0XSDH/Ak97bFcuIIX4lRWxnyGWSj/BREvIjCoyi2BCA==", "requires": { "@github/auto-check-element": "^5.2.0", "@github/auto-complete-element": "^3.6.2", @@ -26296,7 +26296,7 @@ "integrity": "sha512-vQoTeu7yfL/1Njg372lN6xqIsiPl0QgoIrkDjJ+TpDkeIznXFc+jLdu+5VUVi+bzyKHwv/gd42hhlLA2K5oD6w==", "requires": { "@primer/primitives": "^7.15.12", - "@primer/view-components": "npm:@openproject/primer-view-components@^0.32.1" + "@primer/view-components": "npm:@openproject/primer-view-components@^0.33.1" } }, "@primer/primitives": { @@ -26305,9 +26305,9 @@ "integrity": "sha512-ujAsbRB5Xw6rrxizbTgv1bxpraZ091stPMsO6pqGxzc+zIyhrojpGVBuCKJ+RYkpbKK7T4bZzgOT/KyWBAFwwg==" }, "@primer/view-components": { - "version": "npm:@openproject/primer-view-components@0.32.1", - "resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.32.1.tgz", - "integrity": "sha512-kaw88/hzmciaac4m4wHfcgGL7hTkus3ihz77hByuQXvKXmVvfuJ0uJS129JPc7dUXaWeUK2R6jshWHPG2z+xFw==", + "version": "npm:@openproject/primer-view-components@0.33.1", + "resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.33.1.tgz", + "integrity": "sha512-lOKqObPWYfuscBJnj0fFuyq8Lz/sQYBlXsvFAs3N1Nu0XSDH/Ak97bFcuIIX4lRWxnyGWSj/BREvIjCoyi2BCA==", "requires": { "@github/auto-check-element": "^5.2.0", "@github/auto-complete-element": "^3.6.2", diff --git a/frontend/package.json b/frontend/package.json index d71210885275..cca13211361e 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -97,8 +97,8 @@ "@ng-select/ng-select": "^12.0.7", "@ngneat/content-loader": "^7.0.0", "@ngx-formly/core": "^6.1.4", - "@openproject/octicons-angular": "^19.13.0", - "@openproject/primer-view-components": "^0.32.1", + "@openproject/octicons-angular": "^19.14.0", + "@openproject/primer-view-components": "^0.33.1", "@openproject/reactivestates": "^3.0.1", "@primer/css": "^21.2.2", "@types/hotwired__turbo": "^8.0.1", @@ -177,6 +177,6 @@ "generate-typings": "tsc -d -p src/tsconfig.app.json" }, "overrides": { - "@primer/view-components": "npm:@openproject/primer-view-components@^0.32.1" + "@primer/view-components": "npm:@openproject/primer-view-components@^0.33.1" } } From 6c4754188fda8148dd4b4dba252c6499d0c372b7 Mon Sep 17 00:00:00 2001 From: Markus Kahl Date: Wed, 5 Jun 2024 09:05:21 +0100 Subject: [PATCH 149/176] validate presence of type as it must not be null Co-authored-by: Dombi Attila <83396+dombesz@users.noreply.github.com> --- modules/github_integration/app/models/deploy_target.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/github_integration/app/models/deploy_target.rb b/modules/github_integration/app/models/deploy_target.rb index decbcf0b11e6..92563c45d8bc 100644 --- a/modules/github_integration/app/models/deploy_target.rb +++ b/modules/github_integration/app/models/deploy_target.rb @@ -34,7 +34,7 @@ class DeployTarget < ApplicationRecord has_many :deploy_status_checks, dependent: :destroy validates_presence_of :host - + validates_presence_of :type # this is very much specific to the only type of target we support for now, OpenProject validates_presence_of :api_key end From 22a8424f94ff8df4c5370b6fc9a116c601158d3b Mon Sep 17 00:00:00 2001 From: Markus Kahl Date: Wed, 5 Jun 2024 09:21:04 +0100 Subject: [PATCH 150/176] address review remarks --- .../app/models/deploy_target.rb | 3 +++ .../workers/cron/check_deploy_status_job.rb | 18 ++++++++++++++---- modules/github_integration/config/routes.rb | 2 +- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/modules/github_integration/app/models/deploy_target.rb b/modules/github_integration/app/models/deploy_target.rb index 92563c45d8bc..cb4d5942193e 100644 --- a/modules/github_integration/app/models/deploy_target.rb +++ b/modules/github_integration/app/models/deploy_target.rb @@ -34,7 +34,10 @@ class DeployTarget < ApplicationRecord has_many :deploy_status_checks, dependent: :destroy validates_presence_of :host + validates_uniqueness_of :host + validates_presence_of :type + # this is very much specific to the only type of target we support for now, OpenProject validates_presence_of :api_key end diff --git a/modules/github_integration/app/workers/cron/check_deploy_status_job.rb b/modules/github_integration/app/workers/cron/check_deploy_status_job.rb index b1ed86d3e32e..1372811aa5d0 100644 --- a/modules/github_integration/app/workers/cron/check_deploy_status_job.rb +++ b/modules/github_integration/app/workers/cron/check_deploy_status_job.rb @@ -90,13 +90,13 @@ def update_deploy_status(pull_request, deploy_target) end def delete_status_check(pull_request, deploy_target) - # we use `find` and delete it this way to also cover + # we use `select` and delete it this way to also cover # not-yet-persisted records - check = pull_request + checks = pull_request .deploy_status_checks - .find { |c| c.deploy_target == deploy_target } + .select { |c| c.deploy_target == deploy_target } - pull_request.deploy_status_checks.delete(check) + pull_request.deploy_status_checks.delete(checks) end ## @@ -143,6 +143,16 @@ def commit_contains?(base_commit_sha, merge_commit_sha) return false if data.nil? + status_identical?(data) || status_behind?(data) + end + + def status_identical?(data) + status = data["status"].presence + + status == "identical" + end + + def status_behind?(data) status = data["status"].presence ahead_by = data["ahead_by"].presence behind_by = data["behind_by"].presence diff --git a/modules/github_integration/config/routes.rb b/modules/github_integration/config/routes.rb index 7fe0aaba47a2..2f6f23ab8f4e 100644 --- a/modules/github_integration/config/routes.rb +++ b/modules/github_integration/config/routes.rb @@ -27,5 +27,5 @@ #++ Rails.application.routes.draw do - resources :deploy_targets, only: %i[index new edit update create destroy] + resources :deploy_targets, only: %i[index new create destroy] end From 3939c0b542f312c6053a6cb21bde3299ae4869d3 Mon Sep 17 00:00:00 2001 From: ulferts Date: Wed, 5 Jun 2024 10:36:54 +0200 Subject: [PATCH 151/176] bump patch version requirement --- lib/open_project/patches/mailer_controller_preview.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/open_project/patches/mailer_controller_preview.rb b/lib/open_project/patches/mailer_controller_preview.rb index aa68045c9683..081ae55ff406 100644 --- a/lib/open_project/patches/mailer_controller_preview.rb +++ b/lib/open_project/patches/mailer_controller_preview.rb @@ -41,6 +41,6 @@ def extend_content_security_policy end end -OpenProject::Patches.patch_gem_version "rails", "7.1.3.3" do +OpenProject::Patches.patch_gem_version "rails", "7.1.3.4" do Rails::MailersController.include OpenProject::Patches::MailerControllerCsp end From 9d9430f2e984aae84afdd860507d186ea28b39b9 Mon Sep 17 00:00:00 2001 From: Eric Schubert Date: Mon, 3 Jun 2024 13:29:16 +0200 Subject: [PATCH 152/176] [#52670] rework main menu resizer - https://community.openproject.org/work_packages/52670 - fixed typings in resizer component - changed CSS for resizer to be: - drag handle no has 1rem width - drag handle is now fixed position over right side of the menu itself - changed hover behavior of toggle to replacing the icon - changed hover color to accent --- .../components/grids/grid/grid.component.html | 8 +- .../components/resizer/resizer.component.ts | 106 +++++++++++++----- .../resizer/main-menu-resizer.component.ts | 50 +++++---- .../resizer/resizer/wp-resizer.component.ts | 8 +- .../src/global_styles/layout/_main_menu.sass | 96 +++++++++------- 5 files changed, 169 insertions(+), 99 deletions(-) diff --git a/frontend/src/app/shared/components/grids/grid/grid.component.html b/frontend/src/app/shared/components/grids/grid/grid.component.html index 059697732fa3..b6ae6f2af043 100644 --- a/frontend/src/app/shared/components/grids/grid/grid.component.html +++ b/frontend/src/app/shared/components/grids/grid/grid.component.html @@ -35,17 +35,17 @@ [ndcDynamicOutputs]="widgetComponentOutput(area)"> -
    -
    + diff --git a/frontend/src/app/shared/components/resizer/resizer.component.ts b/frontend/src/app/shared/components/resizer/resizer.component.ts index 7d6dbd3384e6..5383a9f50aff 100644 --- a/frontend/src/app/shared/components/resizer/resizer.component.ts +++ b/frontend/src/app/shared/components/resizer/resizer.component.ts @@ -1,10 +1,45 @@ +// -- copyright +// OpenProject is an open source project management software. +// Copyright (C) 2012-2024 the OpenProject GmbH +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License version 3. +// +// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +// Copyright (C) 2006-2013 Jean-Philippe Lang +// Copyright (C) 2010-2013 the ChiliProject Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// See COPYRIGHT and LICENSE files for more details. +//++ + import { - Component, EventEmitter, HostListener, Input, OnDestroy, Output, + ChangeDetectionStrategy, + Component, + EventEmitter, + HostListener, + Input, + OnDestroy, + Output, } from '@angular/core'; + import { setBodyCursor } from 'core-app/shared/helpers/dom/set-window-cursor.helper'; export interface ResizeDelta { - origin:any; + origin:UIEvent; // Absolute difference from start absolute:{ @@ -20,8 +55,9 @@ export interface ResizeDelta { } @Component({ - selector: 'resizer', + selector: 'op-resizer', templateUrl: './resizer.component.html', + changeDetection: ChangeDetectionStrategy.OnPush, }) export class ResizerComponent implements OnDestroy { private startX:number; @@ -40,13 +76,11 @@ export class ResizerComponent implements OnDestroy { private mouseUpHandler:EventListener; - private resizing = false; + @Output() resizeFinished:EventEmitter = new EventEmitter(); - @Output() end:EventEmitter = new EventEmitter(); + @Output() resizeStarted:EventEmitter = new EventEmitter(); - @Output() start:EventEmitter = new EventEmitter(); - - @Output() move:EventEmitter = new EventEmitter(); + @Output() move:EventEmitter = new EventEmitter(); @Input() customHandler = false; @@ -60,50 +94,64 @@ export class ResizerComponent implements OnDestroy { @HostListener('mousedown', ['$event']) @HostListener('touchstart', ['$event']) - public startResize(event:any) { + // public startResize(event:any) { + public startResize(event:MouseEvent|TouchEvent) { event.preventDefault(); event.stopPropagation(); - // Only on left mouse click the resizing is started - if (event.buttons === 1 || event.which === 1 || event.which === 0) { - // Getting starting position - this.oldX = this.startX = event.clientX || event.pageX || event.touches[0].clientX; - this.oldY = this.startY = event.clientY || event.pageY || event.touches[0].clientY; + if (this.isMouseEvent(event) && event.button !== 0) { + // Only handle primary mouse button clicks + return; + } - this.newX = event.clientX || event.pageX || event.touches[0].clientX; - this.newY = event.clientY || event.pageY || event.touches[0].clientY; + const { x, y } = this.position(event); + this.oldX = x; + this.startX = x; + this.newX = x; + this.oldY = y; + this.startY = y; + this.newY = y; + + this.setResizeCursor(); + this.bindEventListener(); + this.resizeStarted.emit(this.buildDelta(event)); + } - this.resizing = true; + private position(event:MouseEvent|TouchEvent):{ x:number, y:number } { + if (this.isMouseEvent(event)) { + return { x: event.clientX, y: event.clientY }; + } - this.setResizeCursor(); - this.bindEventListener(event); + return { x: event.touches[0].clientX, y: event.touches[0].clientY }; + } - this.start.emit(this.buildDelta(event)); - } + private isMouseEvent(event:MouseEvent|TouchEvent):event is MouseEvent { + return event instanceof MouseEvent; } - private onMouseUp(event:any) { + private onMouseUp(event:MouseEvent|TouchEvent) { this.setAutoCursor(); this.removeEventListener(); - this.end.emit(this.buildDelta(event)); + this.resizeFinished.emit(this.buildDelta(event)); } - private onMouseMove(event:any) { + private onMouseMove(event:MouseEvent|TouchEvent) { event.preventDefault(); event.stopPropagation(); this.oldX = this.newX; this.oldY = this.newY; - this.newX = event.clientX || event.pageX || event.touches[0].clientX; - this.newY = event.clientY || event.pageY || event.touches[0].clientX; + const { x, y } = this.position(event); + this.newX = x; + this.newY = y; this.move.emit(this.buildDelta(event)); } // Necessary to encapsulate this to be able to remove the event listener later - private bindEventListener(event:any) { + private bindEventListener() { this.mouseMoveHandler = this.onMouseMove.bind(this); this.mouseUpHandler = this.onMouseUp.bind(this); @@ -128,7 +176,7 @@ export class ResizerComponent implements OnDestroy { setBodyCursor('auto'); } - private buildDelta(event:any):ResizeDelta { + private buildDelta(event:MouseEvent|TouchEvent):ResizeDelta { return { origin: event, absolute: { @@ -137,7 +185,7 @@ export class ResizerComponent implements OnDestroy { }, relative: { x: this.newX - this.oldX, - y: this.newY - this.oldX, + y: this.newY - this.oldY, }, }; } diff --git a/frontend/src/app/shared/components/resizer/resizer/main-menu-resizer.component.ts b/frontend/src/app/shared/components/resizer/resizer/main-menu-resizer.component.ts index 0fd310b08de4..51a1ec5d7912 100644 --- a/frontend/src/app/shared/components/resizer/resizer/main-menu-resizer.component.ts +++ b/frontend/src/app/shared/components/resizer/resizer/main-menu-resizer.component.ts @@ -27,9 +27,14 @@ //++ import { - ChangeDetectorRef, Component, ElementRef, OnInit, + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + ElementRef, + OnInit, } from '@angular/core'; import { distinctUntilChanged } from 'rxjs/operators'; + import { ResizeDelta } from 'core-app/shared/components/resizer/resizer.component'; import { UntilDestroyedMixin } from 'core-app/shared/helpers/angular/until-destroyed.mixin'; import { MainMenuToggleService } from 'core-app/core/main-menu/main-menu-toggle.service'; @@ -38,23 +43,28 @@ export const mainMenuResizerSelector = 'main-menu-resizer'; @Component({ selector: mainMenuResizerSelector, + changeDetection: ChangeDetectionStrategy.OnPush, template: ` - -
    - -
    -
    + + + + + `, }) @@ -71,9 +81,11 @@ export class MainMenuResizerComponent extends UntilDestroyedMixin implements OnI public moving = false; - constructor(readonly toggleService:MainMenuToggleService, + constructor( + readonly toggleService:MainMenuToggleService, readonly cdRef:ChangeDetectorRef, - readonly elementRef:ElementRef) { + readonly elementRef:ElementRef, + ) { super(); } diff --git a/frontend/src/app/shared/components/resizer/resizer/wp-resizer.component.ts b/frontend/src/app/shared/components/resizer/resizer/wp-resizer.component.ts index 5b8a939ca20f..eca03af8bea5 100644 --- a/frontend/src/app/shared/components/resizer/resizer/wp-resizer.component.ts +++ b/frontend/src/app/shared/components/resizer/resizer/wp-resizer.component.ts @@ -40,13 +40,13 @@ import { MainMenuToggleService } from 'core-app/core/main-menu/main-menu-toggle. @Component({ selector: 'wp-resizer', template: ` - - + `, changeDetection: ChangeDetectionStrategy.OnPush, }) diff --git a/frontend/src/global_styles/layout/_main_menu.sass b/frontend/src/global_styles/layout/_main_menu.sass index 698ae8e68c39..e07790f563bd 100644 --- a/frontend/src/global_styles/layout/_main_menu.sass +++ b/frontend/src/global_styles/layout/_main_menu.sass @@ -26,6 +26,8 @@ // See COPYRIGHT and LICENSE files for more details. //++ +@import "app/spot/styles/sass/common/icon" + $menu-item-line-height: 30px $arrow-left-width: 40px @@ -64,7 +66,8 @@ $arrow-left-width: 40px height: 100% .main-menu--children - height: calc(100% - (var(--main-menu-item-height) + 10px)) // 10px spacing + height: calc(100% - (var(--main-menu-item-height) + 10px)) + // 10px spacing overflow: auto @include styled-scroll-bar @@ -97,9 +100,11 @@ $arrow-left-width: 40px // work around due to dom manipulation on document: ready: // this isn't scoped to .main-item-wrapper to avoid flickering padding-left: 12px + &.toggler // explicitly reset to zero to avoid selector precedence problems padding-left: 0 + .main-menu--children li a // children have no icon so we need to push them right. padding-left: 24px @@ -115,6 +120,7 @@ $arrow-left-width: 40px font-size: var(--main-menu-font-size) font-style: normal padding: 0 12px + &:hover text-decoration: none @@ -139,16 +145,17 @@ $arrow-left-width: 40px a border: 1px solid transparent + &.selected, &.selected + a @include main-menu-selected &:hover @include main-menu-hover - &:hover, &:focus , &:active + &:hover, &:focus, &:active @include main-menu-hover - &~ .toggler + & ~ .toggler @include main-menu-hover a:not(.toggler) @@ -163,8 +170,10 @@ $arrow-left-width: 40px display: none padding: 10px 0 width: 100% + &.unattached border-top: 1px solid #ddd + li &:hover // simultaneously hover all menu item anchor tags @@ -174,7 +183,8 @@ $arrow-left-width: 40px > a &.selected, &.selected @include main-menu-selected - &:hover, &:focus , &:active + + &:hover, &:focus, &:active @include main-menu-hover .main-menu--children-menu-header @@ -189,6 +199,7 @@ $arrow-left-width: 40px padding-left: 14px padding-right: 14px border: 1px solid transparent + &:hover, &:focus, &:active @include main-menu-hover @@ -203,6 +214,7 @@ a.main-menu--parent-node line-height: var(--main-menu-item-height) border-radius: 3px color: var(--main-menu-font-color) + &:hover, &:focus, &:active @include main-menu-hover @@ -212,6 +224,7 @@ a.main-menu--parent-node &.closed li display: none + > li.open display: list-item @@ -226,11 +239,14 @@ a.main-menu--parent-node .main-menu--children display: block + li display: list-item + &.open > li display: list-item + .main-menu--children-menu-header display: none @@ -238,6 +254,7 @@ a.main-menu--parent-node .main-menu width: var(--main-menu-folded-width) min-width: var(--main-menu-folded-width) + ul &.menu_root > li @@ -249,6 +266,7 @@ a.main-menu--parent-node text-overflow: clip -o-text-overflow: clip -ms-text-overflow: clip + .toggler display: none @@ -285,8 +303,10 @@ a.main-menu--parent-node ul border: none overflow-x: hidden + li border: none + li a padding: 0 @@ -299,13 +319,17 @@ a.main-menu--parent-node #main-menu ul ul.main-menu--children ul.pages-hierarchy .tree-menu--hierarchy-indicator color: var(--main-menu-font-color) + .tree-menu--item &.-selected background: var(--main-menu-bg-selected-background) + .tree-menu--title color: var(--main-menu-selected-font-color) + &:hover background: var(--main-menu-bg-hover-background) + .tree-menu--title color: var(--main-menu-hover-font-color) text-decoration: none @@ -313,50 +337,36 @@ a.main-menu--parent-node // Resizer & toggle styles .main-menu--resizer background: none - height: 100vh - width: 18px + height: 100% + width: 1rem position: fixed - top: 0 - border-left-width: 2px - border-left-style: solid - border-left-color: transparent - left: calc(var(--main-menu-width) - 2px) - vertical-align: middle + display: flex + align-items: center + left: calc(var(--main-menu-width) - 1rem) z-index: 1 cursor: col-resize - &:hover - border-left-color: var(--main-menu-resizer-color) - i:before - color: var(--main-menu-resizer-color) - &.show - left: var(--main-menu-folded-width) - -.resizer-toggle-container - margin-top: 50vh - margin-left: -12px - display: inline-block + .main-menu--navigation-toggler + position: relative cursor: pointer - &:before - @include icon-common - font-size: 11px - font-weight: 400 - &:not(.open):before - @include icon-mixin-arrow-right2 - position: absolute - right: 0 - &:hover - color: var(--main-menu-resizer-color) - .main-menu--navigation-toggler - background-color: var(--main-menu-bg-color) - &.open:before - @include icon-mixin-arrow-left2 - i - display: inline-block - width: 12px - &:before - vertical-align: middle - color: var(--light-gray) + color: var(--main-menu-font-color) + + > .spot-icon:before + @include spot-icon_resizer-vertical-lines + + &:hover + > .spot-icon:before + @include spot-icon_arrow-left2 + + &:not(.open) + left: 1rem + color: var(--accent-color) + + > .spot-icon:before + @include spot-icon_arrow-right2 + + &:hover .main-menu--navigation-toggler + color: var(--accent-color) // Badges for menu items such as "EXPERIMENTAL" or "BETA" $badge_offset: 4px From 2c6e971e7452ccaa2c273d279de868a10d4a072c Mon Sep 17 00:00:00 2001 From: Eric Schubert Date: Mon, 3 Jun 2024 13:42:57 +0200 Subject: [PATCH 153/176] [#52670] removed unused code in resizer component --- .../resizer/resizer/main-menu-resizer.component.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/frontend/src/app/shared/components/resizer/resizer/main-menu-resizer.component.ts b/frontend/src/app/shared/components/resizer/resizer/main-menu-resizer.component.ts index 51a1ec5d7912..870368f67312 100644 --- a/frontend/src/app/shared/components/resizer/resizer/main-menu-resizer.component.ts +++ b/frontend/src/app/shared/components/resizer/resizer/main-menu-resizer.component.ts @@ -51,7 +51,6 @@ export const mainMenuResizerSelector = 'main-menu-resizer'; (resizeFinished)="resizeEnd()" (resizeStarted)="resizeStart()" (move)="resizeMove($event)"> - - `, }) @@ -73,8 +68,6 @@ export class MainMenuResizerComponent extends UntilDestroyedMixin implements OnI private resizeEvent:string; - private localStorageKey:string; - private elementWidth:number; private mainMenu = jQuery('#main-menu')[0]; @@ -101,7 +94,6 @@ export class MainMenuResizerComponent extends UntilDestroyedMixin implements OnI }); this.resizeEvent = 'main-menu-resize'; - this.localStorageKey = 'openProject-mainMenuWidth'; } public resizeStart() { From a3b59e0adca1c2ed46c17a49cfd867a82c32759d Mon Sep 17 00:00:00 2001 From: Eric Schubert Date: Mon, 3 Jun 2024 14:55:36 +0200 Subject: [PATCH 154/176] [#52670] use octicons instead of spot-icons - hover effect enlarges main menu border - hover changes color of toggle icon to border color --- .../app/shared/components/icon/icon.module.ts | 10 +++++++ .../resizer/main-menu-resizer.component.ts | 4 ++- .../src/global_styles/layout/_main_menu.sass | 30 ++++++++++++------- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/frontend/src/app/shared/components/icon/icon.module.ts b/frontend/src/app/shared/components/icon/icon.module.ts index 5558307695e8..1a0ab158485d 100644 --- a/frontend/src/app/shared/components/icon/icon.module.ts +++ b/frontend/src/app/shared/components/icon/icon.module.ts @@ -2,6 +2,8 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { OpIconComponent } from './icon.component'; import { + ChevronLeftIconComponent, + ChevronRightIconComponent, HomeIconComponent, InfoIconComponent, OpCursorRectangleSelectIconComponent, @@ -11,6 +13,7 @@ import { OpFirstPersonViewIconComponent, OpGridMenuIconComponent, OpOrthographicPerspectiveIconComponent, + OpResizerVerticalLinesIconComponent, OpScissorsIconComponent, OpThreedReturnDefaultIconComponent, OpViewFitToIconComponent, @@ -29,6 +32,8 @@ import { imports: [ CommonModule, + ChevronLeftIconComponent, + ChevronRightIconComponent, HomeIconComponent, InfoIconComponent, OpCursorRectangleSelectIconComponent, @@ -38,6 +43,7 @@ import { OpFirstPersonViewIconComponent, OpGridMenuIconComponent, OpOrthographicPerspectiveIconComponent, + OpResizerVerticalLinesIconComponent, OpScissorsIconComponent, OpThreedReturnDefaultIconComponent, OpViewFitToIconComponent, @@ -58,6 +64,8 @@ import { exports: [ OpIconComponent, + ChevronLeftIconComponent, + ChevronRightIconComponent, HomeIconComponent, InfoIconComponent, OpCursorRectangleSelectIconComponent, @@ -67,6 +75,7 @@ import { OpFirstPersonViewIconComponent, OpGridMenuIconComponent, OpOrthographicPerspectiveIconComponent, + OpResizerVerticalLinesIconComponent, OpScissorsIconComponent, OpThreedReturnDefaultIconComponent, OpViewFitToIconComponent, @@ -79,6 +88,7 @@ import { StarFillIconComponent, StarIconComponent, XIconComponent, + ], }) export class IconModule {} diff --git a/frontend/src/app/shared/components/resizer/resizer/main-menu-resizer.component.ts b/frontend/src/app/shared/components/resizer/resizer/main-menu-resizer.component.ts index 870368f67312..9644515a73a8 100644 --- a/frontend/src/app/shared/components/resizer/resizer/main-menu-resizer.component.ts +++ b/frontend/src/app/shared/components/resizer/resizer/main-menu-resizer.component.ts @@ -57,7 +57,9 @@ export const mainMenuResizerSelector = 'main-menu-resizer'; [class.open]="toggleService.showNavigation" (click)="toggleService.toggleNavigation($event)" > - + + + `, diff --git a/frontend/src/global_styles/layout/_main_menu.sass b/frontend/src/global_styles/layout/_main_menu.sass index e07790f563bd..f3458fbd4c42 100644 --- a/frontend/src/global_styles/layout/_main_menu.sass +++ b/frontend/src/global_styles/layout/_main_menu.sass @@ -66,8 +66,8 @@ $arrow-left-width: 40px height: 100% .main-menu--children - height: calc(100% - (var(--main-menu-item-height) + 10px)) // 10px spacing + height: calc(100% - (var(--main-menu-item-height) + 10px)) overflow: auto @include styled-scroll-bar @@ -351,22 +351,32 @@ a.main-menu--parent-node cursor: pointer color: var(--main-menu-font-color) - > .spot-icon:before - @include spot-icon_resizer-vertical-lines + > .collapse-menu, + > .expand-menu + display: none - &:hover - > .spot-icon:before - @include spot-icon_arrow-left2 + &.open:hover + > .resize-handle + display: none + + > .collapse-menu + display: block &:not(.open) left: 1rem color: var(--accent-color) - > .spot-icon:before - @include spot-icon_arrow-right2 + > .resize-handle + display: none + + > .expand-menu + display: block + + &:hover + border-right: 0.125rem solid var(--main-menu-border-color) - &:hover .main-menu--navigation-toggler - color: var(--accent-color) + .main-menu--navigation-toggler + color: var(--main-menu-border-color) // Badges for menu items such as "EXPERIMENTAL" or "BETA" $badge_offset: 4px From 9c9653af6bc83db9510b20258ba61c436c1d968c Mon Sep 17 00:00:00 2001 From: Kabiru Mwenja Date: Wed, 5 Jun 2024 12:32:04 +0300 Subject: [PATCH 155/176] fix[Op#54749]: use `project.active_subprojects` so to cover all descendants --- .../bulk_create_service.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/project_custom_field_project_mappings/bulk_create_service.rb b/app/services/project_custom_field_project_mappings/bulk_create_service.rb index 410082f37aab..f9bb4b7f530d 100644 --- a/app/services/project_custom_field_project_mappings/bulk_create_service.rb +++ b/app/services/project_custom_field_project_mappings/bulk_create_service.rb @@ -87,7 +87,7 @@ def incoming_mapping_ids def projects [@project].tap do |projects_array| - projects_array.concat(@project.children.to_a) if @include_sub_projects + projects_array.concat(@project.active_subprojects.to_a) if @include_sub_projects end end From 4dae5df1478dfbaee966967c0047154cba27b761 Mon Sep 17 00:00:00 2001 From: Kabiru Mwenja Date: Wed, 5 Jun 2024 13:02:23 +0300 Subject: [PATCH 156/176] tests[Op#54749]: add unit test for project descendants --- .../bulk_create_service_spec.rb | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/spec/services/project_custom_field_project_mappings/bulk_create_service_spec.rb b/spec/services/project_custom_field_project_mappings/bulk_create_service_spec.rb index 968458780c19..464f6c3663ba 100644 --- a/spec/services/project_custom_field_project_mappings/bulk_create_service_spec.rb +++ b/spec/services/project_custom_field_project_mappings/bulk_create_service_spec.rb @@ -51,14 +51,17 @@ context "with subprojects" do let(:project) { create(:project) } let!(:subproject) { create(:project, parent: project) } - let(:instance) { described_class.new(user:, project:, project_custom_field:, include_sub_projects: true) } + let!(:subproject2) { create(:project, parent: subproject) } it "creates the mappings for the project and sub-projects" do - expect { instance.call }.to change(ProjectCustomFieldProjectMapping, :count).by(2) + create_service = described_class.new(user:, project: project.reload, project_custom_field:, + include_sub_projects: true) + + expect { create_service.call }.to change(ProjectCustomFieldProjectMapping, :count).by(3) aggregate_failures "creates the mapping for the correct project and custom field" do - expect(ProjectCustomFieldProjectMapping.last.project).to eq(subproject) - expect(ProjectCustomFieldProjectMapping.last.project_custom_field).to eq(project_custom_field) + expect(ProjectCustomFieldProjectMapping.where(project_custom_field:).pluck(:project_id)) + .to contain_exactly(project.id, subproject.id, subproject2.id) end end end From d69cfe8e72e8f73bd9bb6a142bb47571074930fd Mon Sep 17 00:00:00 2001 From: Kabiru Mwenja Date: Wed, 5 Jun 2024 13:44:07 +0300 Subject: [PATCH 157/176] chore[Op#54749]: relocate form for consistency --- .../new_project_mapping_component.html.erb | 41 +---------- .../custom_field_mapping_form.rb | 68 +++++++++++++++++++ 2 files changed, 69 insertions(+), 40 deletions(-) create mode 100644 app/forms/projects/custom_fields/custom_field_mapping_form.rb diff --git a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb index dd5105151385..817a44612ec6 100644 --- a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb +++ b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.html.erb @@ -1,44 +1,5 @@ <%= component_wrapper do - new_project_mapping_form = Class.new(ApplicationForm) do - form do |f| - f.group(layout: :horizontal) do |f_group| - f_group.project_autocompleter( - name: :id, - label: Project.model_name.human, - visually_hide_label: true, - autocomplete_options: { - openDirectly: false, - focusDirectly: false, - dropdownPosition: 'bottom', - disabledProjects: projects_with_custom_field_mapping, - inputName: 'project_custom_field_project_mapping[project_id]' - } - ) - - f_group.check_box( - name: :include_sub_projects, - label: I18n.t("projects.settings.project_custom_fields.new_project_mapping_form.include_sub_projects"), - checked: false - ) - end - end - - def initialize(project_custom_field:) - super() - @project_custom_field = project_custom_field - end - - private - - def projects_with_custom_field_mapping - ProjectCustomFieldProjectMapping - .where(project_custom_field: @project_custom_field) - .pluck(:project_id) - .to_h { |id| [id, id] } - end - end - render( Primer::Alpha::Dialog.new( id: dialog_id, @@ -68,7 +29,7 @@ id: dialog_body_id, test_selector: dialog_body_id, aria: { label: title }, style: "min-height: 300px" )) do - render(new_project_mapping_form.new(form, project_custom_field: @project_custom_field)) + render(Projects::CustomFields::CustomFieldMappingForm.new(form, project_custom_field: @project_custom_field)) end) concat(render(Primer::Alpha::Dialog::Footer.new(show_divider: false)) do diff --git a/app/forms/projects/custom_fields/custom_field_mapping_form.rb b/app/forms/projects/custom_fields/custom_field_mapping_form.rb new file mode 100644 index 000000000000..65084926c108 --- /dev/null +++ b/app/forms/projects/custom_fields/custom_field_mapping_form.rb @@ -0,0 +1,68 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2012-2024 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +module Projects::CustomFields + class CustomFieldMappingForm < ApplicationForm + form do |f| + f.group(layout: :horizontal) do |f_group| + f_group.project_autocompleter( + name: :id, + label: Project.model_name.human, + visually_hide_label: true, + autocomplete_options: { + openDirectly: false, + focusDirectly: false, + dropdownPosition: "bottom", + disabledProjects: projects_with_custom_field_mapping, + inputName: "project_custom_field_project_mapping[project_id]" + } + ) + + f_group.check_box( + name: :include_sub_projects, + label: I18n.t("projects.settings.project_custom_fields.new_project_mapping_form.include_sub_projects"), + checked: false + ) + end + end + + def initialize(project_custom_field:) + super() + @project_custom_field = project_custom_field + end + + private + + def projects_with_custom_field_mapping + ProjectCustomFieldProjectMapping + .where(project_custom_field: @project_custom_field) + .pluck(:project_id) + .to_h { |id| [id, id] } + end + end +end From b842917d61b1a2aaf7818fff3b2d2ba8d480001a Mon Sep 17 00:00:00 2001 From: Kabiru Mwenja Date: Wed, 5 Jun 2024 14:45:51 +0300 Subject: [PATCH 158/176] fix[Op#54749]: do not wrap checkbox label --- app/forms/projects/custom_fields/custom_field_mapping_form.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/forms/projects/custom_fields/custom_field_mapping_form.rb b/app/forms/projects/custom_fields/custom_field_mapping_form.rb index 65084926c108..2d0501ee2c4d 100644 --- a/app/forms/projects/custom_fields/custom_field_mapping_form.rb +++ b/app/forms/projects/custom_fields/custom_field_mapping_form.rb @@ -46,7 +46,8 @@ class CustomFieldMappingForm < ApplicationForm f_group.check_box( name: :include_sub_projects, label: I18n.t("projects.settings.project_custom_fields.new_project_mapping_form.include_sub_projects"), - checked: false + checked: false, + label_arguments: { class: "no-wrap" } ) end end From d9c50851fb19af05f1fcefcb82ad4378d01d8b66 Mon Sep 17 00:00:00 2001 From: dominic-braeunlein Date: Wed, 5 Jun 2024 13:52:28 +0200 Subject: [PATCH 159/176] Revert "Code maintenance/55267 replace webfonts generator package and add missing icons" --- frontend/package.json | 2 +- frontend/src/app/spot/icon-font/generate.js | 2 +- .../spot/icon-font/src/arrow-thin-left.svg | 3 - .../app/spot/icon-font/src/baseline-add.svg | 4 - .../spot/icon-font/src/baseline-delete.svg | 4 - .../src/app/spot/icon-font/src/blocked.svg | 3 - .../spot/icon-font/src/bookmark-filled.svg | 3 - .../src/app/spot/icon-font/src/bookmark.svg | 3 - .../src/app/spot/icon-font/src/comments.svg | 3 - .../spot/icon-font/src/configure-knobs.svg | 4 - .../app/spot/icon-font/src/copy-documents.svg | 4 - .../spot/icon-font/src/enterprise-badge.svg | 4 - .../app/spot/icon-font/src/export-pdf-1.svg | 7 - .../icon-font/src/file-storage-connection.svg | 6 - .../app/spot/icon-font/src/github_logo.svg | 3 - .../app/spot/icon-font/src/gitlab_logo.svg | 7 - frontend/src/app/spot/icon-font/src/hide.svg | 4 - .../spot/icon-font/src/iconfont-scaler.svg | 3 - .../src/app/spot/icon-font/src/like-hand.svg | 3 - .../spot/icon-font/src/mention-comment.svg | 4 - .../app/spot/icon-font/src/not-watching.svg | 3 - .../src/app/spot/icon-font/src/remove-1.svg | 3 - .../spot/icon-font/src/return-to-previous.svg | 3 - .../spot/icon-font/src/settings-display.svg | 3 - .../src/app/spot/icon-font/src/snooze.svg | 3 - .../src/app/spot/icon-font/src/star-empty.svg | 3 - .../app/spot/icon-font/src/star-filled.svg | 3 - frontend/src/app/spot/icon-font/src/stop.svg | 3 - .../src/app/spot/icon-font/src/sum-error.svg | 4 - .../src/app/spot/icon-font/src/sum-sign.svg | 3 - .../app/spot/icon-font/src/today-arrows.svg | 5 - .../src/two-factor-authentification.svg | 5 - .../spot/icon-font/src/up-down-stepper.svg | 3 - .../app/spot/icon-font/src/user-missing.svg | 4 - .../src/app/spot/styles/sass/common/icon.sass | 1312 ++++---- .../openproject-icon-font.html | 2808 +++++++---------- .../openproject-icon-font.svg | 2291 ++++---------- .../openproject-icon-font.ttf | Bin 90040 -> 55440 bytes .../openproject-icon-font.woff | Bin 47080 -> 32532 bytes .../openproject-icon-font.woff2 | Bin 39208 -> 26424 bytes .../openproject-spot-icon-font.svg | 2303 ++++---------- .../openproject-spot-icon-font.ttf | Bin 110156 -> 64600 bytes .../openproject-spot-icon-font.woff | Bin 45060 -> 38108 bytes .../openproject-spot-icon-font.woff2 | Bin 37488 -> 31508 bytes .../fonts/_openproject_icon_definitions.sass | 1421 ++++----- 45 files changed, 3711 insertions(+), 6548 deletions(-) delete mode 100644 frontend/src/app/spot/icon-font/src/arrow-thin-left.svg delete mode 100644 frontend/src/app/spot/icon-font/src/baseline-add.svg delete mode 100644 frontend/src/app/spot/icon-font/src/baseline-delete.svg delete mode 100644 frontend/src/app/spot/icon-font/src/blocked.svg delete mode 100644 frontend/src/app/spot/icon-font/src/bookmark-filled.svg delete mode 100644 frontend/src/app/spot/icon-font/src/bookmark.svg delete mode 100644 frontend/src/app/spot/icon-font/src/comments.svg delete mode 100644 frontend/src/app/spot/icon-font/src/configure-knobs.svg delete mode 100644 frontend/src/app/spot/icon-font/src/copy-documents.svg delete mode 100644 frontend/src/app/spot/icon-font/src/enterprise-badge.svg delete mode 100644 frontend/src/app/spot/icon-font/src/export-pdf-1.svg delete mode 100644 frontend/src/app/spot/icon-font/src/file-storage-connection.svg delete mode 100644 frontend/src/app/spot/icon-font/src/github_logo.svg delete mode 100644 frontend/src/app/spot/icon-font/src/gitlab_logo.svg delete mode 100644 frontend/src/app/spot/icon-font/src/hide.svg delete mode 100644 frontend/src/app/spot/icon-font/src/iconfont-scaler.svg delete mode 100644 frontend/src/app/spot/icon-font/src/like-hand.svg delete mode 100644 frontend/src/app/spot/icon-font/src/mention-comment.svg delete mode 100644 frontend/src/app/spot/icon-font/src/not-watching.svg delete mode 100644 frontend/src/app/spot/icon-font/src/remove-1.svg delete mode 100644 frontend/src/app/spot/icon-font/src/return-to-previous.svg delete mode 100644 frontend/src/app/spot/icon-font/src/settings-display.svg delete mode 100644 frontend/src/app/spot/icon-font/src/snooze.svg delete mode 100644 frontend/src/app/spot/icon-font/src/star-empty.svg delete mode 100644 frontend/src/app/spot/icon-font/src/star-filled.svg delete mode 100644 frontend/src/app/spot/icon-font/src/stop.svg delete mode 100644 frontend/src/app/spot/icon-font/src/sum-error.svg delete mode 100644 frontend/src/app/spot/icon-font/src/sum-sign.svg delete mode 100644 frontend/src/app/spot/icon-font/src/today-arrows.svg delete mode 100644 frontend/src/app/spot/icon-font/src/two-factor-authentification.svg delete mode 100644 frontend/src/app/spot/icon-font/src/up-down-stepper.svg delete mode 100644 frontend/src/app/spot/icon-font/src/user-missing.svg diff --git a/frontend/package.json b/frontend/package.json index cca13211361e..eaad830ac79d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -105,7 +105,7 @@ "@uirouter/angular": "^13.0.0", "@uirouter/core": "^6.1.0", "@uirouter/rx": "^1.0.0", - "webfonts-generator-casaper": "^0.5.2", + "@vusion/webfonts-generator": "^0.8.0", "@w11k/ngx-componentdestroyed": "^5.0.2", "@xeokit/xeokit-bim-viewer": "2.5.1-beta-28", "autoprefixer": "^10.4.19", diff --git a/frontend/src/app/spot/icon-font/generate.js b/frontend/src/app/spot/icon-font/generate.js index 1be342317092..4096638042bd 100644 --- a/frontend/src/app/spot/icon-font/generate.js +++ b/frontend/src/app/spot/icon-font/generate.js @@ -1,6 +1,6 @@ #!/usr/bin/env node -const webfontsGenerator = require('webfonts-generator-casaper'); +const webfontsGenerator = require('@vusion/webfonts-generator'); const path = require('path'); const glob = require("glob") diff --git a/frontend/src/app/spot/icon-font/src/arrow-thin-left.svg b/frontend/src/app/spot/icon-font/src/arrow-thin-left.svg deleted file mode 100644 index a54ec09c91d1..000000000000 --- a/frontend/src/app/spot/icon-font/src/arrow-thin-left.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/frontend/src/app/spot/icon-font/src/baseline-add.svg b/frontend/src/app/spot/icon-font/src/baseline-add.svg deleted file mode 100644 index 87bf2c6f34ed..000000000000 --- a/frontend/src/app/spot/icon-font/src/baseline-add.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/frontend/src/app/spot/icon-font/src/baseline-delete.svg b/frontend/src/app/spot/icon-font/src/baseline-delete.svg deleted file mode 100644 index 1044dea6ab27..000000000000 --- a/frontend/src/app/spot/icon-font/src/baseline-delete.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/frontend/src/app/spot/icon-font/src/blocked.svg b/frontend/src/app/spot/icon-font/src/blocked.svg deleted file mode 100644 index 2cf2759243ef..000000000000 --- a/frontend/src/app/spot/icon-font/src/blocked.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/frontend/src/app/spot/icon-font/src/bookmark-filled.svg b/frontend/src/app/spot/icon-font/src/bookmark-filled.svg deleted file mode 100644 index 676e0b096dab..000000000000 --- a/frontend/src/app/spot/icon-font/src/bookmark-filled.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/frontend/src/app/spot/icon-font/src/bookmark.svg b/frontend/src/app/spot/icon-font/src/bookmark.svg deleted file mode 100644 index f604a8487e5b..000000000000 --- a/frontend/src/app/spot/icon-font/src/bookmark.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/frontend/src/app/spot/icon-font/src/comments.svg b/frontend/src/app/spot/icon-font/src/comments.svg deleted file mode 100644 index 2e79c91e4606..000000000000 --- a/frontend/src/app/spot/icon-font/src/comments.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/frontend/src/app/spot/icon-font/src/configure-knobs.svg b/frontend/src/app/spot/icon-font/src/configure-knobs.svg deleted file mode 100644 index 79345d86065c..000000000000 --- a/frontend/src/app/spot/icon-font/src/configure-knobs.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/frontend/src/app/spot/icon-font/src/copy-documents.svg b/frontend/src/app/spot/icon-font/src/copy-documents.svg deleted file mode 100644 index daeb72e53212..000000000000 --- a/frontend/src/app/spot/icon-font/src/copy-documents.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/frontend/src/app/spot/icon-font/src/enterprise-badge.svg b/frontend/src/app/spot/icon-font/src/enterprise-badge.svg deleted file mode 100644 index fcf714ed09fb..000000000000 --- a/frontend/src/app/spot/icon-font/src/enterprise-badge.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/frontend/src/app/spot/icon-font/src/export-pdf-1.svg b/frontend/src/app/spot/icon-font/src/export-pdf-1.svg deleted file mode 100644 index ef70df401092..000000000000 --- a/frontend/src/app/spot/icon-font/src/export-pdf-1.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/frontend/src/app/spot/icon-font/src/file-storage-connection.svg b/frontend/src/app/spot/icon-font/src/file-storage-connection.svg deleted file mode 100644 index c59cce4baf8b..000000000000 --- a/frontend/src/app/spot/icon-font/src/file-storage-connection.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/frontend/src/app/spot/icon-font/src/github_logo.svg b/frontend/src/app/spot/icon-font/src/github_logo.svg deleted file mode 100644 index ecdf31e23185..000000000000 --- a/frontend/src/app/spot/icon-font/src/github_logo.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/frontend/src/app/spot/icon-font/src/gitlab_logo.svg b/frontend/src/app/spot/icon-font/src/gitlab_logo.svg deleted file mode 100644 index 47ac9da36af5..000000000000 --- a/frontend/src/app/spot/icon-font/src/gitlab_logo.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/frontend/src/app/spot/icon-font/src/hide.svg b/frontend/src/app/spot/icon-font/src/hide.svg deleted file mode 100644 index c8e1911af160..000000000000 --- a/frontend/src/app/spot/icon-font/src/hide.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/frontend/src/app/spot/icon-font/src/iconfont-scaler.svg b/frontend/src/app/spot/icon-font/src/iconfont-scaler.svg deleted file mode 100644 index beb049be4d18..000000000000 --- a/frontend/src/app/spot/icon-font/src/iconfont-scaler.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/frontend/src/app/spot/icon-font/src/like-hand.svg b/frontend/src/app/spot/icon-font/src/like-hand.svg deleted file mode 100644 index d487a1907c92..000000000000 --- a/frontend/src/app/spot/icon-font/src/like-hand.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/frontend/src/app/spot/icon-font/src/mention-comment.svg b/frontend/src/app/spot/icon-font/src/mention-comment.svg deleted file mode 100644 index 5de0c6e0729c..000000000000 --- a/frontend/src/app/spot/icon-font/src/mention-comment.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/frontend/src/app/spot/icon-font/src/not-watching.svg b/frontend/src/app/spot/icon-font/src/not-watching.svg deleted file mode 100644 index 22382d95890b..000000000000 --- a/frontend/src/app/spot/icon-font/src/not-watching.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/frontend/src/app/spot/icon-font/src/remove-1.svg b/frontend/src/app/spot/icon-font/src/remove-1.svg deleted file mode 100644 index 646e900b30ea..000000000000 --- a/frontend/src/app/spot/icon-font/src/remove-1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/frontend/src/app/spot/icon-font/src/return-to-previous.svg b/frontend/src/app/spot/icon-font/src/return-to-previous.svg deleted file mode 100644 index 2ba6833cc606..000000000000 --- a/frontend/src/app/spot/icon-font/src/return-to-previous.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/frontend/src/app/spot/icon-font/src/settings-display.svg b/frontend/src/app/spot/icon-font/src/settings-display.svg deleted file mode 100644 index ecdbb6350228..000000000000 --- a/frontend/src/app/spot/icon-font/src/settings-display.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/frontend/src/app/spot/icon-font/src/snooze.svg b/frontend/src/app/spot/icon-font/src/snooze.svg deleted file mode 100644 index 9ea5a430f70e..000000000000 --- a/frontend/src/app/spot/icon-font/src/snooze.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/frontend/src/app/spot/icon-font/src/star-empty.svg b/frontend/src/app/spot/icon-font/src/star-empty.svg deleted file mode 100644 index ef3e8fd6bd34..000000000000 --- a/frontend/src/app/spot/icon-font/src/star-empty.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/frontend/src/app/spot/icon-font/src/star-filled.svg b/frontend/src/app/spot/icon-font/src/star-filled.svg deleted file mode 100644 index b1e6dd3afc91..000000000000 --- a/frontend/src/app/spot/icon-font/src/star-filled.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/frontend/src/app/spot/icon-font/src/stop.svg b/frontend/src/app/spot/icon-font/src/stop.svg deleted file mode 100644 index d03a815be5f0..000000000000 --- a/frontend/src/app/spot/icon-font/src/stop.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/frontend/src/app/spot/icon-font/src/sum-error.svg b/frontend/src/app/spot/icon-font/src/sum-error.svg deleted file mode 100644 index a3ae94aecb4e..000000000000 --- a/frontend/src/app/spot/icon-font/src/sum-error.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/frontend/src/app/spot/icon-font/src/sum-sign.svg b/frontend/src/app/spot/icon-font/src/sum-sign.svg deleted file mode 100644 index 581b94bc9da4..000000000000 --- a/frontend/src/app/spot/icon-font/src/sum-sign.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/frontend/src/app/spot/icon-font/src/today-arrows.svg b/frontend/src/app/spot/icon-font/src/today-arrows.svg deleted file mode 100644 index 3fd50088bd00..000000000000 --- a/frontend/src/app/spot/icon-font/src/today-arrows.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/frontend/src/app/spot/icon-font/src/two-factor-authentification.svg b/frontend/src/app/spot/icon-font/src/two-factor-authentification.svg deleted file mode 100644 index ea4ec94e09ba..000000000000 --- a/frontend/src/app/spot/icon-font/src/two-factor-authentification.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/frontend/src/app/spot/icon-font/src/up-down-stepper.svg b/frontend/src/app/spot/icon-font/src/up-down-stepper.svg deleted file mode 100644 index 8403457f99fc..000000000000 --- a/frontend/src/app/spot/icon-font/src/up-down-stepper.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/frontend/src/app/spot/icon-font/src/user-missing.svg b/frontend/src/app/spot/icon-font/src/user-missing.svg deleted file mode 100644 index 8f595d6e4f64..000000000000 --- a/frontend/src/app/spot/icon-font/src/user-missing.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/frontend/src/app/spot/styles/sass/common/icon.sass b/frontend/src/app/spot/styles/sass/common/icon.sass index c8e3bc5af048..7a6f9bbd1b6f 100644 --- a/frontend/src/app/spot/styles/sass/common/icon.sass +++ b/frontend/src/app/spot/styles/sass/common/icon.sass @@ -28,1151 +28,1151 @@ -moz-osx-font-smoothing: grayscale -@mixin spot-icon-zoom-out +@mixin spot-icon-accessibility content: "\f101" -.spot-icon_zoom-out:before +.spot-icon_accessibility:before content: "\f101" -@mixin spot-icon-zoom-in +@mixin spot-icon-accountable content: "\f102" -.spot-icon_zoom-in:before +.spot-icon_accountable:before content: "\f102" -@mixin spot-icon-zoom-auto +@mixin spot-icon-activity-history content: "\f103" -.spot-icon_zoom-auto:before +.spot-icon_activity-history:before content: "\f103" -@mixin spot-icon-zen-mode +@mixin spot-icon-add-attachment content: "\f104" -.spot-icon_zen-mode:before +.spot-icon_add-attachment:before content: "\f104" -@mixin spot-icon-yes +@mixin spot-icon-add-link content: "\f105" -.spot-icon_yes:before +.spot-icon_add-link:before content: "\f105" -@mixin spot-icon-workflow +@mixin spot-icon-add content: "\f106" -.spot-icon_workflow:before +.spot-icon_add:before content: "\f106" -@mixin spot-icon-work-packages +@mixin spot-icon-align-center content: "\f107" -.spot-icon_work-packages:before +.spot-icon_align-center:before content: "\f107" -@mixin spot-icon-wiki2 +@mixin spot-icon-align-justify content: "\f108" -.spot-icon_wiki2:before +.spot-icon_align-justify:before content: "\f108" -@mixin spot-icon-wiki +@mixin spot-icon-align-left content: "\f109" -.spot-icon_wiki:before +.spot-icon_align-left:before content: "\f109" -@mixin spot-icon-wiki-edit +@mixin spot-icon-align-right content: "\f10a" -.spot-icon_wiki-edit:before +.spot-icon_align-right:before content: "\f10a" -@mixin spot-icon-watching +@mixin spot-icon-arrow-down1 content: "\f10b" -.spot-icon_watching:before +.spot-icon_arrow-down1:before content: "\f10b" -@mixin spot-icon-watched +@mixin spot-icon-arrow-down2 content: "\f10c" -.spot-icon_watched:before +.spot-icon_arrow-down2:before content: "\f10c" -@mixin spot-icon-warning +@mixin spot-icon-arrow-in content: "\f10d" -.spot-icon_warning:before +.spot-icon_arrow-in:before content: "\f10d" -@mixin spot-icon-view-timeline +@mixin spot-icon-arrow-left-right content: "\f10e" -.spot-icon_view-timeline:before +.spot-icon_arrow-left-right:before content: "\f10e" -@mixin spot-icon-view-split2 +@mixin spot-icon-arrow-left1 content: "\f10f" -.spot-icon_view-split2:before +.spot-icon_arrow-left1:before content: "\f10f" -@mixin spot-icon-view-split +@mixin spot-icon-arrow-left2 content: "\f110" -.spot-icon_view-split:before +.spot-icon_arrow-left2:before content: "\f110" -@mixin spot-icon-view-split-viewer-table +@mixin spot-icon-arrow-left3 content: "\f111" -.spot-icon_view-split-viewer-table:before +.spot-icon_arrow-left3:before content: "\f111" -@mixin spot-icon-view-model +@mixin spot-icon-arrow-left4 content: "\f112" -.spot-icon_view-model:before +.spot-icon_arrow-left4:before content: "\f112" -@mixin spot-icon-view-list +@mixin spot-icon-arrow-out content: "\f113" -.spot-icon_view-list:before +.spot-icon_arrow-out:before content: "\f113" -@mixin spot-icon-view-fullscreen +@mixin spot-icon-arrow-right2 content: "\f114" -.spot-icon_view-fullscreen:before +.spot-icon_arrow-right2:before content: "\f114" -@mixin spot-icon-view-card +@mixin spot-icon-arrow-right3 content: "\f115" -.spot-icon_view-card:before +.spot-icon_arrow-right3:before content: "\f115" -@mixin spot-icon-user +@mixin spot-icon-arrow-right4 content: "\f116" -.spot-icon_user:before +.spot-icon_arrow-right4:before content: "\f116" -@mixin spot-icon-user-plus +@mixin spot-icon-arrow-right5 content: "\f117" -.spot-icon_user-plus:before +.spot-icon_arrow-right5:before content: "\f117" -@mixin spot-icon-user-missing +@mixin spot-icon-arrow-right6 content: "\f118" -.spot-icon_user-missing:before +.spot-icon_arrow-right6:before content: "\f118" -@mixin spot-icon-user-minus +@mixin spot-icon-arrow-right7 content: "\f119" -.spot-icon_user-minus:before +.spot-icon_arrow-right7:before content: "\f119" -@mixin spot-icon-upload +@mixin spot-icon-arrow-thin-left content: "\f11a" -.spot-icon_upload:before +.spot-icon_arrow-thin-left:before content: "\f11a" -@mixin spot-icon-upload-arrow +@mixin spot-icon-arrow-thin content: "\f11b" -.spot-icon_upload-arrow:before +.spot-icon_arrow-thin:before content: "\f11b" -@mixin spot-icon-up-down-stepper +@mixin spot-icon-arrow-up1 content: "\f11c" -.spot-icon_up-down-stepper:before +.spot-icon_arrow-up1:before content: "\f11c" -@mixin spot-icon-unwatched +@mixin spot-icon-arrow-up2 content: "\f11d" -.spot-icon_unwatched:before +.spot-icon_arrow-up2:before content: "\f11d" -@mixin spot-icon-unordered-list +@mixin spot-icon-assigned-to-me content: "\f11e" -.spot-icon_unordered-list:before +.spot-icon_assigned-to-me:before content: "\f11e" -@mixin spot-icon-unlocked +@mixin spot-icon-assigned content: "\f11f" -.spot-icon_unlocked:before +.spot-icon_assigned:before content: "\f11f" -@mixin spot-icon-unit +@mixin spot-icon-attachment content: "\f120" -.spot-icon_unit:before +.spot-icon_attachment:before content: "\f120" -@mixin spot-icon-undo +@mixin spot-icon-attention content: "\f121" -.spot-icon_undo:before +.spot-icon_attention:before content: "\f121" -@mixin spot-icon-underline +@mixin spot-icon-back-up content: "\f122" -.spot-icon_underline:before +.spot-icon_back-up:before content: "\f122" -@mixin spot-icon-types +@mixin spot-icon-backlogs content: "\f123" -.spot-icon_types:before +.spot-icon_backlogs:before content: "\f123" -@mixin spot-icon-two-factor-authentification +@mixin spot-icon-baseline-add content: "\f124" -.spot-icon_two-factor-authentification:before +.spot-icon_baseline-add:before content: "\f124" -@mixin spot-icon-two-factor-authentication +@mixin spot-icon-baseline-delete content: "\f125" -.spot-icon_two-factor-authentication:before +.spot-icon_baseline-delete:before content: "\f125" -@mixin spot-icon-training-consulting +@mixin spot-icon-baseline content: "\f126" -.spot-icon_training-consulting:before +.spot-icon_baseline:before content: "\f126" -@mixin spot-icon-today-arrows +@mixin spot-icon-bcf content: "\f127" -.spot-icon_today-arrows:before +.spot-icon_bcf:before content: "\f127" -@mixin spot-icon-to-fullscreen +@mixin spot-icon-bell content: "\f128" -.spot-icon_to-fullscreen:before +.spot-icon_bell:before content: "\f128" -@mixin spot-icon-time +@mixin spot-icon-billing-information content: "\f129" -.spot-icon_time:before +.spot-icon_billing-information:before content: "\f129" -@mixin spot-icon-time-tracking-stop +@mixin spot-icon-blocked content: "\f12a" -.spot-icon_time-tracking-stop:before +.spot-icon_blocked:before content: "\f12a" -@mixin spot-icon-time-tracking-start +@mixin spot-icon-boards content: "\f12b" -.spot-icon_time-tracking-start:before +.spot-icon_boards:before content: "\f12b" -@mixin spot-icon-time-tracking-running +@mixin spot-icon-bold content: "\f12c" -.spot-icon_time-tracking-running:before +.spot-icon_bold:before content: "\f12c" -@mixin spot-icon-ticket +@mixin spot-icon-bookmark-filled content: "\f12d" -.spot-icon_ticket:before +.spot-icon_bookmark-filled:before content: "\f12d" -@mixin spot-icon-ticket-note +@mixin spot-icon-bookmark content: "\f12e" -.spot-icon_ticket-note:before +.spot-icon_bookmark:before content: "\f12e" -@mixin spot-icon-ticket-minus +@mixin spot-icon-budget content: "\f12f" -.spot-icon_ticket-minus:before +.spot-icon_budget:before content: "\f12f" -@mixin spot-icon-ticket-edit +@mixin spot-icon-bug content: "\f130" -.spot-icon_ticket-edit:before +.spot-icon_bug:before content: "\f130" -@mixin spot-icon-ticket-down +@mixin spot-icon-calendar content: "\f131" -.spot-icon_ticket-down:before +.spot-icon_calendar:before content: "\f131" -@mixin spot-icon-ticket-checked +@mixin spot-icon-calendar2 content: "\f132" -.spot-icon_ticket-checked:before +.spot-icon_calendar2:before content: "\f132" -@mixin spot-icon-text +@mixin spot-icon-camera content: "\f133" -.spot-icon_text:before +.spot-icon_camera:before content: "\f133" -@mixin spot-icon-team-planner +@mixin spot-icon-cancel-circle content: "\f134" -.spot-icon_team-planner:before +.spot-icon_cancel-circle:before content: "\f134" -@mixin spot-icon-sum-sign +@mixin spot-icon-cancel content: "\f135" -.spot-icon_sum-sign:before +.spot-icon_cancel:before content: "\f135" -@mixin spot-icon-sum-error +@mixin spot-icon-cart content: "\f136" -.spot-icon_sum-error:before +.spot-icon_cart:before content: "\f136" -@mixin spot-icon-strike-through +@mixin spot-icon-changeset-down content: "\f137" -.spot-icon_strike-through:before +.spot-icon_changeset-down:before content: "\f137" -@mixin spot-icon-stop +@mixin spot-icon-changeset-up content: "\f138" -.spot-icon_stop:before +.spot-icon_changeset-up:before content: "\f138" -@mixin spot-icon-status +@mixin spot-icon-changeset content: "\f139" -.spot-icon_status:before +.spot-icon_changeset:before content: "\f139" -@mixin spot-icon-status-reporting +@mixin spot-icon-chart1 content: "\f13a" -.spot-icon_status-reporting:before +.spot-icon_chart1:before content: "\f13a" -@mixin spot-icon-star +@mixin spot-icon-chart2 content: "\f13b" -.spot-icon_star:before +.spot-icon_chart2:before content: "\f13b" -@mixin spot-icon-star-filled +@mixin spot-icon-chart3 content: "\f13c" -.spot-icon_star-filled:before +.spot-icon_chart3:before content: "\f13c" -@mixin spot-icon-star-empty +@mixin spot-icon-checkmark-circle content: "\f13d" -.spot-icon_star-empty:before +.spot-icon_checkmark-circle:before content: "\f13d" -@mixin spot-icon-square +@mixin spot-icon-checkmark content: "\f13e" -.spot-icon_square:before +.spot-icon_checkmark:before content: "\f13e" -@mixin spot-icon-sort-up +@mixin spot-icon-clipboard content: "\f13f" -.spot-icon_sort-up:before +.spot-icon_clipboard:before content: "\f13f" -@mixin spot-icon-sort-down +@mixin spot-icon-close content: "\f140" -.spot-icon_sort-down:before +.spot-icon_close:before content: "\f140" -@mixin spot-icon-sort-descending +@mixin spot-icon-code-tag content: "\f141" -.spot-icon_sort-descending:before +.spot-icon_code-tag:before content: "\f141" -@mixin spot-icon-sort-by +@mixin spot-icon-color-text content: "\f142" -.spot-icon_sort-by:before +.spot-icon_color-text:before content: "\f142" -@mixin spot-icon-sort-ascending +@mixin spot-icon-color-underline content: "\f143" -.spot-icon_sort-ascending:before +.spot-icon_color-underline:before content: "\f143" -@mixin spot-icon-snooze +@mixin spot-icon-column-left content: "\f144" -.spot-icon_snooze:before +.spot-icon_column-left:before content: "\f144" -@mixin spot-icon-slack +@mixin spot-icon-column-right content: "\f145" -.spot-icon_slack:before +.spot-icon_column-right:before content: "\f145" -@mixin spot-icon-show-more +@mixin spot-icon-columns content: "\f146" -.spot-icon_show-more:before +.spot-icon_columns:before content: "\f146" -@mixin spot-icon-show-more-horizontal +@mixin spot-icon-comments content: "\f147" -.spot-icon_show-more-horizontal:before +.spot-icon_comments:before content: "\f147" -@mixin spot-icon-show-all-projects +@mixin spot-icon-compare2 content: "\f148" -.spot-icon_show-all-projects:before +.spot-icon_compare2:before content: "\f148" -@mixin spot-icon-shortcuts +@mixin spot-icon-concept content: "\f149" -.spot-icon_shortcuts:before +.spot-icon_concept:before content: "\f149" -@mixin spot-icon-share +@mixin spot-icon-configure-knobs content: "\f14a" -.spot-icon_share:before +.spot-icon_configure-knobs:before content: "\f14a" -@mixin spot-icon-settings4 +@mixin spot-icon-console-light content: "\f14b" -.spot-icon_settings4:before +.spot-icon_console-light:before content: "\f14b" -@mixin spot-icon-settings3 +@mixin spot-icon-console content: "\f14c" -.spot-icon_settings3:before +.spot-icon_console:before content: "\f14c" -@mixin spot-icon-settings2 +@mixin spot-icon-contacts content: "\f14d" -.spot-icon_settings2:before +.spot-icon_contacts:before content: "\f14d" -@mixin spot-icon-settings +@mixin spot-icon-copy-documents content: "\f14e" -.spot-icon_settings:before +.spot-icon_copy-documents:before content: "\f14e" -@mixin spot-icon-settings-display +@mixin spot-icon-copy content: "\f14f" -.spot-icon_settings-display:before +.spot-icon_copy:before content: "\f14f" -@mixin spot-icon-server-key +@mixin spot-icon-cost-reports content: "\f150" -.spot-icon_server-key:before +.spot-icon_cost-reports:before content: "\f150" -@mixin spot-icon-send-mail +@mixin spot-icon-cost-types content: "\f151" -.spot-icon_send-mail:before +.spot-icon_cost-types:before content: "\f151" -@mixin spot-icon-select-all +@mixin spot-icon-cursor content: "\f152" -.spot-icon_select-all:before +.spot-icon_cursor:before content: "\f152" -@mixin spot-icon-search +@mixin spot-icon-custom-development content: "\f153" -.spot-icon_search:before +.spot-icon_custom-development:before content: "\f153" -@mixin spot-icon-save +@mixin spot-icon-custom-fields content: "\f154" -.spot-icon_save:before +.spot-icon_custom-fields:before content: "\f154" -@mixin spot-icon-rubber +@mixin spot-icon-cut content: "\f155" -.spot-icon_rubber:before +.spot-icon_cut:before content: "\f155" -@mixin spot-icon-rss +@mixin spot-icon-date-alerts content: "\f156" -.spot-icon_rss:before +.spot-icon_date-alerts:before content: "\f156" -@mixin spot-icon-roadmap +@mixin spot-icon-delete-folder content: "\f157" -.spot-icon_roadmap:before +.spot-icon_delete-folder:before content: "\f157" -@mixin spot-icon-return-to-previous +@mixin spot-icon-delete content: "\f158" -.spot-icon_return-to-previous:before +.spot-icon_delete:before content: "\f158" -@mixin spot-icon-resizer-vertical-lines +@mixin spot-icon-delta-triangle content: "\f159" -.spot-icon_resizer-vertical-lines:before +.spot-icon_delta-triangle:before content: "\f159" -@mixin spot-icon-resizer-bottom-right +@mixin spot-icon-dependency content: "\f15a" -.spot-icon_resizer-bottom-right:before +.spot-icon_dependency:before content: "\f15a" -@mixin spot-icon-reported-by-me +@mixin spot-icon-design content: "\f15b" -.spot-icon_reported-by-me:before +.spot-icon_design:before content: "\f15b" -@mixin spot-icon-rename +@mixin spot-icon-double-arrow-left content: "\f15c" -.spot-icon_rename:before +.spot-icon_double-arrow-left:before content: "\f15c" -@mixin spot-icon-remove +@mixin spot-icon-double-arrow-right content: "\f15d" -.spot-icon_remove:before +.spot-icon_double-arrow-right:before content: "\f15d" -@mixin spot-icon-remove-link +@mixin spot-icon-download-arrow content: "\f15e" -.spot-icon_remove-link:before +.spot-icon_download-arrow:before content: "\f15e" -@mixin spot-icon-remove-1 +@mixin spot-icon-download content: "\f15f" -.spot-icon_remove-1:before +.spot-icon_download:before content: "\f15f" -@mixin spot-icon-reminder +@mixin spot-icon-drag-handle content: "\f160" -.spot-icon_reminder:before +.spot-icon_drag-handle:before content: "\f160" -@mixin spot-icon-reload +@mixin spot-icon-dropdown-open content: "\f161" -.spot-icon_reload:before +.spot-icon_dropdown-open:before content: "\f161" -@mixin spot-icon-relations +@mixin spot-icon-dropdown content: "\f162" -.spot-icon_relations:before +.spot-icon_dropdown:before content: "\f162" -@mixin spot-icon-relation-precedes +@mixin spot-icon-duplicate content: "\f163" -.spot-icon_relation-precedes:before +.spot-icon_duplicate:before content: "\f163" -@mixin spot-icon-relation-new-child +@mixin spot-icon-edit content: "\f164" -.spot-icon_relation-new-child:before +.spot-icon_edit:before content: "\f164" -@mixin spot-icon-relation-follows +@mixin spot-icon-email-alert content: "\f165" -.spot-icon_relation-follows:before +.spot-icon_email-alert:before content: "\f165" -@mixin spot-icon-redo +@mixin spot-icon-enterprise-addons content: "\f166" -.spot-icon_redo:before +.spot-icon_enterprise-addons:before content: "\f166" -@mixin spot-icon-quote2 +@mixin spot-icon-enterprise-badge content: "\f167" -.spot-icon_quote2:before +.spot-icon_enterprise-badge:before content: "\f167" -@mixin spot-icon-quote +@mixin spot-icon-enterprise content: "\f168" -.spot-icon_quote:before +.spot-icon_enterprise:before content: "\f168" -@mixin spot-icon-pulldown +@mixin spot-icon-enumerations content: "\f169" -.spot-icon_pulldown:before +.spot-icon_enumerations:before content: "\f169" -@mixin spot-icon-pulldown-up +@mixin spot-icon-error content: "\f16a" -.spot-icon_pulldown-up:before +.spot-icon_error:before content: "\f16a" -@mixin spot-icon-publish +@mixin spot-icon-export-atom content: "\f16b" -.spot-icon_publish:before +.spot-icon_export-atom:before content: "\f16b" -@mixin spot-icon-projects +@mixin spot-icon-export-bcf content: "\f16c" -.spot-icon_projects:before +.spot-icon_export-bcf:before content: "\f16c" -@mixin spot-icon-project-types +@mixin spot-icon-export-csv content: "\f16d" -.spot-icon_project-types:before +.spot-icon_export-csv:before content: "\f16d" -@mixin spot-icon-priority +@mixin spot-icon-export-pdf-1 content: "\f16e" -.spot-icon_priority:before +.spot-icon_export-pdf-1:before content: "\f16e" -@mixin spot-icon-print +@mixin spot-icon-export-pdf-descr content: "\f16f" -.spot-icon_print:before +.spot-icon_export-pdf-descr:before content: "\f16f" -@mixin spot-icon-preview +@mixin spot-icon-export-pdf-with-descriptions content: "\f170" -.spot-icon_preview:before +.spot-icon_export-pdf-with-descriptions:before content: "\f170" -@mixin spot-icon-presentation +@mixin spot-icon-export-pdf content: "\f171" -.spot-icon_presentation:before +.spot-icon_export-pdf:before content: "\f171" -@mixin spot-icon-pre +@mixin spot-icon-export-xls-descr content: "\f172" -.spot-icon_pre:before +.spot-icon_export-xls-descr:before content: "\f172" -@mixin spot-icon-plus +@mixin spot-icon-export-xls-with-descriptions content: "\f173" -.spot-icon_plus:before +.spot-icon_export-xls-with-descriptions:before content: "\f173" -@mixin spot-icon-plugins +@mixin spot-icon-export-xls-with-relations content: "\f174" -.spot-icon_plugins:before +.spot-icon_export-xls-with-relations:before content: "\f174" -@mixin spot-icon-play +@mixin spot-icon-export-xls content: "\f175" -.spot-icon_play:before +.spot-icon_export-xls:before content: "\f175" -@mixin spot-icon-pin +@mixin spot-icon-export content: "\f176" -.spot-icon_pin:before +.spot-icon_export:before content: "\f176" -@mixin spot-icon-phone +@mixin spot-icon-external-link content: "\f177" -.spot-icon_phone:before +.spot-icon_external-link:before content: "\f177" -@mixin spot-icon-payment-history +@mixin spot-icon-faq content: "\f178" -.spot-icon_payment-history:before +.spot-icon_faq:before content: "\f178" -@mixin spot-icon-paragraph +@mixin spot-icon-file-doc content: "\f179" -.spot-icon_paragraph:before +.spot-icon_file-doc:before content: "\f179" -@mixin spot-icon-paragraph-right +@mixin spot-icon-file-form content: "\f17a" -.spot-icon_paragraph-right:before +.spot-icon_file-form:before content: "\f17a" -@mixin spot-icon-paragraph-left +@mixin spot-icon-file-presentation content: "\f17b" -.spot-icon_paragraph-left:before +.spot-icon_file-presentation:before content: "\f17b" -@mixin spot-icon-outline +@mixin spot-icon-file-sheet content: "\f17c" -.spot-icon_outline:before +.spot-icon_file-sheet:before content: "\f17c" -@mixin spot-icon-ordered-list +@mixin spot-icon-file-storage-connection content: "\f17d" -.spot-icon_ordered-list:before +.spot-icon_file-storage-connection:before content: "\f17d" -@mixin spot-icon-openproject +@mixin spot-icon-file-text content: "\f17e" -.spot-icon_openproject:before +.spot-icon_file-text:before content: "\f17e" -@mixin spot-icon-openid +@mixin spot-icon-filter content: "\f17f" -.spot-icon_openid:before +.spot-icon_filter:before content: "\f17f" -@mixin spot-icon-notes +@mixin spot-icon-flag content: "\f180" -.spot-icon_notes:before +.spot-icon_flag:before content: "\f180" -@mixin spot-icon-not-watching +@mixin spot-icon-folder-add content: "\f181" -.spot-icon_not-watching:before +.spot-icon_folder-add:before content: "\f181" -@mixin spot-icon-not-supported +@mixin spot-icon-folder-locked content: "\f182" -.spot-icon_not-supported:before +.spot-icon_folder-locked:before content: "\f182" -@mixin spot-icon-no-zen-mode +@mixin spot-icon-folder-open content: "\f183" -.spot-icon_no-zen-mode:before +.spot-icon_folder-open:before content: "\f183" -@mixin spot-icon-no-hierarchy +@mixin spot-icon-folder-remove content: "\f184" -.spot-icon_no-hierarchy:before +.spot-icon_folder-remove:before content: "\f184" -@mixin spot-icon-nextcloud +@mixin spot-icon-folder content: "\f185" -.spot-icon_nextcloud:before +.spot-icon_folder:before content: "\f185" -@mixin spot-icon-nextcloud-circle +@mixin spot-icon-forums content: "\f186" -.spot-icon_nextcloud-circle:before +.spot-icon_forums:before content: "\f186" -@mixin spot-icon-news +@mixin spot-icon-from-fullscreen content: "\f187" -.spot-icon_news:before +.spot-icon_from-fullscreen:before content: "\f187" -@mixin spot-icon-new-planning-element +@mixin spot-icon-getting-started content: "\f188" -.spot-icon_new-planning-element:before +.spot-icon_getting-started:before content: "\f188" -@mixin spot-icon-music +@mixin spot-icon-github_logo content: "\f189" -.spot-icon_music:before +.spot-icon_github_logo:before content: "\f189" -@mixin spot-icon-movie +@mixin spot-icon-gitlab_logo content: "\f18a" -.spot-icon_movie:before +.spot-icon_gitlab_logo:before content: "\f18a" -@mixin spot-icon-move +@mixin spot-icon-glossar content: "\f18b" -.spot-icon_move:before +.spot-icon_glossar:before content: "\f18b" -@mixin spot-icon-more +@mixin spot-icon-google-plus content: "\f18c" -.spot-icon_more:before +.spot-icon_google-plus:before content: "\f18c" -@mixin spot-icon-modules +@mixin spot-icon-group-by content: "\f18d" -.spot-icon_modules:before +.spot-icon_group-by:before content: "\f18d" -@mixin spot-icon-mobile +@mixin spot-icon-group content: "\f18e" -.spot-icon_mobile:before +.spot-icon_group:before content: "\f18e" -@mixin spot-icon-minus2 +@mixin spot-icon-hamburger content: "\f18f" -.spot-icon_minus2:before +.spot-icon_hamburger:before content: "\f18f" -@mixin spot-icon-minus1 +@mixin spot-icon-headline1 content: "\f190" -.spot-icon_minus1:before +.spot-icon_headline1:before content: "\f190" -@mixin spot-icon-milestone +@mixin spot-icon-headline2 content: "\f191" -.spot-icon_milestone:before +.spot-icon_headline2:before content: "\f191" -@mixin spot-icon-microphone +@mixin spot-icon-headline3 content: "\f192" -.spot-icon_microphone:before +.spot-icon_headline3:before content: "\f192" -@mixin spot-icon-merge-branch +@mixin spot-icon-headset content: "\f193" -.spot-icon_merge-branch:before +.spot-icon_headset:before content: "\f193" -@mixin spot-icon-menu +@mixin spot-icon-help content: "\f194" -.spot-icon_menu:before +.spot-icon_help:before content: "\f194" -@mixin spot-icon-mention +@mixin spot-icon-help1 content: "\f195" -.spot-icon_mention:before +.spot-icon_help1:before content: "\f195" -@mixin spot-icon-mention-comment +@mixin spot-icon-help2 content: "\f196" -.spot-icon_mention-comment:before +.spot-icon_help2:before content: "\f196" -@mixin spot-icon-meetings +@mixin spot-icon-hide content: "\f197" -.spot-icon_meetings:before +.spot-icon_hide:before content: "\f197" -@mixin spot-icon-mark-read +@mixin spot-icon-hierarchy content: "\f198" -.spot-icon_mark-read:before +.spot-icon_hierarchy:before content: "\f198" -@mixin spot-icon-mark-all-read +@mixin spot-icon-home content: "\f199" -.spot-icon_mark-all-read:before +.spot-icon_home:before content: "\f199" -@mixin spot-icon-maintenance-support +@mixin spot-icon-hosting content: "\f19a" -.spot-icon_maintenance-support:before +.spot-icon_hosting:before content: "\f19a" -@mixin spot-icon-mail2 +@mixin spot-icon-iconfont-scaler content: "\f19b" -.spot-icon_mail2:before +.spot-icon_iconfont-scaler:before content: "\f19b" -@mixin spot-icon-mail1 +@mixin spot-icon-ifc content: "\f19c" -.spot-icon_mail1:before +.spot-icon_ifc:before content: "\f19c" -@mixin spot-icon-logout +@mixin spot-icon-image1 content: "\f19d" -.spot-icon_logout:before +.spot-icon_image1:before content: "\f19d" -@mixin spot-icon-locked +@mixin spot-icon-image2 content: "\f19e" -.spot-icon_locked:before +.spot-icon_image2:before content: "\f19e" -@mixin spot-icon-location +@mixin spot-icon-import content: "\f19f" -.spot-icon_location:before +.spot-icon_import:before content: "\f19f" -@mixin spot-icon-loading2 +@mixin spot-icon-inbox content: "\f1a0" -.spot-icon_loading2:before +.spot-icon_inbox:before content: "\f1a0" -@mixin spot-icon-loading1 +@mixin spot-icon-info1 content: "\f1a1" -.spot-icon_loading1:before +.spot-icon_info1:before content: "\f1a1" -@mixin spot-icon-link +@mixin spot-icon-info2 content: "\f1a2" -.spot-icon_link:before +.spot-icon_info2:before content: "\f1a2" -@mixin spot-icon-like-hand +@mixin spot-icon-input-disabled content: "\f1a3" -.spot-icon_like-hand:before +.spot-icon_input-disabled:before content: "\f1a3" -@mixin spot-icon-key +@mixin spot-icon-installation-services content: "\f1a4" -.spot-icon_key:before +.spot-icon_installation-services:before content: "\f1a4" @@ -1183,1150 +1183,1150 @@ content: "\f1a5" -@mixin spot-icon-installation-services +@mixin spot-icon-key content: "\f1a6" -.spot-icon_installation-services:before +.spot-icon_key:before content: "\f1a6" -@mixin spot-icon-input-disabled +@mixin spot-icon-like-hand content: "\f1a7" -.spot-icon_input-disabled:before +.spot-icon_like-hand:before content: "\f1a7" -@mixin spot-icon-info2 +@mixin spot-icon-link content: "\f1a8" -.spot-icon_info2:before +.spot-icon_link:before content: "\f1a8" -@mixin spot-icon-info1 +@mixin spot-icon-loading1 content: "\f1a9" -.spot-icon_info1:before +.spot-icon_loading1:before content: "\f1a9" -@mixin spot-icon-inbox +@mixin spot-icon-loading2 content: "\f1aa" -.spot-icon_inbox:before +.spot-icon_loading2:before content: "\f1aa" -@mixin spot-icon-import +@mixin spot-icon-location content: "\f1ab" -.spot-icon_import:before +.spot-icon_location:before content: "\f1ab" -@mixin spot-icon-image2 +@mixin spot-icon-locked content: "\f1ac" -.spot-icon_image2:before +.spot-icon_locked:before content: "\f1ac" -@mixin spot-icon-image1 +@mixin spot-icon-logout content: "\f1ad" -.spot-icon_image1:before +.spot-icon_logout:before content: "\f1ad" -@mixin spot-icon-ifc +@mixin spot-icon-mail1 content: "\f1ae" -.spot-icon_ifc:before +.spot-icon_mail1:before content: "\f1ae" -@mixin spot-icon-iconfont-scaler +@mixin spot-icon-mail2 content: "\f1af" -.spot-icon_iconfont-scaler:before +.spot-icon_mail2:before content: "\f1af" -@mixin spot-icon-hosting +@mixin spot-icon-maintenance-support content: "\f1b0" -.spot-icon_hosting:before +.spot-icon_maintenance-support:before content: "\f1b0" -@mixin spot-icon-home +@mixin spot-icon-mark-all-read content: "\f1b1" -.spot-icon_home:before +.spot-icon_mark-all-read:before content: "\f1b1" -@mixin spot-icon-hierarchy +@mixin spot-icon-mark-read content: "\f1b2" -.spot-icon_hierarchy:before +.spot-icon_mark-read:before content: "\f1b2" -@mixin spot-icon-hide +@mixin spot-icon-meetings content: "\f1b3" -.spot-icon_hide:before +.spot-icon_meetings:before content: "\f1b3" -@mixin spot-icon-help2 +@mixin spot-icon-mention-comment content: "\f1b4" -.spot-icon_help2:before +.spot-icon_mention-comment:before content: "\f1b4" -@mixin spot-icon-help1 +@mixin spot-icon-mention content: "\f1b5" -.spot-icon_help1:before +.spot-icon_mention:before content: "\f1b5" -@mixin spot-icon-help +@mixin spot-icon-menu content: "\f1b6" -.spot-icon_help:before +.spot-icon_menu:before content: "\f1b6" -@mixin spot-icon-headset +@mixin spot-icon-merge-branch content: "\f1b7" -.spot-icon_headset:before +.spot-icon_merge-branch:before content: "\f1b7" -@mixin spot-icon-headline3 +@mixin spot-icon-microphone content: "\f1b8" -.spot-icon_headline3:before +.spot-icon_microphone:before content: "\f1b8" -@mixin spot-icon-headline2 +@mixin spot-icon-milestone content: "\f1b9" -.spot-icon_headline2:before +.spot-icon_milestone:before content: "\f1b9" -@mixin spot-icon-headline1 +@mixin spot-icon-minus1 content: "\f1ba" -.spot-icon_headline1:before +.spot-icon_minus1:before content: "\f1ba" -@mixin spot-icon-hamburger +@mixin spot-icon-minus2 content: "\f1bb" -.spot-icon_hamburger:before +.spot-icon_minus2:before content: "\f1bb" -@mixin spot-icon-group +@mixin spot-icon-mobile content: "\f1bc" -.spot-icon_group:before +.spot-icon_mobile:before content: "\f1bc" -@mixin spot-icon-group-by +@mixin spot-icon-modules content: "\f1bd" -.spot-icon_group-by:before +.spot-icon_modules:before content: "\f1bd" -@mixin spot-icon-google-plus +@mixin spot-icon-more content: "\f1be" -.spot-icon_google-plus:before +.spot-icon_more:before content: "\f1be" -@mixin spot-icon-glossar +@mixin spot-icon-move content: "\f1bf" -.spot-icon_glossar:before +.spot-icon_move:before content: "\f1bf" -@mixin spot-icon-gitlab_logo +@mixin spot-icon-movie content: "\f1c0" -.spot-icon_gitlab_logo:before +.spot-icon_movie:before content: "\f1c0" -@mixin spot-icon-github_logo +@mixin spot-icon-music content: "\f1c1" -.spot-icon_github_logo:before +.spot-icon_music:before content: "\f1c1" -@mixin spot-icon-getting-started +@mixin spot-icon-new-planning-element content: "\f1c2" -.spot-icon_getting-started:before +.spot-icon_new-planning-element:before content: "\f1c2" -@mixin spot-icon-from-fullscreen +@mixin spot-icon-news content: "\f1c3" -.spot-icon_from-fullscreen:before +.spot-icon_news:before content: "\f1c3" -@mixin spot-icon-forums +@mixin spot-icon-nextcloud-circle content: "\f1c4" -.spot-icon_forums:before +.spot-icon_nextcloud-circle:before content: "\f1c4" -@mixin spot-icon-folder +@mixin spot-icon-nextcloud content: "\f1c5" -.spot-icon_folder:before +.spot-icon_nextcloud:before content: "\f1c5" -@mixin spot-icon-folder-remove +@mixin spot-icon-no-hierarchy content: "\f1c6" -.spot-icon_folder-remove:before +.spot-icon_no-hierarchy:before content: "\f1c6" -@mixin spot-icon-folder-open +@mixin spot-icon-no-zen-mode content: "\f1c7" -.spot-icon_folder-open:before +.spot-icon_no-zen-mode:before content: "\f1c7" -@mixin spot-icon-folder-locked +@mixin spot-icon-not-supported content: "\f1c8" -.spot-icon_folder-locked:before +.spot-icon_not-supported:before content: "\f1c8" -@mixin spot-icon-folder-add +@mixin spot-icon-not-watching content: "\f1c9" -.spot-icon_folder-add:before +.spot-icon_not-watching:before content: "\f1c9" -@mixin spot-icon-flag +@mixin spot-icon-notes content: "\f1ca" -.spot-icon_flag:before +.spot-icon_notes:before content: "\f1ca" -@mixin spot-icon-filter +@mixin spot-icon-openid content: "\f1cb" -.spot-icon_filter:before +.spot-icon_openid:before content: "\f1cb" -@mixin spot-icon-file-text +@mixin spot-icon-openproject content: "\f1cc" -.spot-icon_file-text:before +.spot-icon_openproject:before content: "\f1cc" -@mixin spot-icon-file-storage-connection +@mixin spot-icon-ordered-list content: "\f1cd" -.spot-icon_file-storage-connection:before +.spot-icon_ordered-list:before content: "\f1cd" -@mixin spot-icon-file-sheet +@mixin spot-icon-outline content: "\f1ce" -.spot-icon_file-sheet:before +.spot-icon_outline:before content: "\f1ce" -@mixin spot-icon-file-presentation +@mixin spot-icon-paragraph-left content: "\f1cf" -.spot-icon_file-presentation:before +.spot-icon_paragraph-left:before content: "\f1cf" -@mixin spot-icon-file-form +@mixin spot-icon-paragraph-right content: "\f1d0" -.spot-icon_file-form:before +.spot-icon_paragraph-right:before content: "\f1d0" -@mixin spot-icon-file-doc +@mixin spot-icon-paragraph content: "\f1d1" -.spot-icon_file-doc:before +.spot-icon_paragraph:before content: "\f1d1" -@mixin spot-icon-faq +@mixin spot-icon-payment-history content: "\f1d2" -.spot-icon_faq:before +.spot-icon_payment-history:before content: "\f1d2" -@mixin spot-icon-external-link +@mixin spot-icon-phone content: "\f1d3" -.spot-icon_external-link:before +.spot-icon_phone:before content: "\f1d3" -@mixin spot-icon-export +@mixin spot-icon-pin content: "\f1d4" -.spot-icon_export:before +.spot-icon_pin:before content: "\f1d4" -@mixin spot-icon-export-xls +@mixin spot-icon-play content: "\f1d5" -.spot-icon_export-xls:before +.spot-icon_play:before content: "\f1d5" -@mixin spot-icon-export-xls-with-relations +@mixin spot-icon-plugins content: "\f1d6" -.spot-icon_export-xls-with-relations:before +.spot-icon_plugins:before content: "\f1d6" -@mixin spot-icon-export-xls-with-descriptions +@mixin spot-icon-plus content: "\f1d7" -.spot-icon_export-xls-with-descriptions:before +.spot-icon_plus:before content: "\f1d7" -@mixin spot-icon-export-xls-descr +@mixin spot-icon-pre content: "\f1d8" -.spot-icon_export-xls-descr:before +.spot-icon_pre:before content: "\f1d8" -@mixin spot-icon-export-pdf +@mixin spot-icon-presentation content: "\f1d9" -.spot-icon_export-pdf:before +.spot-icon_presentation:before content: "\f1d9" -@mixin spot-icon-export-pdf-with-descriptions +@mixin spot-icon-preview content: "\f1da" -.spot-icon_export-pdf-with-descriptions:before +.spot-icon_preview:before content: "\f1da" -@mixin spot-icon-export-pdf-descr +@mixin spot-icon-print content: "\f1db" -.spot-icon_export-pdf-descr:before +.spot-icon_print:before content: "\f1db" -@mixin spot-icon-export-pdf-1 +@mixin spot-icon-priority content: "\f1dc" -.spot-icon_export-pdf-1:before +.spot-icon_priority:before content: "\f1dc" -@mixin spot-icon-export-csv +@mixin spot-icon-project-types content: "\f1dd" -.spot-icon_export-csv:before +.spot-icon_project-types:before content: "\f1dd" -@mixin spot-icon-export-bcf +@mixin spot-icon-projects content: "\f1de" -.spot-icon_export-bcf:before +.spot-icon_projects:before content: "\f1de" -@mixin spot-icon-export-atom +@mixin spot-icon-publish content: "\f1df" -.spot-icon_export-atom:before +.spot-icon_publish:before content: "\f1df" -@mixin spot-icon-error +@mixin spot-icon-pulldown-up content: "\f1e0" -.spot-icon_error:before +.spot-icon_pulldown-up:before content: "\f1e0" -@mixin spot-icon-enumerations +@mixin spot-icon-pulldown content: "\f1e1" -.spot-icon_enumerations:before +.spot-icon_pulldown:before content: "\f1e1" -@mixin spot-icon-enterprise +@mixin spot-icon-quote content: "\f1e2" -.spot-icon_enterprise:before +.spot-icon_quote:before content: "\f1e2" -@mixin spot-icon-enterprise-badge +@mixin spot-icon-quote2 content: "\f1e3" -.spot-icon_enterprise-badge:before +.spot-icon_quote2:before content: "\f1e3" -@mixin spot-icon-enterprise-addons +@mixin spot-icon-redo content: "\f1e4" -.spot-icon_enterprise-addons:before +.spot-icon_redo:before content: "\f1e4" -@mixin spot-icon-email-alert +@mixin spot-icon-relation-follows content: "\f1e5" -.spot-icon_email-alert:before +.spot-icon_relation-follows:before content: "\f1e5" -@mixin spot-icon-edit +@mixin spot-icon-relation-new-child content: "\f1e6" -.spot-icon_edit:before +.spot-icon_relation-new-child:before content: "\f1e6" -@mixin spot-icon-duplicate +@mixin spot-icon-relation-precedes content: "\f1e7" -.spot-icon_duplicate:before +.spot-icon_relation-precedes:before content: "\f1e7" -@mixin spot-icon-dropdown +@mixin spot-icon-relations content: "\f1e8" -.spot-icon_dropdown:before +.spot-icon_relations:before content: "\f1e8" -@mixin spot-icon-dropdown-open +@mixin spot-icon-reload content: "\f1e9" -.spot-icon_dropdown-open:before +.spot-icon_reload:before content: "\f1e9" -@mixin spot-icon-drag-handle +@mixin spot-icon-reminder content: "\f1ea" -.spot-icon_drag-handle:before +.spot-icon_reminder:before content: "\f1ea" -@mixin spot-icon-download +@mixin spot-icon-remove-1 content: "\f1eb" -.spot-icon_download:before +.spot-icon_remove-1:before content: "\f1eb" -@mixin spot-icon-download-arrow +@mixin spot-icon-remove-link content: "\f1ec" -.spot-icon_download-arrow:before +.spot-icon_remove-link:before content: "\f1ec" -@mixin spot-icon-double-arrow-right +@mixin spot-icon-remove content: "\f1ed" -.spot-icon_double-arrow-right:before +.spot-icon_remove:before content: "\f1ed" -@mixin spot-icon-double-arrow-left +@mixin spot-icon-rename content: "\f1ee" -.spot-icon_double-arrow-left:before +.spot-icon_rename:before content: "\f1ee" -@mixin spot-icon-design +@mixin spot-icon-reported-by-me content: "\f1ef" -.spot-icon_design:before +.spot-icon_reported-by-me:before content: "\f1ef" -@mixin spot-icon-dependency +@mixin spot-icon-resizer-bottom-right content: "\f1f0" -.spot-icon_dependency:before +.spot-icon_resizer-bottom-right:before content: "\f1f0" -@mixin spot-icon-delta-triangle +@mixin spot-icon-resizer-vertical-lines content: "\f1f1" -.spot-icon_delta-triangle:before +.spot-icon_resizer-vertical-lines:before content: "\f1f1" -@mixin spot-icon-delete +@mixin spot-icon-return-to-previous content: "\f1f2" -.spot-icon_delete:before +.spot-icon_return-to-previous:before content: "\f1f2" -@mixin spot-icon-delete-folder +@mixin spot-icon-roadmap content: "\f1f3" -.spot-icon_delete-folder:before +.spot-icon_roadmap:before content: "\f1f3" -@mixin spot-icon-date-alerts +@mixin spot-icon-rss content: "\f1f4" -.spot-icon_date-alerts:before +.spot-icon_rss:before content: "\f1f4" -@mixin spot-icon-cut +@mixin spot-icon-rubber content: "\f1f5" -.spot-icon_cut:before +.spot-icon_rubber:before content: "\f1f5" -@mixin spot-icon-custom-fields +@mixin spot-icon-save content: "\f1f6" -.spot-icon_custom-fields:before +.spot-icon_save:before content: "\f1f6" -@mixin spot-icon-custom-development +@mixin spot-icon-search content: "\f1f7" -.spot-icon_custom-development:before +.spot-icon_search:before content: "\f1f7" -@mixin spot-icon-cursor +@mixin spot-icon-select-all content: "\f1f8" -.spot-icon_cursor:before +.spot-icon_select-all:before content: "\f1f8" -@mixin spot-icon-cost-types +@mixin spot-icon-send-mail content: "\f1f9" -.spot-icon_cost-types:before +.spot-icon_send-mail:before content: "\f1f9" -@mixin spot-icon-cost-reports +@mixin spot-icon-server-key content: "\f1fa" -.spot-icon_cost-reports:before +.spot-icon_server-key:before content: "\f1fa" -@mixin spot-icon-copy +@mixin spot-icon-settings-display content: "\f1fb" -.spot-icon_copy:before +.spot-icon_settings-display:before content: "\f1fb" -@mixin spot-icon-copy-documents +@mixin spot-icon-settings content: "\f1fc" -.spot-icon_copy-documents:before +.spot-icon_settings:before content: "\f1fc" -@mixin spot-icon-contacts +@mixin spot-icon-settings2 content: "\f1fd" -.spot-icon_contacts:before +.spot-icon_settings2:before content: "\f1fd" -@mixin spot-icon-console +@mixin spot-icon-settings3 content: "\f1fe" -.spot-icon_console:before +.spot-icon_settings3:before content: "\f1fe" -@mixin spot-icon-console-light +@mixin spot-icon-settings4 content: "\f1ff" -.spot-icon_console-light:before +.spot-icon_settings4:before content: "\f1ff" -@mixin spot-icon-configure-knobs +@mixin spot-icon-share content: "\f200" -.spot-icon_configure-knobs:before +.spot-icon_share:before content: "\f200" -@mixin spot-icon-concept +@mixin spot-icon-shortcuts content: "\f201" -.spot-icon_concept:before +.spot-icon_shortcuts:before content: "\f201" -@mixin spot-icon-compare2 +@mixin spot-icon-show-all-projects content: "\f202" -.spot-icon_compare2:before +.spot-icon_show-all-projects:before content: "\f202" -@mixin spot-icon-comments +@mixin spot-icon-show-more-horizontal content: "\f203" -.spot-icon_comments:before +.spot-icon_show-more-horizontal:before content: "\f203" -@mixin spot-icon-columns +@mixin spot-icon-show-more content: "\f204" -.spot-icon_columns:before +.spot-icon_show-more:before content: "\f204" -@mixin spot-icon-column-right +@mixin spot-icon-slack content: "\f205" -.spot-icon_column-right:before +.spot-icon_slack:before content: "\f205" -@mixin spot-icon-column-left +@mixin spot-icon-snooze content: "\f206" -.spot-icon_column-left:before +.spot-icon_snooze:before content: "\f206" -@mixin spot-icon-color-underline +@mixin spot-icon-sort-ascending content: "\f207" -.spot-icon_color-underline:before +.spot-icon_sort-ascending:before content: "\f207" -@mixin spot-icon-color-text +@mixin spot-icon-sort-by content: "\f208" -.spot-icon_color-text:before +.spot-icon_sort-by:before content: "\f208" -@mixin spot-icon-code-tag +@mixin spot-icon-sort-descending content: "\f209" -.spot-icon_code-tag:before +.spot-icon_sort-descending:before content: "\f209" -@mixin spot-icon-close +@mixin spot-icon-sort-down content: "\f20a" -.spot-icon_close:before +.spot-icon_sort-down:before content: "\f20a" -@mixin spot-icon-clipboard +@mixin spot-icon-sort-up content: "\f20b" -.spot-icon_clipboard:before +.spot-icon_sort-up:before content: "\f20b" -@mixin spot-icon-checkmark +@mixin spot-icon-square content: "\f20c" -.spot-icon_checkmark:before +.spot-icon_square:before content: "\f20c" -@mixin spot-icon-checkmark-circle +@mixin spot-icon-star-empty content: "\f20d" -.spot-icon_checkmark-circle:before +.spot-icon_star-empty:before content: "\f20d" -@mixin spot-icon-chart3 +@mixin spot-icon-star-filled content: "\f20e" -.spot-icon_chart3:before +.spot-icon_star-filled:before content: "\f20e" -@mixin spot-icon-chart2 +@mixin spot-icon-star content: "\f20f" -.spot-icon_chart2:before +.spot-icon_star:before content: "\f20f" -@mixin spot-icon-chart1 +@mixin spot-icon-status-reporting content: "\f210" -.spot-icon_chart1:before +.spot-icon_status-reporting:before content: "\f210" -@mixin spot-icon-changeset +@mixin spot-icon-status content: "\f211" -.spot-icon_changeset:before +.spot-icon_status:before content: "\f211" -@mixin spot-icon-changeset-up +@mixin spot-icon-stop content: "\f212" -.spot-icon_changeset-up:before +.spot-icon_stop:before content: "\f212" -@mixin spot-icon-changeset-down +@mixin spot-icon-strike-through content: "\f213" -.spot-icon_changeset-down:before +.spot-icon_strike-through:before content: "\f213" -@mixin spot-icon-cart +@mixin spot-icon-sum-error content: "\f214" -.spot-icon_cart:before +.spot-icon_sum-error:before content: "\f214" -@mixin spot-icon-cancel +@mixin spot-icon-sum-sign content: "\f215" -.spot-icon_cancel:before +.spot-icon_sum-sign:before content: "\f215" -@mixin spot-icon-cancel-circle +@mixin spot-icon-team-planner content: "\f216" -.spot-icon_cancel-circle:before +.spot-icon_team-planner:before content: "\f216" -@mixin spot-icon-camera +@mixin spot-icon-text content: "\f217" -.spot-icon_camera:before +.spot-icon_text:before content: "\f217" -@mixin spot-icon-calendar2 +@mixin spot-icon-ticket-checked content: "\f218" -.spot-icon_calendar2:before +.spot-icon_ticket-checked:before content: "\f218" -@mixin spot-icon-calendar +@mixin spot-icon-ticket-down content: "\f219" -.spot-icon_calendar:before +.spot-icon_ticket-down:before content: "\f219" -@mixin spot-icon-bug +@mixin spot-icon-ticket-edit content: "\f21a" -.spot-icon_bug:before +.spot-icon_ticket-edit:before content: "\f21a" -@mixin spot-icon-budget +@mixin spot-icon-ticket-minus content: "\f21b" -.spot-icon_budget:before +.spot-icon_ticket-minus:before content: "\f21b" -@mixin spot-icon-bookmark +@mixin spot-icon-ticket-note content: "\f21c" -.spot-icon_bookmark:before +.spot-icon_ticket-note:before content: "\f21c" -@mixin spot-icon-bookmark-filled +@mixin spot-icon-ticket content: "\f21d" -.spot-icon_bookmark-filled:before +.spot-icon_ticket:before content: "\f21d" -@mixin spot-icon-bold +@mixin spot-icon-time-tracking-running content: "\f21e" -.spot-icon_bold:before +.spot-icon_time-tracking-running:before content: "\f21e" -@mixin spot-icon-boards +@mixin spot-icon-time-tracking-start content: "\f21f" -.spot-icon_boards:before +.spot-icon_time-tracking-start:before content: "\f21f" -@mixin spot-icon-blocked +@mixin spot-icon-time-tracking-stop content: "\f220" -.spot-icon_blocked:before +.spot-icon_time-tracking-stop:before content: "\f220" -@mixin spot-icon-billing-information +@mixin spot-icon-time content: "\f221" -.spot-icon_billing-information:before +.spot-icon_time:before content: "\f221" -@mixin spot-icon-bell +@mixin spot-icon-to-fullscreen content: "\f222" -.spot-icon_bell:before +.spot-icon_to-fullscreen:before content: "\f222" -@mixin spot-icon-bcf +@mixin spot-icon-today-arrows content: "\f223" -.spot-icon_bcf:before +.spot-icon_today-arrows:before content: "\f223" -@mixin spot-icon-baseline +@mixin spot-icon-training-consulting content: "\f224" -.spot-icon_baseline:before +.spot-icon_training-consulting:before content: "\f224" -@mixin spot-icon-baseline-delete +@mixin spot-icon-two-factor-authentication content: "\f225" -.spot-icon_baseline-delete:before +.spot-icon_two-factor-authentication:before content: "\f225" -@mixin spot-icon-baseline-add +@mixin spot-icon-two-factor-authentification content: "\f226" -.spot-icon_baseline-add:before +.spot-icon_two-factor-authentification:before content: "\f226" -@mixin spot-icon-backlogs +@mixin spot-icon-types content: "\f227" -.spot-icon_backlogs:before +.spot-icon_types:before content: "\f227" -@mixin spot-icon-back-up +@mixin spot-icon-underline content: "\f228" -.spot-icon_back-up:before +.spot-icon_underline:before content: "\f228" -@mixin spot-icon-attention +@mixin spot-icon-undo content: "\f229" -.spot-icon_attention:before +.spot-icon_undo:before content: "\f229" -@mixin spot-icon-attachment +@mixin spot-icon-unit content: "\f22a" -.spot-icon_attachment:before +.spot-icon_unit:before content: "\f22a" -@mixin spot-icon-assigned +@mixin spot-icon-unlocked content: "\f22b" -.spot-icon_assigned:before +.spot-icon_unlocked:before content: "\f22b" -@mixin spot-icon-assigned-to-me +@mixin spot-icon-unordered-list content: "\f22c" -.spot-icon_assigned-to-me:before +.spot-icon_unordered-list:before content: "\f22c" -@mixin spot-icon-arrow-up2 +@mixin spot-icon-unwatched content: "\f22d" -.spot-icon_arrow-up2:before +.spot-icon_unwatched:before content: "\f22d" -@mixin spot-icon-arrow-up1 +@mixin spot-icon-up-down-stepper content: "\f22e" -.spot-icon_arrow-up1:before +.spot-icon_up-down-stepper:before content: "\f22e" -@mixin spot-icon-arrow-thin +@mixin spot-icon-upload-arrow content: "\f22f" -.spot-icon_arrow-thin:before +.spot-icon_upload-arrow:before content: "\f22f" -@mixin spot-icon-arrow-thin-left +@mixin spot-icon-upload content: "\f230" -.spot-icon_arrow-thin-left:before +.spot-icon_upload:before content: "\f230" -@mixin spot-icon-arrow-right7 +@mixin spot-icon-user-minus content: "\f231" -.spot-icon_arrow-right7:before +.spot-icon_user-minus:before content: "\f231" -@mixin spot-icon-arrow-right6 +@mixin spot-icon-user-missing content: "\f232" -.spot-icon_arrow-right6:before +.spot-icon_user-missing:before content: "\f232" -@mixin spot-icon-arrow-right5 +@mixin spot-icon-user-plus content: "\f233" -.spot-icon_arrow-right5:before +.spot-icon_user-plus:before content: "\f233" -@mixin spot-icon-arrow-right4 +@mixin spot-icon-user content: "\f234" -.spot-icon_arrow-right4:before +.spot-icon_user:before content: "\f234" -@mixin spot-icon-arrow-right3 +@mixin spot-icon-view-card content: "\f235" -.spot-icon_arrow-right3:before +.spot-icon_view-card:before content: "\f235" -@mixin spot-icon-arrow-right2 +@mixin spot-icon-view-fullscreen content: "\f236" -.spot-icon_arrow-right2:before +.spot-icon_view-fullscreen:before content: "\f236" -@mixin spot-icon-arrow-out +@mixin spot-icon-view-list content: "\f237" -.spot-icon_arrow-out:before +.spot-icon_view-list:before content: "\f237" -@mixin spot-icon-arrow-left4 +@mixin spot-icon-view-model content: "\f238" -.spot-icon_arrow-left4:before +.spot-icon_view-model:before content: "\f238" -@mixin spot-icon-arrow-left3 +@mixin spot-icon-view-split-viewer-table content: "\f239" -.spot-icon_arrow-left3:before +.spot-icon_view-split-viewer-table:before content: "\f239" -@mixin spot-icon-arrow-left2 +@mixin spot-icon-view-split content: "\f23a" -.spot-icon_arrow-left2:before +.spot-icon_view-split:before content: "\f23a" -@mixin spot-icon-arrow-left1 +@mixin spot-icon-view-split2 content: "\f23b" -.spot-icon_arrow-left1:before +.spot-icon_view-split2:before content: "\f23b" -@mixin spot-icon-arrow-left-right +@mixin spot-icon-view-timeline content: "\f23c" -.spot-icon_arrow-left-right:before +.spot-icon_view-timeline:before content: "\f23c" -@mixin spot-icon-arrow-in +@mixin spot-icon-warning content: "\f23d" -.spot-icon_arrow-in:before +.spot-icon_warning:before content: "\f23d" -@mixin spot-icon-arrow-down2 +@mixin spot-icon-watched content: "\f23e" -.spot-icon_arrow-down2:before +.spot-icon_watched:before content: "\f23e" -@mixin spot-icon-arrow-down1 +@mixin spot-icon-watching content: "\f23f" -.spot-icon_arrow-down1:before +.spot-icon_watching:before content: "\f23f" -@mixin spot-icon-align-right +@mixin spot-icon-wiki-edit content: "\f240" -.spot-icon_align-right:before +.spot-icon_wiki-edit:before content: "\f240" -@mixin spot-icon-align-left +@mixin spot-icon-wiki content: "\f241" -.spot-icon_align-left:before +.spot-icon_wiki:before content: "\f241" -@mixin spot-icon-align-justify +@mixin spot-icon-wiki2 content: "\f242" -.spot-icon_align-justify:before +.spot-icon_wiki2:before content: "\f242" -@mixin spot-icon-align-center +@mixin spot-icon-work-packages content: "\f243" -.spot-icon_align-center:before +.spot-icon_work-packages:before content: "\f243" -@mixin spot-icon-add +@mixin spot-icon-workflow content: "\f244" -.spot-icon_add:before +.spot-icon_workflow:before content: "\f244" -@mixin spot-icon-add-link +@mixin spot-icon-yes content: "\f245" -.spot-icon_add-link:before +.spot-icon_yes:before content: "\f245" -@mixin spot-icon-add-attachment +@mixin spot-icon-zen-mode content: "\f246" -.spot-icon_add-attachment:before +.spot-icon_zen-mode:before content: "\f246" -@mixin spot-icon-activity-history +@mixin spot-icon-zoom-auto content: "\f247" -.spot-icon_activity-history:before +.spot-icon_zoom-auto:before content: "\f247" -@mixin spot-icon-accountable +@mixin spot-icon-zoom-in content: "\f248" -.spot-icon_accountable:before +.spot-icon_zoom-in:before content: "\f248" -@mixin spot-icon-accessibility +@mixin spot-icon-zoom-out content: "\f249" -.spot-icon_accessibility:before +.spot-icon_zoom-out:before content: "\f249" diff --git a/frontend/src/assets/fonts/openproject_icon/openproject-icon-font.html b/frontend/src/assets/fonts/openproject_icon/openproject-icon-font.html index 265938846694..14f11926b2e5 100644 --- a/frontend/src/assets/fonts/openproject_icon/openproject-icon-font.html +++ b/frontend/src/assets/fonts/openproject_icon/openproject-icon-font.html @@ -25,4313 +25,3897 @@ font-size: 16px; } - -@mixin icon-mixin-zoom-out + +@mixin icon-mixin-accessibility content: "\f101" -.icon-zoom-out:before +.icon-accessibility:before content: "\f101" -@mixin icon-mixin-zoom-in +@mixin icon-mixin-accountable content: "\f102" -.icon-zoom-in:before +.icon-accountable:before content: "\f102" -@mixin icon-mixin-zoom-auto +@mixin icon-mixin-activity-history content: "\f103" -.icon-zoom-auto:before +.icon-activity-history:before content: "\f103" -@mixin icon-mixin-zen-mode +@mixin icon-mixin-add-attachment content: "\f104" -.icon-zen-mode:before +.icon-add-attachment:before content: "\f104" -@mixin icon-mixin-yes +@mixin icon-mixin-add-link content: "\f105" -.icon-yes:before +.icon-add-link:before content: "\f105" -@mixin icon-mixin-workflow +@mixin icon-mixin-add content: "\f106" -.icon-workflow:before +.icon-add:before content: "\f106" -@mixin icon-mixin-work-packages +@mixin icon-mixin-align-center content: "\f107" -.icon-work-packages:before +.icon-align-center:before content: "\f107" -@mixin icon-mixin-wiki2 +@mixin icon-mixin-align-justify content: "\f108" -.icon-wiki2:before +.icon-align-justify:before content: "\f108" -@mixin icon-mixin-wiki +@mixin icon-mixin-align-left content: "\f109" -.icon-wiki:before +.icon-align-left:before content: "\f109" -@mixin icon-mixin-wiki-edit +@mixin icon-mixin-align-right content: "\f10a" -.icon-wiki-edit:before +.icon-align-right:before content: "\f10a" -@mixin icon-mixin-watching +@mixin icon-mixin-arrow-down1 content: "\f10b" -.icon-watching:before +.icon-arrow-down1:before content: "\f10b" -@mixin icon-mixin-watched +@mixin icon-mixin-arrow-down2 content: "\f10c" -.icon-watched:before +.icon-arrow-down2:before content: "\f10c" -@mixin icon-mixin-warning +@mixin icon-mixin-arrow-in content: "\f10d" -.icon-warning:before +.icon-arrow-in:before content: "\f10d" -@mixin icon-mixin-view-timeline +@mixin icon-mixin-arrow-left-right content: "\f10e" -.icon-view-timeline:before +.icon-arrow-left-right:before content: "\f10e" -@mixin icon-mixin-view-split2 +@mixin icon-mixin-arrow-left1 content: "\f10f" -.icon-view-split2:before +.icon-arrow-left1:before content: "\f10f" -@mixin icon-mixin-view-split +@mixin icon-mixin-arrow-left2 content: "\f110" -.icon-view-split:before +.icon-arrow-left2:before content: "\f110" -@mixin icon-mixin-view-split-viewer-table +@mixin icon-mixin-arrow-left3 content: "\f111" -.icon-view-split-viewer-table:before +.icon-arrow-left3:before content: "\f111" -@mixin icon-mixin-view-model +@mixin icon-mixin-arrow-left4 content: "\f112" -.icon-view-model:before +.icon-arrow-left4:before content: "\f112" -@mixin icon-mixin-view-list +@mixin icon-mixin-arrow-out content: "\f113" -.icon-view-list:before +.icon-arrow-out:before content: "\f113" -@mixin icon-mixin-view-fullscreen +@mixin icon-mixin-arrow-right2 content: "\f114" -.icon-view-fullscreen:before +.icon-arrow-right2:before content: "\f114" -@mixin icon-mixin-view-card +@mixin icon-mixin-arrow-right3 content: "\f115" -.icon-view-card:before +.icon-arrow-right3:before content: "\f115" -@mixin icon-mixin-user +@mixin icon-mixin-arrow-right4 content: "\f116" -.icon-user:before +.icon-arrow-right4:before content: "\f116" -@mixin icon-mixin-user-plus +@mixin icon-mixin-arrow-right5 content: "\f117" -.icon-user-plus:before +.icon-arrow-right5:before content: "\f117" -@mixin icon-mixin-user-missing +@mixin icon-mixin-arrow-right6 content: "\f118" -.icon-user-missing:before +.icon-arrow-right6:before content: "\f118" -@mixin icon-mixin-user-minus +@mixin icon-mixin-arrow-right7 content: "\f119" -.icon-user-minus:before +.icon-arrow-right7:before content: "\f119" -@mixin icon-mixin-upload +@mixin icon-mixin-arrow-thin content: "\f11a" -.icon-upload:before +.icon-arrow-thin:before content: "\f11a" -@mixin icon-mixin-upload-arrow +@mixin icon-mixin-arrow-up1 content: "\f11b" -.icon-upload-arrow:before +.icon-arrow-up1:before content: "\f11b" -@mixin icon-mixin-up-down-stepper +@mixin icon-mixin-arrow-up2 content: "\f11c" -.icon-up-down-stepper:before +.icon-arrow-up2:before content: "\f11c" -@mixin icon-mixin-unwatched +@mixin icon-mixin-assigned-to-me content: "\f11d" -.icon-unwatched:before +.icon-assigned-to-me:before content: "\f11d" -@mixin icon-mixin-unordered-list +@mixin icon-mixin-assigned content: "\f11e" -.icon-unordered-list:before +.icon-assigned:before content: "\f11e" -@mixin icon-mixin-unlocked +@mixin icon-mixin-attachment content: "\f11f" -.icon-unlocked:before +.icon-attachment:before content: "\f11f" -@mixin icon-mixin-unit +@mixin icon-mixin-attention content: "\f120" -.icon-unit:before +.icon-attention:before content: "\f120" -@mixin icon-mixin-undo +@mixin icon-mixin-back-up content: "\f121" -.icon-undo:before +.icon-back-up:before content: "\f121" -@mixin icon-mixin-underline +@mixin icon-mixin-backlogs content: "\f122" -.icon-underline:before +.icon-backlogs:before content: "\f122" -@mixin icon-mixin-types +@mixin icon-mixin-baseline content: "\f123" -.icon-types:before +.icon-baseline:before content: "\f123" -@mixin icon-mixin-two-factor-authentification +@mixin icon-mixin-bcf content: "\f124" -.icon-two-factor-authentification:before +.icon-bcf:before content: "\f124" -@mixin icon-mixin-two-factor-authentication +@mixin icon-mixin-bell content: "\f125" -.icon-two-factor-authentication:before +.icon-bell:before content: "\f125" -@mixin icon-mixin-training-consulting +@mixin icon-mixin-billing-information content: "\f126" -.icon-training-consulting:before +.icon-billing-information:before content: "\f126" -@mixin icon-mixin-today-arrows +@mixin icon-mixin-boards content: "\f127" -.icon-today-arrows:before +.icon-boards:before content: "\f127" -@mixin icon-mixin-to-fullscreen +@mixin icon-mixin-bold content: "\f128" -.icon-to-fullscreen:before +.icon-bold:before content: "\f128" -@mixin icon-mixin-time +@mixin icon-mixin-budget content: "\f129" -.icon-time:before +.icon-budget:before content: "\f129" -@mixin icon-mixin-time-tracking-stop +@mixin icon-mixin-bug content: "\f12a" -.icon-time-tracking-stop:before +.icon-bug:before content: "\f12a" -@mixin icon-mixin-time-tracking-start +@mixin icon-mixin-calendar content: "\f12b" -.icon-time-tracking-start:before +.icon-calendar:before content: "\f12b" -@mixin icon-mixin-time-tracking-running +@mixin icon-mixin-calendar2 content: "\f12c" -.icon-time-tracking-running:before +.icon-calendar2:before content: "\f12c" -@mixin icon-mixin-ticket +@mixin icon-mixin-camera content: "\f12d" -.icon-ticket:before +.icon-camera:before content: "\f12d" -@mixin icon-mixin-ticket-note +@mixin icon-mixin-cancel-circle content: "\f12e" -.icon-ticket-note:before +.icon-cancel-circle:before content: "\f12e" -@mixin icon-mixin-ticket-minus +@mixin icon-mixin-cancel content: "\f12f" -.icon-ticket-minus:before +.icon-cancel:before content: "\f12f" -@mixin icon-mixin-ticket-edit +@mixin icon-mixin-cart content: "\f130" -.icon-ticket-edit:before +.icon-cart:before content: "\f130" -@mixin icon-mixin-ticket-down +@mixin icon-mixin-changeset-down content: "\f131" -.icon-ticket-down:before +.icon-changeset-down:before content: "\f131" -@mixin icon-mixin-ticket-checked +@mixin icon-mixin-changeset-up content: "\f132" -.icon-ticket-checked:before +.icon-changeset-up:before content: "\f132" -@mixin icon-mixin-text +@mixin icon-mixin-changeset content: "\f133" -.icon-text:before +.icon-changeset:before content: "\f133" -@mixin icon-mixin-team-planner +@mixin icon-mixin-chart1 content: "\f134" -.icon-team-planner:before +.icon-chart1:before content: "\f134" -@mixin icon-mixin-sum-sign +@mixin icon-mixin-chart2 content: "\f135" -.icon-sum-sign:before +.icon-chart2:before content: "\f135" -@mixin icon-mixin-sum-error +@mixin icon-mixin-chart3 content: "\f136" -.icon-sum-error:before +.icon-chart3:before content: "\f136" -@mixin icon-mixin-strike-through +@mixin icon-mixin-checkmark-circle content: "\f137" -.icon-strike-through:before +.icon-checkmark-circle:before content: "\f137" -@mixin icon-mixin-stop +@mixin icon-mixin-checkmark content: "\f138" -.icon-stop:before +.icon-checkmark:before content: "\f138" -@mixin icon-mixin-status +@mixin icon-mixin-clipboard content: "\f139" -.icon-status:before +.icon-clipboard:before content: "\f139" -@mixin icon-mixin-status-reporting +@mixin icon-mixin-close content: "\f13a" -.icon-status-reporting:before +.icon-close:before content: "\f13a" -@mixin icon-mixin-star +@mixin icon-mixin-code-tag content: "\f13b" -.icon-star:before +.icon-code-tag:before content: "\f13b" -@mixin icon-mixin-star-filled +@mixin icon-mixin-color-text content: "\f13c" -.icon-star-filled:before +.icon-color-text:before content: "\f13c" -@mixin icon-mixin-star-empty +@mixin icon-mixin-color-underline content: "\f13d" -.icon-star-empty:before +.icon-color-underline:before content: "\f13d" -@mixin icon-mixin-square +@mixin icon-mixin-column-left content: "\f13e" -.icon-square:before +.icon-column-left:before content: "\f13e" -@mixin icon-mixin-sort-up +@mixin icon-mixin-column-right content: "\f13f" -.icon-sort-up:before +.icon-column-right:before content: "\f13f" -@mixin icon-mixin-sort-down +@mixin icon-mixin-columns content: "\f140" -.icon-sort-down:before +.icon-columns:before content: "\f140" -@mixin icon-mixin-sort-descending +@mixin icon-mixin-compare2 content: "\f141" -.icon-sort-descending:before +.icon-compare2:before content: "\f141" -@mixin icon-mixin-sort-by +@mixin icon-mixin-concept content: "\f142" -.icon-sort-by:before +.icon-concept:before content: "\f142" -@mixin icon-mixin-sort-ascending +@mixin icon-mixin-console-light content: "\f143" -.icon-sort-ascending:before +.icon-console-light:before content: "\f143" -@mixin icon-mixin-snooze +@mixin icon-mixin-console content: "\f144" -.icon-snooze:before +.icon-console:before content: "\f144" -@mixin icon-mixin-slack +@mixin icon-mixin-contacts content: "\f145" -.icon-slack:before +.icon-contacts:before content: "\f145" -@mixin icon-mixin-show-more +@mixin icon-mixin-copy content: "\f146" -.icon-show-more:before +.icon-copy:before content: "\f146" -@mixin icon-mixin-show-more-horizontal +@mixin icon-mixin-cost-reports content: "\f147" -.icon-show-more-horizontal:before +.icon-cost-reports:before content: "\f147" -@mixin icon-mixin-show-all-projects +@mixin icon-mixin-cost-types content: "\f148" -.icon-show-all-projects:before +.icon-cost-types:before content: "\f148" -@mixin icon-mixin-shortcuts +@mixin icon-mixin-cursor content: "\f149" -.icon-shortcuts:before +.icon-cursor:before content: "\f149" -@mixin icon-mixin-share +@mixin icon-mixin-custom-development content: "\f14a" -.icon-share:before +.icon-custom-development:before content: "\f14a" -@mixin icon-mixin-settings4 +@mixin icon-mixin-custom-fields content: "\f14b" -.icon-settings4:before +.icon-custom-fields:before content: "\f14b" -@mixin icon-mixin-settings3 +@mixin icon-mixin-cut content: "\f14c" -.icon-settings3:before +.icon-cut:before content: "\f14c" -@mixin icon-mixin-settings2 +@mixin icon-mixin-date-alert content: "\f14d" -.icon-settings2:before +.icon-date-alert:before content: "\f14d" -@mixin icon-mixin-settings +@mixin icon-mixin-date-alerts content: "\f14e" -.icon-settings:before +.icon-date-alerts:before content: "\f14e" -@mixin icon-mixin-settings-display +@mixin icon-mixin-delete-folder content: "\f14f" -.icon-settings-display:before +.icon-delete-folder:before content: "\f14f" -@mixin icon-mixin-server-key +@mixin icon-mixin-delete content: "\f150" -.icon-server-key:before +.icon-delete:before content: "\f150" -@mixin icon-mixin-send-mail +@mixin icon-mixin-delta-triangle content: "\f151" -.icon-send-mail:before +.icon-delta-triangle:before content: "\f151" -@mixin icon-mixin-select-all +@mixin icon-mixin-dependency content: "\f152" -.icon-select-all:before +.icon-dependency:before content: "\f152" -@mixin icon-mixin-search +@mixin icon-mixin-design content: "\f153" -.icon-search:before +.icon-design:before content: "\f153" -@mixin icon-mixin-save +@mixin icon-mixin-double-arrow-left content: "\f154" -.icon-save:before +.icon-double-arrow-left:before content: "\f154" -@mixin icon-mixin-rubber +@mixin icon-mixin-double-arrow-right content: "\f155" -.icon-rubber:before +.icon-double-arrow-right:before content: "\f155" -@mixin icon-mixin-rss +@mixin icon-mixin-download-arrow content: "\f156" -.icon-rss:before +.icon-download-arrow:before content: "\f156" -@mixin icon-mixin-roadmap +@mixin icon-mixin-download content: "\f157" -.icon-roadmap:before +.icon-download:before content: "\f157" -@mixin icon-mixin-return-to-previous +@mixin icon-mixin-drag-handle content: "\f158" -.icon-return-to-previous:before +.icon-drag-handle:before content: "\f158" -@mixin icon-mixin-resizer-vertical-lines +@mixin icon-mixin-dropdown-open content: "\f159" -.icon-resizer-vertical-lines:before +.icon-dropdown-open:before content: "\f159" -@mixin icon-mixin-resizer-bottom-right +@mixin icon-mixin-dropdown content: "\f15a" -.icon-resizer-bottom-right:before +.icon-dropdown:before content: "\f15a" -@mixin icon-mixin-reported-by-me +@mixin icon-mixin-duplicate content: "\f15b" -.icon-reported-by-me:before +.icon-duplicate:before content: "\f15b" -@mixin icon-mixin-rename +@mixin icon-mixin-edit content: "\f15c" -.icon-rename:before +.icon-edit:before content: "\f15c" -@mixin icon-mixin-remove +@mixin icon-mixin-email-alert content: "\f15d" -.icon-remove:before +.icon-email-alert:before content: "\f15d" -@mixin icon-mixin-remove-link +@mixin icon-mixin-enterprise-addons content: "\f15e" -.icon-remove-link:before +.icon-enterprise-addons:before content: "\f15e" -@mixin icon-mixin-remove-1 +@mixin icon-mixin-enterprise content: "\f15f" -.icon-remove-1:before +.icon-enterprise:before content: "\f15f" -@mixin icon-mixin-reminder +@mixin icon-mixin-enumerations content: "\f160" -.icon-reminder:before +.icon-enumerations:before content: "\f160" -@mixin icon-mixin-reload +@mixin icon-mixin-error content: "\f161" -.icon-reload:before +.icon-error:before content: "\f161" -@mixin icon-mixin-relations +@mixin icon-mixin-export-atom content: "\f162" -.icon-relations:before +.icon-export-atom:before content: "\f162" -@mixin icon-mixin-relation-precedes +@mixin icon-mixin-export-bcf content: "\f163" -.icon-relation-precedes:before +.icon-export-bcf:before content: "\f163" -@mixin icon-mixin-relation-new-child +@mixin icon-mixin-export-csv content: "\f164" -.icon-relation-new-child:before +.icon-export-csv:before content: "\f164" -@mixin icon-mixin-relation-follows +@mixin icon-mixin-export-pdf-descr content: "\f165" -.icon-relation-follows:before +.icon-export-pdf-descr:before content: "\f165" -@mixin icon-mixin-redo +@mixin icon-mixin-export-pdf-with-descriptions content: "\f166" -.icon-redo:before +.icon-export-pdf-with-descriptions:before content: "\f166" -@mixin icon-mixin-quote2 +@mixin icon-mixin-export-pdf content: "\f167" -.icon-quote2:before +.icon-export-pdf:before content: "\f167" -@mixin icon-mixin-quote +@mixin icon-mixin-export-xls-descr content: "\f168" -.icon-quote:before +.icon-export-xls-descr:before content: "\f168" -@mixin icon-mixin-pulldown +@mixin icon-mixin-export-xls-with-descriptions content: "\f169" -.icon-pulldown:before +.icon-export-xls-with-descriptions:before content: "\f169" -@mixin icon-mixin-pulldown-up +@mixin icon-mixin-export-xls-with-relations content: "\f16a" -.icon-pulldown-up:before +.icon-export-xls-with-relations:before content: "\f16a" -@mixin icon-mixin-publish +@mixin icon-mixin-export-xls content: "\f16b" -.icon-publish:before +.icon-export-xls:before content: "\f16b" -@mixin icon-mixin-projects +@mixin icon-mixin-export content: "\f16c" -.icon-projects:before +.icon-export:before content: "\f16c" -@mixin icon-mixin-project-types +@mixin icon-mixin-external-link content: "\f16d" -.icon-project-types:before +.icon-external-link:before content: "\f16d" -@mixin icon-mixin-priority +@mixin icon-mixin-faq content: "\f16e" -.icon-priority:before +.icon-faq:before content: "\f16e" -@mixin icon-mixin-print +@mixin icon-mixin-file-doc content: "\f16f" -.icon-print:before +.icon-file-doc:before content: "\f16f" -@mixin icon-mixin-preview +@mixin icon-mixin-file-form content: "\f170" -.icon-preview:before +.icon-file-form:before content: "\f170" -@mixin icon-mixin-presentation +@mixin icon-mixin-file-presentation content: "\f171" -.icon-presentation:before +.icon-file-presentation:before content: "\f171" -@mixin icon-mixin-pre +@mixin icon-mixin-file-sheet content: "\f172" -.icon-pre:before +.icon-file-sheet:before content: "\f172" -@mixin icon-mixin-plus +@mixin icon-mixin-file-text content: "\f173" -.icon-plus:before +.icon-file-text:before content: "\f173" -@mixin icon-mixin-plugins +@mixin icon-mixin-filter content: "\f174" -.icon-plugins:before +.icon-filter:before content: "\f174" -@mixin icon-mixin-play +@mixin icon-mixin-flag content: "\f175" -.icon-play:before +.icon-flag:before content: "\f175" -@mixin icon-mixin-pin +@mixin icon-mixin-folder-add content: "\f176" -.icon-pin:before +.icon-folder-add:before content: "\f176" -@mixin icon-mixin-phone +@mixin icon-mixin-folder-locked content: "\f177" -.icon-phone:before +.icon-folder-locked:before content: "\f177" -@mixin icon-mixin-payment-history +@mixin icon-mixin-folder-open content: "\f178" -.icon-payment-history:before +.icon-folder-open:before content: "\f178" -@mixin icon-mixin-paragraph +@mixin icon-mixin-folder-remove content: "\f179" -.icon-paragraph:before +.icon-folder-remove:before content: "\f179" -@mixin icon-mixin-paragraph-right +@mixin icon-mixin-folder content: "\f17a" -.icon-paragraph-right:before +.icon-folder:before content: "\f17a" -@mixin icon-mixin-paragraph-left +@mixin icon-mixin-forums content: "\f17b" -.icon-paragraph-left:before +.icon-forums:before content: "\f17b" -@mixin icon-mixin-outline +@mixin icon-mixin-from-fullscreen content: "\f17c" -.icon-outline:before +.icon-from-fullscreen:before content: "\f17c" -@mixin icon-mixin-ordered-list +@mixin icon-mixin-getting-started content: "\f17d" -.icon-ordered-list:before +.icon-getting-started:before content: "\f17d" -@mixin icon-mixin-openproject +@mixin icon-mixin-glossar content: "\f17e" -.icon-openproject:before +.icon-glossar:before content: "\f17e" -@mixin icon-mixin-openid +@mixin icon-mixin-google-plus content: "\f17f" -.icon-openid:before +.icon-google-plus:before content: "\f17f" -@mixin icon-mixin-notes +@mixin icon-mixin-group-by content: "\f180" -.icon-notes:before +.icon-group-by:before content: "\f180" -@mixin icon-mixin-not-watching +@mixin icon-mixin-group content: "\f181" -.icon-not-watching:before +.icon-group:before content: "\f181" -@mixin icon-mixin-not-supported +@mixin icon-mixin-hamburger content: "\f182" -.icon-not-supported:before +.icon-hamburger:before content: "\f182" -@mixin icon-mixin-no-zen-mode +@mixin icon-mixin-headline1 content: "\f183" -.icon-no-zen-mode:before +.icon-headline1:before content: "\f183" -@mixin icon-mixin-no-hierarchy +@mixin icon-mixin-headline2 content: "\f184" -.icon-no-hierarchy:before +.icon-headline2:before content: "\f184" -@mixin icon-mixin-nextcloud +@mixin icon-mixin-headline3 content: "\f185" -.icon-nextcloud:before +.icon-headline3:before content: "\f185" -@mixin icon-mixin-nextcloud-circle +@mixin icon-mixin-headset content: "\f186" -.icon-nextcloud-circle:before +.icon-headset:before content: "\f186" -@mixin icon-mixin-news +@mixin icon-mixin-help content: "\f187" -.icon-news:before +.icon-help:before content: "\f187" -@mixin icon-mixin-new-planning-element +@mixin icon-mixin-help1 content: "\f188" -.icon-new-planning-element:before +.icon-help1:before content: "\f188" -@mixin icon-mixin-music +@mixin icon-mixin-help2 content: "\f189" -.icon-music:before +.icon-help2:before content: "\f189" -@mixin icon-mixin-movie +@mixin icon-mixin-hierarchy content: "\f18a" -.icon-movie:before +.icon-hierarchy:before content: "\f18a" -@mixin icon-mixin-move +@mixin icon-mixin-home content: "\f18b" -.icon-move:before +.icon-home:before content: "\f18b" -@mixin icon-mixin-more +@mixin icon-mixin-hosting content: "\f18c" -.icon-more:before +.icon-hosting:before content: "\f18c" -@mixin icon-mixin-modules +@mixin icon-mixin-ifc content: "\f18d" -.icon-modules:before +.icon-ifc:before content: "\f18d" -@mixin icon-mixin-mobile +@mixin icon-mixin-image1 content: "\f18e" -.icon-mobile:before +.icon-image1:before content: "\f18e" -@mixin icon-mixin-minus2 +@mixin icon-mixin-image2 content: "\f18f" -.icon-minus2:before +.icon-image2:before content: "\f18f" -@mixin icon-mixin-minus1 +@mixin icon-mixin-import content: "\f190" -.icon-minus1:before +.icon-import:before content: "\f190" -@mixin icon-mixin-milestone +@mixin icon-mixin-inbox content: "\f191" -.icon-milestone:before +.icon-inbox:before content: "\f191" -@mixin icon-mixin-microphone +@mixin icon-mixin-info1 content: "\f192" -.icon-microphone:before +.icon-info1:before content: "\f192" -@mixin icon-mixin-merge-branch +@mixin icon-mixin-info2 content: "\f193" -.icon-merge-branch:before +.icon-info2:before content: "\f193" -@mixin icon-mixin-menu +@mixin icon-mixin-input-disabled content: "\f194" -.icon-menu:before +.icon-input-disabled:before content: "\f194" -@mixin icon-mixin-mention +@mixin icon-mixin-installation-services content: "\f195" -.icon-mention:before +.icon-installation-services:before content: "\f195" -@mixin icon-mixin-mention-comment +@mixin icon-mixin-italic content: "\f196" -.icon-mention-comment:before +.icon-italic:before content: "\f196" -@mixin icon-mixin-meetings +@mixin icon-mixin-key content: "\f197" -.icon-meetings:before +.icon-key:before content: "\f197" -@mixin icon-mixin-medal +@mixin icon-mixin-link content: "\f198" -.icon-medal:before +.icon-link:before content: "\f198" -@mixin icon-mixin-mark-read +@mixin icon-mixin-loading1 content: "\f199" -.icon-mark-read:before +.icon-loading1:before content: "\f199" -@mixin icon-mixin-mark-all-read +@mixin icon-mixin-loading2 content: "\f19a" -.icon-mark-all-read:before +.icon-loading2:before content: "\f19a" -@mixin icon-mixin-maintenance-support +@mixin icon-mixin-location content: "\f19b" -.icon-maintenance-support:before +.icon-location:before content: "\f19b" -@mixin icon-mixin-mail2 +@mixin icon-mixin-locked content: "\f19c" -.icon-mail2:before +.icon-locked:before content: "\f19c" -@mixin icon-mixin-mail1 +@mixin icon-mixin-logout content: "\f19d" -.icon-mail1:before +.icon-logout:before content: "\f19d" -@mixin icon-mixin-logout +@mixin icon-mixin-mail1 content: "\f19e" -.icon-logout:before +.icon-mail1:before content: "\f19e" -@mixin icon-mixin-locked +@mixin icon-mixin-mail2 content: "\f19f" -.icon-locked:before +.icon-mail2:before content: "\f19f" -@mixin icon-mixin-location +@mixin icon-mixin-maintenance-support content: "\f1a0" -.icon-location:before +.icon-maintenance-support:before content: "\f1a0" -@mixin icon-mixin-loading2 +@mixin icon-mixin-mark-all-read content: "\f1a1" -.icon-loading2:before +.icon-mark-all-read:before content: "\f1a1" -@mixin icon-mixin-loading1 +@mixin icon-mixin-mark-read content: "\f1a2" -.icon-loading1:before +.icon-mark-read:before content: "\f1a2" -@mixin icon-mixin-link +@mixin icon-mixin-medal content: "\f1a3" -.icon-link:before +.icon-medal:before content: "\f1a3" -@mixin icon-mixin-like-hand +@mixin icon-mixin-meetings content: "\f1a4" -.icon-like-hand:before +.icon-meetings:before content: "\f1a4" -@mixin icon-mixin-key +@mixin icon-mixin-mention content: "\f1a5" -.icon-key:before +.icon-mention:before content: "\f1a5" -@mixin icon-mixin-italic +@mixin icon-mixin-menu content: "\f1a6" -.icon-italic:before +.icon-menu:before content: "\f1a6" -@mixin icon-mixin-installation-services +@mixin icon-mixin-merge-branch content: "\f1a7" -.icon-installation-services:before +.icon-merge-branch:before content: "\f1a7" -@mixin icon-mixin-input-disabled +@mixin icon-mixin-microphone content: "\f1a8" -.icon-input-disabled:before +.icon-microphone:before content: "\f1a8" -@mixin icon-mixin-info2 +@mixin icon-mixin-milestone content: "\f1a9" -.icon-info2:before +.icon-milestone:before content: "\f1a9" -@mixin icon-mixin-info1 +@mixin icon-mixin-minus1 content: "\f1aa" -.icon-info1:before +.icon-minus1:before content: "\f1aa" -@mixin icon-mixin-inbox +@mixin icon-mixin-minus2 content: "\f1ab" -.icon-inbox:before +.icon-minus2:before content: "\f1ab" -@mixin icon-mixin-import +@mixin icon-mixin-mobile content: "\f1ac" -.icon-import:before +.icon-mobile:before content: "\f1ac" -@mixin icon-mixin-image2 +@mixin icon-mixin-modules content: "\f1ad" -.icon-image2:before +.icon-modules:before content: "\f1ad" -@mixin icon-mixin-image1 +@mixin icon-mixin-more content: "\f1ae" -.icon-image1:before +.icon-more:before content: "\f1ae" -@mixin icon-mixin-ifc +@mixin icon-mixin-move content: "\f1af" -.icon-ifc:before +.icon-move:before content: "\f1af" -@mixin icon-mixin-iconfont-scaler +@mixin icon-mixin-movie content: "\f1b0" -.icon-iconfont-scaler:before +.icon-movie:before content: "\f1b0" -@mixin icon-mixin-hosting +@mixin icon-mixin-music content: "\f1b1" -.icon-hosting:before +.icon-music:before content: "\f1b1" -@mixin icon-mixin-home +@mixin icon-mixin-new-planning-element content: "\f1b2" -.icon-home:before +.icon-new-planning-element:before content: "\f1b2" -@mixin icon-mixin-hierarchy +@mixin icon-mixin-news content: "\f1b3" -.icon-hierarchy:before +.icon-news:before content: "\f1b3" -@mixin icon-mixin-hide +@mixin icon-mixin-nextcloud-circle content: "\f1b4" -.icon-hide:before +.icon-nextcloud-circle:before content: "\f1b4" -@mixin icon-mixin-help2 +@mixin icon-mixin-nextcloud content: "\f1b5" -.icon-help2:before +.icon-nextcloud:before content: "\f1b5" -@mixin icon-mixin-help1 +@mixin icon-mixin-no-hierarchy content: "\f1b6" -.icon-help1:before +.icon-no-hierarchy:before content: "\f1b6" -@mixin icon-mixin-help +@mixin icon-mixin-no-zen-mode content: "\f1b7" -.icon-help:before +.icon-no-zen-mode:before content: "\f1b7" -@mixin icon-mixin-headset +@mixin icon-mixin-not-supported content: "\f1b8" -.icon-headset:before +.icon-not-supported:before content: "\f1b8" -@mixin icon-mixin-headline3 +@mixin icon-mixin-notes content: "\f1b9" -.icon-headline3:before +.icon-notes:before content: "\f1b9" -@mixin icon-mixin-headline2 +@mixin icon-mixin-openid content: "\f1ba" -.icon-headline2:before +.icon-openid:before content: "\f1ba" -@mixin icon-mixin-headline1 +@mixin icon-mixin-openproject content: "\f1bb" -.icon-headline1:before +.icon-openproject:before content: "\f1bb" -@mixin icon-mixin-hamburger +@mixin icon-mixin-ordered-list content: "\f1bc" -.icon-hamburger:before +.icon-ordered-list:before content: "\f1bc" -@mixin icon-mixin-group +@mixin icon-mixin-outline content: "\f1bd" -.icon-group:before +.icon-outline:before content: "\f1bd" -@mixin icon-mixin-group-by +@mixin icon-mixin-paragraph-left content: "\f1be" -.icon-group-by:before +.icon-paragraph-left:before content: "\f1be" -@mixin icon-mixin-google-plus +@mixin icon-mixin-paragraph-right content: "\f1bf" -.icon-google-plus:before +.icon-paragraph-right:before content: "\f1bf" -@mixin icon-mixin-glossar +@mixin icon-mixin-paragraph content: "\f1c0" -.icon-glossar:before +.icon-paragraph:before content: "\f1c0" -@mixin icon-mixin-gitlab_logo +@mixin icon-mixin-payment-history content: "\f1c1" -.icon-gitlab_logo:before +.icon-payment-history:before content: "\f1c1" -@mixin icon-mixin-github_logo +@mixin icon-mixin-phone content: "\f1c2" -.icon-github_logo:before +.icon-phone:before content: "\f1c2" -@mixin icon-mixin-getting-started +@mixin icon-mixin-pin content: "\f1c3" -.icon-getting-started:before +.icon-pin:before content: "\f1c3" -@mixin icon-mixin-from-fullscreen +@mixin icon-mixin-play content: "\f1c4" -.icon-from-fullscreen:before +.icon-play:before content: "\f1c4" -@mixin icon-mixin-forums +@mixin icon-mixin-plugins content: "\f1c5" -.icon-forums:before +.icon-plugins:before content: "\f1c5" -@mixin icon-mixin-folder +@mixin icon-mixin-plus content: "\f1c6" -.icon-folder:before +.icon-plus:before content: "\f1c6" -@mixin icon-mixin-folder-remove +@mixin icon-mixin-pre content: "\f1c7" -.icon-folder-remove:before +.icon-pre:before content: "\f1c7" -@mixin icon-mixin-folder-open +@mixin icon-mixin-presentation content: "\f1c8" -.icon-folder-open:before +.icon-presentation:before content: "\f1c8" -@mixin icon-mixin-folder-locked +@mixin icon-mixin-preview content: "\f1c9" -.icon-folder-locked:before +.icon-preview:before content: "\f1c9" -@mixin icon-mixin-folder-add +@mixin icon-mixin-print content: "\f1ca" -.icon-folder-add:before +.icon-print:before content: "\f1ca" -@mixin icon-mixin-flag +@mixin icon-mixin-priority content: "\f1cb" -.icon-flag:before +.icon-priority:before content: "\f1cb" -@mixin icon-mixin-filter +@mixin icon-mixin-project-types content: "\f1cc" -.icon-filter:before +.icon-project-types:before content: "\f1cc" -@mixin icon-mixin-file-text +@mixin icon-mixin-projects content: "\f1cd" -.icon-file-text:before +.icon-projects:before content: "\f1cd" -@mixin icon-mixin-file-storage-connection +@mixin icon-mixin-publish content: "\f1ce" -.icon-file-storage-connection:before +.icon-publish:before content: "\f1ce" -@mixin icon-mixin-file-sheet +@mixin icon-mixin-pulldown-up content: "\f1cf" -.icon-file-sheet:before +.icon-pulldown-up:before content: "\f1cf" -@mixin icon-mixin-file-presentation +@mixin icon-mixin-pulldown content: "\f1d0" -.icon-file-presentation:before +.icon-pulldown:before content: "\f1d0" -@mixin icon-mixin-file-form +@mixin icon-mixin-quote content: "\f1d1" -.icon-file-form:before +.icon-quote:before content: "\f1d1" -@mixin icon-mixin-file-doc +@mixin icon-mixin-quote2 content: "\f1d2" -.icon-file-doc:before +.icon-quote2:before content: "\f1d2" -@mixin icon-mixin-faq +@mixin icon-mixin-redo content: "\f1d3" -.icon-faq:before +.icon-redo:before content: "\f1d3" -@mixin icon-mixin-external-link +@mixin icon-mixin-relation-follows content: "\f1d4" -.icon-external-link:before +.icon-relation-follows:before content: "\f1d4" -@mixin icon-mixin-export +@mixin icon-mixin-relation-new-child content: "\f1d5" -.icon-export:before +.icon-relation-new-child:before content: "\f1d5" -@mixin icon-mixin-export-xls +@mixin icon-mixin-relation-precedes content: "\f1d6" -.icon-export-xls:before +.icon-relation-precedes:before content: "\f1d6" -@mixin icon-mixin-export-xls-with-relations +@mixin icon-mixin-relations content: "\f1d7" -.icon-export-xls-with-relations:before +.icon-relations:before content: "\f1d7" -@mixin icon-mixin-export-xls-with-descriptions +@mixin icon-mixin-reload content: "\f1d8" -.icon-export-xls-with-descriptions:before +.icon-reload:before content: "\f1d8" -@mixin icon-mixin-export-xls-descr +@mixin icon-mixin-reminder content: "\f1d9" -.icon-export-xls-descr:before +.icon-reminder:before content: "\f1d9" -@mixin icon-mixin-export-pdf +@mixin icon-mixin-remove-link content: "\f1da" -.icon-export-pdf:before +.icon-remove-link:before content: "\f1da" -@mixin icon-mixin-export-pdf-with-descriptions +@mixin icon-mixin-remove content: "\f1db" -.icon-export-pdf-with-descriptions:before +.icon-remove:before content: "\f1db" -@mixin icon-mixin-export-pdf-descr +@mixin icon-mixin-rename content: "\f1dc" -.icon-export-pdf-descr:before +.icon-rename:before content: "\f1dc" -@mixin icon-mixin-export-pdf-1 +@mixin icon-mixin-reported-by-me content: "\f1dd" -.icon-export-pdf-1:before +.icon-reported-by-me:before content: "\f1dd" -@mixin icon-mixin-export-csv +@mixin icon-mixin-resizer-bottom-right content: "\f1de" -.icon-export-csv:before +.icon-resizer-bottom-right:before content: "\f1de" -@mixin icon-mixin-export-bcf +@mixin icon-mixin-resizer-vertical-lines content: "\f1df" -.icon-export-bcf:before +.icon-resizer-vertical-lines:before content: "\f1df" -@mixin icon-mixin-export-atom +@mixin icon-mixin-roadmap content: "\f1e0" -.icon-export-atom:before +.icon-roadmap:before content: "\f1e0" -@mixin icon-mixin-error +@mixin icon-mixin-rss content: "\f1e1" -.icon-error:before +.icon-rss:before content: "\f1e1" -@mixin icon-mixin-enumerations +@mixin icon-mixin-rubber content: "\f1e2" -.icon-enumerations:before +.icon-rubber:before content: "\f1e2" -@mixin icon-mixin-enterprise +@mixin icon-mixin-save content: "\f1e3" -.icon-enterprise:before +.icon-save:before content: "\f1e3" -@mixin icon-mixin-enterprise-badge +@mixin icon-mixin-search content: "\f1e4" -.icon-enterprise-badge:before +.icon-search:before content: "\f1e4" -@mixin icon-mixin-enterprise-addons +@mixin icon-mixin-select-all content: "\f1e5" -.icon-enterprise-addons:before +.icon-select-all:before content: "\f1e5" -@mixin icon-mixin-email-alert +@mixin icon-mixin-send-mail content: "\f1e6" -.icon-email-alert:before +.icon-send-mail:before content: "\f1e6" -@mixin icon-mixin-edit +@mixin icon-mixin-server-key content: "\f1e7" -.icon-edit:before +.icon-server-key:before content: "\f1e7" -@mixin icon-mixin-duplicate +@mixin icon-mixin-settings content: "\f1e8" -.icon-duplicate:before +.icon-settings:before content: "\f1e8" -@mixin icon-mixin-dropdown +@mixin icon-mixin-settings2 content: "\f1e9" -.icon-dropdown:before +.icon-settings2:before content: "\f1e9" -@mixin icon-mixin-dropdown-open +@mixin icon-mixin-settings3 content: "\f1ea" -.icon-dropdown-open:before +.icon-settings3:before content: "\f1ea" -@mixin icon-mixin-drag-handle +@mixin icon-mixin-settings4 content: "\f1eb" -.icon-drag-handle:before +.icon-settings4:before content: "\f1eb" -@mixin icon-mixin-download +@mixin icon-mixin-share content: "\f1ec" -.icon-download:before +.icon-share:before content: "\f1ec" -@mixin icon-mixin-download-arrow +@mixin icon-mixin-shortcuts content: "\f1ed" -.icon-download-arrow:before +.icon-shortcuts:before content: "\f1ed" -@mixin icon-mixin-double-arrow-right +@mixin icon-mixin-show-all-projects content: "\f1ee" -.icon-double-arrow-right:before +.icon-show-all-projects:before content: "\f1ee" -@mixin icon-mixin-double-arrow-left +@mixin icon-mixin-show-more-horizontal content: "\f1ef" -.icon-double-arrow-left:before +.icon-show-more-horizontal:before content: "\f1ef" -@mixin icon-mixin-design +@mixin icon-mixin-show-more content: "\f1f0" -.icon-design:before +.icon-show-more:before content: "\f1f0" -@mixin icon-mixin-dependency +@mixin icon-mixin-slack content: "\f1f1" -.icon-dependency:before +.icon-slack:before content: "\f1f1" -@mixin icon-mixin-delta-triangle +@mixin icon-mixin-sort-ascending content: "\f1f2" -.icon-delta-triangle:before +.icon-sort-ascending:before content: "\f1f2" -@mixin icon-mixin-delete +@mixin icon-mixin-sort-by content: "\f1f3" -.icon-delete:before +.icon-sort-by:before content: "\f1f3" -@mixin icon-mixin-delete-folder +@mixin icon-mixin-sort-descending content: "\f1f4" -.icon-delete-folder:before +.icon-sort-descending:before content: "\f1f4" -@mixin icon-mixin-date-alerts +@mixin icon-mixin-sort-down content: "\f1f5" -.icon-date-alerts:before +.icon-sort-down:before content: "\f1f5" -@mixin icon-mixin-date-alert +@mixin icon-mixin-sort-up content: "\f1f6" -.icon-date-alert:before +.icon-sort-up:before content: "\f1f6" -@mixin icon-mixin-cut +@mixin icon-mixin-square content: "\f1f7" -.icon-cut:before +.icon-square:before content: "\f1f7" -@mixin icon-mixin-custom-fields +@mixin icon-mixin-star content: "\f1f8" -.icon-custom-fields:before +.icon-star:before content: "\f1f8" -@mixin icon-mixin-custom-development +@mixin icon-mixin-status-reporting content: "\f1f9" -.icon-custom-development:before +.icon-status-reporting:before content: "\f1f9" -@mixin icon-mixin-cursor +@mixin icon-mixin-status content: "\f1fa" -.icon-cursor:before +.icon-status:before content: "\f1fa" -@mixin icon-mixin-cost-types +@mixin icon-mixin-strike-through content: "\f1fb" -.icon-cost-types:before +.icon-strike-through:before content: "\f1fb" -@mixin icon-mixin-cost-reports +@mixin icon-mixin-team-planner content: "\f1fc" -.icon-cost-reports:before +.icon-team-planner:before content: "\f1fc" -@mixin icon-mixin-copy +@mixin icon-mixin-text content: "\f1fd" -.icon-copy:before +.icon-text:before content: "\f1fd" -@mixin icon-mixin-copy-documents +@mixin icon-mixin-ticket-checked content: "\f1fe" -.icon-copy-documents:before +.icon-ticket-checked:before content: "\f1fe" -@mixin icon-mixin-contacts +@mixin icon-mixin-ticket-down content: "\f1ff" -.icon-contacts:before +.icon-ticket-down:before content: "\f1ff" -@mixin icon-mixin-console +@mixin icon-mixin-ticket-edit content: "\f200" -.icon-console:before +.icon-ticket-edit:before content: "\f200" -@mixin icon-mixin-console-light +@mixin icon-mixin-ticket-minus content: "\f201" -.icon-console-light:before +.icon-ticket-minus:before content: "\f201" -@mixin icon-mixin-configure-knobs +@mixin icon-mixin-ticket-note content: "\f202" -.icon-configure-knobs:before +.icon-ticket-note:before content: "\f202" -@mixin icon-mixin-concept +@mixin icon-mixin-ticket content: "\f203" -.icon-concept:before +.icon-ticket:before content: "\f203" -@mixin icon-mixin-compare2 +@mixin icon-mixin-time-tracking-running content: "\f204" -.icon-compare2:before +.icon-time-tracking-running:before content: "\f204" -@mixin icon-mixin-comments +@mixin icon-mixin-time-tracking-start content: "\f205" -.icon-comments:before +.icon-time-tracking-start:before content: "\f205" -@mixin icon-mixin-columns +@mixin icon-mixin-time-tracking-stop content: "\f206" -.icon-columns:before +.icon-time-tracking-stop:before content: "\f206" -@mixin icon-mixin-column-right +@mixin icon-mixin-time content: "\f207" -.icon-column-right:before +.icon-time:before content: "\f207" -@mixin icon-mixin-column-left +@mixin icon-mixin-to-fullscreen content: "\f208" -.icon-column-left:before +.icon-to-fullscreen:before content: "\f208" -@mixin icon-mixin-color-underline +@mixin icon-mixin-training-consulting content: "\f209" -.icon-color-underline:before +.icon-training-consulting:before content: "\f209" -@mixin icon-mixin-color-text +@mixin icon-mixin-two-factor-authentication content: "\f20a" -.icon-color-text:before +.icon-two-factor-authentication:before content: "\f20a" -@mixin icon-mixin-code-tag +@mixin icon-mixin-types content: "\f20b" -.icon-code-tag:before +.icon-types:before content: "\f20b" -@mixin icon-mixin-close +@mixin icon-mixin-underline content: "\f20c" -.icon-close:before +.icon-underline:before content: "\f20c" -@mixin icon-mixin-clipboard +@mixin icon-mixin-undo content: "\f20d" -.icon-clipboard:before +.icon-undo:before content: "\f20d" -@mixin icon-mixin-checkmark +@mixin icon-mixin-unit content: "\f20e" -.icon-checkmark:before +.icon-unit:before content: "\f20e" -@mixin icon-mixin-checkmark-circle +@mixin icon-mixin-unlocked content: "\f20f" -.icon-checkmark-circle:before +.icon-unlocked:before content: "\f20f" -@mixin icon-mixin-chart3 +@mixin icon-mixin-unordered-list content: "\f210" -.icon-chart3:before +.icon-unordered-list:before content: "\f210" -@mixin icon-mixin-chart2 +@mixin icon-mixin-unwatched content: "\f211" -.icon-chart2:before +.icon-unwatched:before content: "\f211" -@mixin icon-mixin-chart1 +@mixin icon-mixin-upload-arrow content: "\f212" -.icon-chart1:before +.icon-upload-arrow:before content: "\f212" -@mixin icon-mixin-changeset +@mixin icon-mixin-upload content: "\f213" -.icon-changeset:before +.icon-upload:before content: "\f213" -@mixin icon-mixin-changeset-up +@mixin icon-mixin-user-minus content: "\f214" -.icon-changeset-up:before +.icon-user-minus:before content: "\f214" -@mixin icon-mixin-changeset-down +@mixin icon-mixin-user-plus content: "\f215" -.icon-changeset-down:before +.icon-user-plus:before content: "\f215" -@mixin icon-mixin-cart +@mixin icon-mixin-user content: "\f216" -.icon-cart:before +.icon-user:before content: "\f216" -@mixin icon-mixin-cancel +@mixin icon-mixin-view-card content: "\f217" -.icon-cancel:before +.icon-view-card:before content: "\f217" -@mixin icon-mixin-cancel-circle +@mixin icon-mixin-view-fullscreen content: "\f218" -.icon-cancel-circle:before +.icon-view-fullscreen:before content: "\f218" -@mixin icon-mixin-camera +@mixin icon-mixin-view-list content: "\f219" -.icon-camera:before +.icon-view-list:before content: "\f219" -@mixin icon-mixin-calendar2 +@mixin icon-mixin-view-model content: "\f21a" -.icon-calendar2:before +.icon-view-model:before content: "\f21a" -@mixin icon-mixin-calendar +@mixin icon-mixin-view-split-viewer-table content: "\f21b" -.icon-calendar:before +.icon-view-split-viewer-table:before content: "\f21b" -@mixin icon-mixin-bug +@mixin icon-mixin-view-split content: "\f21c" -.icon-bug:before +.icon-view-split:before content: "\f21c" -@mixin icon-mixin-budget +@mixin icon-mixin-view-split2 content: "\f21d" -.icon-budget:before +.icon-view-split2:before content: "\f21d" -@mixin icon-mixin-bookmark +@mixin icon-mixin-view-timeline content: "\f21e" -.icon-bookmark:before +.icon-view-timeline:before content: "\f21e" -@mixin icon-mixin-bookmark-filled +@mixin icon-mixin-warning content: "\f21f" -.icon-bookmark-filled:before +.icon-warning:before content: "\f21f" -@mixin icon-mixin-bold +@mixin icon-mixin-watched content: "\f220" -.icon-bold:before +.icon-watched:before content: "\f220" -@mixin icon-mixin-boards +@mixin icon-mixin-watching content: "\f221" -.icon-boards:before +.icon-watching:before content: "\f221" -@mixin icon-mixin-blocked +@mixin icon-mixin-wiki-edit content: "\f222" -.icon-blocked:before +.icon-wiki-edit:before content: "\f222" -@mixin icon-mixin-billing-information +@mixin icon-mixin-wiki content: "\f223" -.icon-billing-information:before +.icon-wiki:before content: "\f223" -@mixin icon-mixin-bell +@mixin icon-mixin-wiki2 content: "\f224" -.icon-bell:before +.icon-wiki2:before content: "\f224" -@mixin icon-mixin-bcf +@mixin icon-mixin-work-packages content: "\f225" -.icon-bcf:before +.icon-work-packages:before content: "\f225" -@mixin icon-mixin-baseline +@mixin icon-mixin-workflow content: "\f226" -.icon-baseline:before +.icon-workflow:before content: "\f226" -@mixin icon-mixin-baseline-delete +@mixin icon-mixin-yes content: "\f227" -.icon-baseline-delete:before +.icon-yes:before content: "\f227" -@mixin icon-mixin-baseline-add +@mixin icon-mixin-zen-mode content: "\f228" -.icon-baseline-add:before +.icon-zen-mode:before content: "\f228" -@mixin icon-mixin-backlogs +@mixin icon-mixin-zoom-auto content: "\f229" -.icon-backlogs:before +.icon-zoom-auto:before content: "\f229" -@mixin icon-mixin-back-up +@mixin icon-mixin-zoom-in content: "\f22a" -.icon-back-up:before +.icon-zoom-in:before content: "\f22a" -@mixin icon-mixin-attention +@mixin icon-mixin-zoom-out content: "\f22b" -.icon-attention:before +.icon-zoom-out:before content: "\f22b" -@mixin icon-mixin-attachment - content: "\f22c" - -.icon-attachment:before - content: "\f22c" - - -@mixin icon-mixin-assigned - content: "\f22d" - -.icon-assigned:before - content: "\f22d" - - -@mixin icon-mixin-assigned-to-me - content: "\f22e" - -.icon-assigned-to-me:before - content: "\f22e" - - -@mixin icon-mixin-arrow-up2 - content: "\f22f" - -.icon-arrow-up2:before - content: "\f22f" - - -@mixin icon-mixin-arrow-up1 - content: "\f230" - -.icon-arrow-up1:before - content: "\f230" - - -@mixin icon-mixin-arrow-thin - content: "\f231" - -.icon-arrow-thin:before - content: "\f231" - - -@mixin icon-mixin-arrow-thin-left - content: "\f232" - -.icon-arrow-thin-left:before - content: "\f232" - - -@mixin icon-mixin-arrow-right7 - content: "\f233" - -.icon-arrow-right7:before - content: "\f233" - - -@mixin icon-mixin-arrow-right6 - content: "\f234" - -.icon-arrow-right6:before - content: "\f234" - - -@mixin icon-mixin-arrow-right5 - content: "\f235" - -.icon-arrow-right5:before - content: "\f235" - - -@mixin icon-mixin-arrow-right4 - content: "\f236" - -.icon-arrow-right4:before - content: "\f236" - - -@mixin icon-mixin-arrow-right3 - content: "\f237" - -.icon-arrow-right3:before - content: "\f237" - - -@mixin icon-mixin-arrow-right2 - content: "\f238" - -.icon-arrow-right2:before - content: "\f238" - - -@mixin icon-mixin-arrow-out - content: "\f239" - -.icon-arrow-out:before - content: "\f239" - - -@mixin icon-mixin-arrow-left4 - content: "\f23a" - -.icon-arrow-left4:before - content: "\f23a" - - -@mixin icon-mixin-arrow-left3 - content: "\f23b" - -.icon-arrow-left3:before - content: "\f23b" - - -@mixin icon-mixin-arrow-left2 - content: "\f23c" - -.icon-arrow-left2:before - content: "\f23c" - - -@mixin icon-mixin-arrow-left1 - content: "\f23d" - -.icon-arrow-left1:before - content: "\f23d" - - -@mixin icon-mixin-arrow-left-right - content: "\f23e" - -.icon-arrow-left-right:before - content: "\f23e" - - -@mixin icon-mixin-arrow-in - content: "\f23f" - -.icon-arrow-in:before - content: "\f23f" - - -@mixin icon-mixin-arrow-down2 - content: "\f240" - -.icon-arrow-down2:before - content: "\f240" - - -@mixin icon-mixin-arrow-down1 - content: "\f241" - -.icon-arrow-down1:before - content: "\f241" - - -@mixin icon-mixin-align-right - content: "\f242" - -.icon-align-right:before - content: "\f242" - - -@mixin icon-mixin-align-left - content: "\f243" - -.icon-align-left:before - content: "\f243" - - -@mixin icon-mixin-align-justify - content: "\f244" - -.icon-align-justify:before - content: "\f244" - - -@mixin icon-mixin-align-center - content: "\f245" - -.icon-align-center:before - content: "\f245" - - -@mixin icon-mixin-add - content: "\f246" - -.icon-add:before - content: "\f246" - - -@mixin icon-mixin-add-link - content: "\f247" - -.icon-add-link:before - content: "\f247" - - -@mixin icon-mixin-add-attachment - content: "\f248" - -.icon-add-attachment:before - content: "\f248" - - -@mixin icon-mixin-activity-history - content: "\f249" - -.icon-activity-history:before - content: "\f249" - - -@mixin icon-mixin-accountable - content: "\f24a" - -.icon-accountable:before - content: "\f24a" - - -@mixin icon-mixin-accessibility - content: "\f24b" - -.icon-accessibility:before - content: "\f24b" - -

    openproject-icon-font

    - - - zoom-out -
    -
    - - - - zoom-in -
    -
    - - - - zoom-auto -
    -
    - - + - zen-mode -
    -
    - - - - yes -
    -
    - - - - workflow -
    -
    - - - - work-packages -
    -
    - - - - wiki2 -
    -
    - - - - wiki -
    -
    - - - - wiki-edit -
    -
    - - - - watching -
    -
    - - - - watched -
    -
    - - - - warning -
    -
    - - - - view-timeline -
    -
    - - - - view-split2 -
    -
    - - - - view-split -
    -
    - - - - view-split-viewer-table -
    -
    - - - - view-model -
    -
    - - - - view-list -
    -
    - - - - view-fullscreen -
    -
    - - - - view-card -
    -
    - - - - user -
    -
    - - - - user-plus -
    -
    - - - - user-missing -
    -
    - - - - user-minus -
    -
    - - - - upload -
    -
    - - - - upload-arrow -
    -
    - - - - up-down-stepper -
    -
    - - - - unwatched -
    -
    - - - - unordered-list -
    -
    - - - - unlocked -
    -
    - - - - unit -
    -
    - - - - undo + accessibility
    - + - underline + accountable
    - + - types + activity-history
    - + - two-factor-authentification + add-attachment
    - + - two-factor-authentication + add-link
    - + - training-consulting + add
    - + - today-arrows + align-center
    - + - to-fullscreen + align-justify
    - + - time + align-left
    - + - time-tracking-stop + align-right
    - + - time-tracking-start + arrow-down1
    - + - time-tracking-running + arrow-down2
    - + - ticket + arrow-in
    - + - ticket-note + arrow-left-right
    - + - ticket-minus + arrow-left1
    - + - ticket-edit + arrow-left2
    - + - ticket-down + arrow-left3
    - + - ticket-checked + arrow-left4
    - + - text + arrow-out
    - + - team-planner + arrow-right2
    - + - sum-sign + arrow-right3
    - + - sum-error + arrow-right4
    - + - strike-through + arrow-right5
    - + - stop + arrow-right6
    - + - status + arrow-right7
    - + - status-reporting + arrow-thin
    - + - star + arrow-up1
    - + - star-filled + arrow-up2
    - + - star-empty + assigned-to-me
    - + - square + assigned
    - + - sort-up + attachment
    - + - sort-down + attention
    - + - sort-descending + back-up
    - + - sort-by + backlogs
    - + - sort-ascending + baseline
    - + - snooze + bcf
    - + - slack + bell
    - + - show-more + billing-information
    - + - show-more-horizontal + boards
    - + - show-all-projects + bold
    - + - shortcuts + budget
    - + - share + bug
    - + - settings4 + calendar
    - + - settings3 + calendar2
    - + - settings2 + camera
    - + - settings + cancel-circle
    - + - settings-display + cancel
    - + - server-key + cart
    - + - send-mail + changeset-down
    - + - select-all + changeset-up
    - + - search + changeset
    - + - save + chart1
    - + - rubber + chart2
    - + - rss + chart3
    - + - roadmap + checkmark-circle
    - + - return-to-previous + checkmark
    - + - resizer-vertical-lines + clipboard
    - + - resizer-bottom-right + close
    - + - reported-by-me + code-tag
    - + - rename + color-text
    - + - remove + color-underline
    - + - remove-link + column-left
    - + - remove-1 + column-right
    - + - reminder + columns
    - + - reload + compare2
    - + - relations + concept
    - + - relation-precedes + console-light
    - + - relation-new-child + console
    - + - relation-follows + contacts
    - + - redo + copy
    - + - quote2 + cost-reports
    - + - quote + cost-types
    - + - pulldown + cursor
    - + - pulldown-up + custom-development
    - + - publish + custom-fields
    - + - projects + cut
    - + - project-types + date-alert
    - + - priority + date-alerts
    - + - print + delete-folder
    - + - preview + delete
    - + - presentation + delta-triangle
    - + - pre + dependency
    - + - plus + design
    - + - plugins + double-arrow-left
    - + - play + double-arrow-right
    - + - pin + download-arrow
    - + - phone + download
    - + - payment-history + drag-handle
    - + - paragraph + dropdown-open
    - + - paragraph-right + dropdown
    - + - paragraph-left + duplicate
    - + - outline + edit
    - + - ordered-list + email-alert
    - + - openproject + enterprise-addons
    - + - openid + enterprise
    - + - notes + enumerations
    - + - not-watching + error
    - + - not-supported + export-atom
    - + - no-zen-mode + export-bcf
    - + - no-hierarchy + export-csv
    - + - nextcloud + export-pdf-descr
    - + - nextcloud-circle + export-pdf-with-descriptions
    - + - news + export-pdf
    - + - new-planning-element + export-xls-descr
    - + - music + export-xls-with-descriptions
    - + - movie + export-xls-with-relations
    - + - move + export-xls
    - + - more + export
    - + - modules + external-link
    - + - mobile + faq
    - + - minus2 + file-doc
    - + - minus1 + file-form
    - + - milestone + file-presentation
    - + - microphone + file-sheet
    - + - merge-branch + file-text
    - + - menu + filter
    - + - mention + flag
    - + - mention-comment + folder-add
    - + - meetings + folder-locked
    - + - medal + folder-open
    - + - mark-read + folder-remove
    - + - mark-all-read + folder
    - + - maintenance-support + forums
    - + - mail2 + from-fullscreen
    - + - mail1 + getting-started
    - + - logout + glossar
    - + - locked + google-plus
    - + - location + group-by
    - + - loading2 + group
    - + - loading1 + hamburger
    - + - link + headline1
    - + - like-hand + headline2
    - + - key + headline3
    - + - italic + headset
    - + - installation-services + help
    - + - input-disabled + help1
    - + - info2 + help2
    - + - info1 + hierarchy
    - + - inbox + home
    - + - import + hosting
    - + - image2 + ifc
    - + image1
    - + - ifc + image2
    - + - iconfont-scaler + import
    - + - hosting + inbox
    - + - home + info1
    - + - hierarchy + info2
    - + - hide + input-disabled
    - + - help2 + installation-services
    - + - help1 + italic
    - + - help + key
    - + - headset + link
    - + - headline3 + loading1
    - + - headline2 + loading2
    - + - headline1 + location
    - + - hamburger + locked
    - + - group + logout
    - + - group-by + mail1
    - + - google-plus + mail2
    - + - glossar + maintenance-support
    - + - gitlab_logo + mark-all-read
    - + - github_logo + mark-read
    - + - getting-started + medal
    - + - from-fullscreen + meetings
    - + - forums + mention
    - + - folder + menu
    - + - folder-remove + merge-branch
    - + - folder-open + microphone
    - + - folder-locked + milestone
    - + - folder-add + minus1
    - + - flag + minus2
    - + - filter + mobile
    - + - file-text + modules
    - + - file-storage-connection + more
    - + - file-sheet + move
    - + - file-presentation + movie
    - + - file-form + music
    - + - file-doc + new-planning-element
    - + - faq + news
    - + - external-link + nextcloud-circle
    - + - export + nextcloud
    - + - export-xls + no-hierarchy
    - + - export-xls-with-relations + no-zen-mode
    - + - export-xls-with-descriptions + not-supported
    - + - export-xls-descr + notes
    - + - export-pdf + openid
    - + - export-pdf-with-descriptions + openproject
    - + - export-pdf-descr + ordered-list
    - + - export-pdf-1 + outline
    - + - export-csv + paragraph-left
    - + - export-bcf + paragraph-right
    - + - export-atom + paragraph
    - + - error + payment-history
    - + - enumerations + phone
    - + - enterprise + pin
    - + - enterprise-badge + play
    - + - enterprise-addons + plugins
    - + - email-alert + plus
    - + - edit + pre
    - + - duplicate + presentation
    - + - dropdown + preview
    - + - dropdown-open + print
    - + - drag-handle + priority
    - + - download + project-types
    - + - download-arrow + projects
    - + - double-arrow-right + publish
    - + - double-arrow-left + pulldown-up
    - + - design + pulldown
    - + - dependency + quote
    - + - delta-triangle + quote2
    - + - delete + redo
    - + - delete-folder + relation-follows
    - + - date-alerts + relation-new-child
    - + - date-alert + relation-precedes
    - + - cut + relations
    - + - custom-fields + reload
    - + - custom-development + reminder
    - + - cursor + remove-link
    - + - cost-types + remove
    - + - cost-reports + rename
    - + - copy + reported-by-me
    - + - copy-documents + resizer-bottom-right
    - + - contacts + resizer-vertical-lines
    - + - console + roadmap
    - + - console-light + rss
    - + - configure-knobs + rubber
    - + - concept + save
    - + - compare2 + search
    - + - comments + select-all
    - + - columns + send-mail
    - + - column-right + server-key
    - + - column-left + settings
    - + - color-underline + settings2
    - + - color-text + settings3
    - + - code-tag + settings4
    - + - close + share
    - + - clipboard + shortcuts
    - + - checkmark + show-all-projects
    - + - checkmark-circle + show-more-horizontal
    - + - chart3 + show-more
    - + - chart2 + slack
    - + - chart1 + sort-ascending
    - + - changeset + sort-by
    - + - changeset-up + sort-descending
    - + - changeset-down + sort-down
    - + - cart + sort-up
    - + - cancel + square
    - + - cancel-circle + star
    - + - camera + status-reporting
    - + - calendar2 + status
    - + - calendar + strike-through
    - + - bug + team-planner
    - + - budget + text
    - + - bookmark + ticket-checked
    - + - bookmark-filled + ticket-down
    - + - bold + ticket-edit
    - + - boards + ticket-minus
    - + - blocked + ticket-note
    - + - billing-information + ticket
    - + - bell + time-tracking-running
    - + - bcf + time-tracking-start
    - + - baseline + time-tracking-stop
    - + - baseline-delete + time
    - + - baseline-add + to-fullscreen
    - + - backlogs + training-consulting
    - + - back-up + two-factor-authentication
    - + - attention + types
    - + - attachment + underline
    - + - assigned + undo
    - + - assigned-to-me + unit
    - + - arrow-up2 + unlocked
    - + - arrow-up1 + unordered-list
    - + - arrow-thin + unwatched
    - + - arrow-thin-left + upload-arrow
    - + - arrow-right7 + upload
    - + - arrow-right6 + user-minus
    - + - arrow-right5 + user-plus
    - + - arrow-right4 + user
    - + - arrow-right3 + view-card
    - + - arrow-right2 + view-fullscreen
    - + - arrow-out + view-list
    - + - arrow-left4 + view-model
    - + - arrow-left3 + view-split-viewer-table
    - + - arrow-left2 + view-split
    - + - arrow-left1 + view-split2
    - + - arrow-left-right + view-timeline
    - + - arrow-in + warning
    - + - arrow-down2 + watched
    - + - arrow-down1 + watching
    - + - align-right + wiki-edit
    - + - align-left + wiki
    - + - align-justify + wiki2
    - + - align-center + work-packages
    - + - add + workflow
    - + - add-link + yes
    - + - add-attachment + zen-mode
    - + - activity-history + zoom-auto
    - + - accountable + zoom-in
    - + - accessibility + zoom-out
    diff --git a/frontend/src/assets/fonts/openproject_icon/openproject-icon-font.svg b/frontend/src/assets/fonts/openproject_icon/openproject-icon-font.svg index ef9977cb6c7d..9422702eb990 100644 --- a/frontend/src/assets/fonts/openproject_icon/openproject-icon-font.svg +++ b/frontend/src/assets/fonts/openproject_icon/openproject-icon-font.svg @@ -1,1998 +1,909 @@ - + - + - - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - - + horiz-adv-x="512" d=" M411 242V290C411 375 341 443 256 443S101 375 101 290V242H67V-67H445V242zM280 2H223L237 81C229 86 223 94 223 105C223 121 236 133 251 133C267 133 280 121 280 105C280 94 274 86 265 81zM342 242H170V290C170 336 209 374 256 374S342 336 342 290z" /> + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + horiz-adv-x="512" d=" M497 -2L361 122C361 123 361 123 360 123C386 156 401 197 401 242C401 352 311 441 201 441S2 352 2 242S91 43 201 43C241 43 278 55 309 75C310 73 311 71 313 70L448 -54C463 -68 483 -69 493 -58L504 -46C514 -35 511 -15 497 -2zM201 95C120 95 54 161 54 242S120 389 201 389C283 389 348 323 348 242S283 95 201 95zM122 269H281V227H122z" /> diff --git a/frontend/src/assets/fonts/openproject_icon/openproject-icon-font.ttf b/frontend/src/assets/fonts/openproject_icon/openproject-icon-font.ttf index 6d6f571c700ba13ed6f6f606ba0f12caabbf9747..95a24ff90fca2c2e7baf06aaa412703f69e572da 100644 GIT binary patch literal 55440 zcmd?Sd7K<&wLknkwf0g~y?6EWzD#$|zV-CxYuUnM=K>0$(_$byMvF7mpp^3e#evIE&;rEfppT2qf zA<_vO8Pl#{EVSpu)84sl$w!~s$yo9_#_qW5q!Tu8Eq`ZO3T0o0jGTlO>PM6Z@O=-Y z{iM^+x!};#rfuF~mzj^BV&*S)s#f(WuoWA*j?b2cVBiNom`TQB1Pd~va z?Ve)niRIY-rR`^)ea@GkeDfa0zWF!CtdBBWJKr_E3& Z%)6d;3xK*_2QlG8mz6A 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 Md8ghpJvB7^AAmpJN&o-= literal 90040 zcmeFa3xHI`nJ->dr~90Kzh5&wub!Un9_IaS7+|Iyh5<%i!iWmPQ$PenL_`FH5o9FD z!w`a~Y}Odp7&VDYT-Uh9CC0d3*Xw${#&r!#yoqs5;u_DaG5%eq`TxE;-7^DfUN_mh z_y6CS`Oc$GovN?Cs`_5_)fvVaV|F&c6xJ|p{-s^NxP0gl#`t)~N(bl6uWwrLt%Wwm z%1$BIf-A3CzVTaser=Yq)B(nVgIBG;Y4zXsq;F&_GnaA8`ZcSTudF`%@L}YA6VSE> z3HH6#GF(3es91B&=B+>Z*K-du7K<>ZZeD-wmCOJ6b0vbY$pOZcN!Kjjx>0;zXs930 zS=ol=*R0ax_YN>V9q)^i8?U{7vmScW#rVY=84FBjz+E|U?gV2NcJA$SZ(Hyp-W&77 z|4gPJb^O|Y`G=+MNxx!tlYIW;?cYKh7^5@Zz16~$4{>W@z()Sy9sXzh-&u*gqf{Gy z89OKMjhbw%fpsv^-7~X~xz;b=ynz)mqj=-_*lWK2>Z_KceB%j6K6=WL!b>eI!rItA z_G2-ie98Q>`ndL>-R9itR^2}Dd%pdF6@d-G4?|lbEIKnfRPJ0IYKDCGdN^8>P+19-Nbe-YOQk-i^gQO%U^7L1V)WVuIh zWz=#9yN}sW-a({nM@@IglJ~GLgTezSVGq$Dm-cm}<;y23QMq4}G~Ry z_*P&p-)0ZsUgBq9&AtRWZRbaf(%GNmj^5mfdJeOD$J`xfcQLa}2X^dkTyN)}N8UZ` zVO&!m?dG?$zr;1s?smL=a^(6ryN8)%{ypr3yaK-LFK|Ve>|{<>gkE2W{y7B7Ji%VX z>>c6^JrrQ2pz;Aw?pC~i8*)=GP`^+=fPyT>Tu7xJ`Lxke2s#f^KD@UBcn#ur0QnEG zVmvtjJhv0w@RTS?G{22S(F0@Ok<`Hau#TkCd!P_2L)tCCYBw-Ch`s_9SVE>5xa7xT zIeO(5S=T{~2Fg_=M`x~f76v6`jVz97O zk3Yp<LO+wVSPEyTR|i#2#T!vgg<<>E9gq2gr1GgepwIuf_!o_xB+;h9Qjn<9egilupRH*%(o$ZtQ7nrIK~B- zfDaOXB|bOE?v(v{8?IvL)zy&F4}u17fj<^Odd=l)f%%vC6Z{qab0I{bXcE0*h1e#J zhzG^f;#KjEIIDP+3Z+e%t}Nth(C!?k11{8;`(-=!0pCNwa~I!&9K=5cB!Ax}=K;0G zkUaZvzX)Svw2WP{t<<7?X_sMa7@YPHT1sP^_yo0`sDA^V-YU~*{Lv^O`sDhBUkj=e z-=sHhhIA)MWbm!M{3bj*h+mR|#K#S(g?R&<`a$V~KQ;X@zv@%dkMnis zrRQbnVZQ!T(~t9OkUom(C>6INohVQ9gmBN#^ghVSPxj$Lq>i>KKRz}fb+qh!Tjyi+ zQwe$bM3Uihq>a8$bMG*};uC4d`IYCTNiCBvfUG@#?5#!0XlXP{uSbe80tug6ASJE? zPeBSeN)`C#m%uGQKf=*(3Z}ewq&n3nXm|X4mCnCHs&SfqUe58b<0D(6&LG zZ$pXHV&aK3PD!#1AYV@2VitdN!J7w=bN}!3=C2^De{-EA#m4gWL2hDR*<-|uNMojX zOmdsF9vTmj!)S}=Q_CG`0dPJ)M;_;q99$qrepHXG=ZLHcdM?v3dx_r?CbuA!^x+)+ z*~ge6V_TLl|2T{w2XgO}{DJg{Q95QZCda-*&q)6^BYg*Qk`_wsq>)CN!@pttjmtO8n;AHeez}jU;OB<4cSD2h zVQazBAApQJgE8mg6&Q81`7*u<_&cHN(5N<~>R4@rw5&Y8cAHk@K7| z%j0QB%K5E!qgQBF8uG;_?+6261B=zf%-{ngbIV}Wu7{LA30v_4?&A%7I$r_{aX%#O zN&XyvgTDt^8xmDwl9(-)hz(+g*e{NY2gFIp+~>tBY(6v*vffA+A$yl*CeeYe2A~7b z%##`t>{9PYPD3vvEs`jnvu%OT6wEHly$h`-E<>f|c@J^0Lu?UpP&;UTP|r~=Ln|{h z(!H>%-LiH=Uo&`d~B)b;_P5 z&6@Jc8N@C|n$#tcn(J#e4`~nMBP! zY%cD|YS>PCBU>s*EIonF#4cfG&`VlhYyqxmmeD&Gfx{3lJOF)>u8;~n*@QDF4u6ji zRznxY-D!JhaH5U*6dDOGc~6|*cy0l{M!AQf$(xL8Y3uf}o$P-00(*~pcpdNI3;B9b;}Ac= zAA*+q9DkXuVj;o}?~pD{Bghy@H1-V(B`;a11*@e^Fg7>Y5j0Z_kJSh#h2;04Jep&K zXI^KexwuE_!o+0<*(RB5tdzYOxecqsXg@e0yAHGZd|7PFY8u@{N5brSIcLu=$>5-p zs>pGbVoQ^Gb5ZsJL`FNRaqxq~k(@d+7mrD zMhG3rYdS_hVxPkt`s8z>HY{JZ9eq1i*3zuc`&M>Ii;g(Wg`Ge}LTv z8eUKryAkv`FE87Ml(BUV!iPaAL}5CTjJyeR(a`)zW4{ADQNuHX4}sUfx1*syi7!$= z46>WSPw8EZdbStWdCxJt>N4LT+mjmsdl}YRs4R9X&Uk|*pc`yrN6}NS!td(gHPCie zqU__)bzb0a@(+a#mQR!Df#tInn$96{uXt3P5-*E0;$88vVo^fyFEl9aN;lR`e0bC7 z9g>Q~S%^E)oH;PkhmGKTH2P^&5U(+0&lv9uk4tTZd_knE5l5zR`8l+Yyw!ueT0W;z ziT{&TDtQ>{AsX!ACFpgkk$9z?E69@{L4!Pvr-n`{r5y4bT9KhGhA}3_wt;Y<7Tk(@ z%Ox)$?b-0$T;RTIbLMYD#u}XJ;o|g>j3CUUU2fDHz4i8erc6yhCN`+ zgliSg5V>FSrPFlu4A)Pn@@$4h~E?GA?D*ItB{SM?BoBkT8Mm&W^htv_+ z>ykqd#^jmZ$9{koyh>FGVYD?iMqSke+Q;CgW&gp zhLFEL&i@uwk^G;gBe*fY^W~8|q_L5s2zs6R>%zJYGq05R7okse^Al9oZ^ z|8{tv4BC^;Nacb;EHoyKOexf4cCw;aAGYSv|Jo znQ~T-E$b4QLK1-H6xZHD(5j}qgO(bRmiZ2(5RFLJB|Ua8aJvnZ zH|(7QD2w?0=P{;_(h9orRmf*EV`jg25%-6UGyer^f=>dKniZse%Fo=@Q&(cn)ec=O zV+i`O{=Wm+;PT4<&;tGcKAija-?a>7;Ez$CQHJu5h>ZaJu66%u@|`>P`?XVri1?LQ@M%BARMz-QO-`_l9LvS{*rcG_+zwfw7h(|f5>?hm*2*Fe%tdu4n9U3K5dSk8~#Ju_v!C^R$0_9 z62ON)*z)1ij^4zP?y)E!1V%-4|MJ{Mb9%x@a=vo12 zb|FOBL|6f$dx{YIQvwYt20v6B9*_j$DN<}4B2{XDcO4>38dwt|E?VImNh2a-0wOCW zvdQp7XW&`wf-kS`NgV5X$BTnH6q7IHi>%9~44|l=lxCc>Ie+HfY&k@1( zW$1`sVSm9MU|&Ua*hA2azrh|woYqNrX&!@r=W+ONo`CP?NyKbCg{Y3F5qEJ4+Vl4i znelx@fjkeb`vvy*(8*tduKhCmAJF{&C$#z>K)?P+XrBMX-hhqs&+tV32vJ-Ai~X3r z1z*#@KqLJ*yj}kaKh`hdani9K_HXP1tTcXz6}OM@`~P5#?JUc(bBJT$TyTY(p}}h0 z!mWt=vU3M_Vl~VSZ-f{AK|gfcAP?~{R%Hu#6p;_b&~;0B8ISQeuiy!ugyuVrSMh3I z!)xI~s)ruj$eVaGBBojqCz0mkkvai>#)*6qp9~*UC%=eKLG)h_p9X)&41O`6#pm!# z5MMQ)_wh^lW&Cn}1^iHpunN2wt3OMzDz}`kfM;YCd{bA!S9vvG2jBEHh{w7XzN+i6 zX15vs%Nr4=z_7~q`~BRE?8gt^dF;eJcmIwr-oo`AT$E(`#VWjd4_0+J3oBm)6S2;FP|SwK2QJpp(z z(=`LYm6;Ajg@62wdE*lnHe0jvyXx~F*V7|x{zKngLPo&g|_m`=|CkW5UcX8_13rqeS3q!rWY z831yN>GTW$3C47K27oMMIz0nGsxiIN0GfX~nl~i#ojnpt-2iI{=!CdZPi5oJ^n}+>}ERE z0U%vO&lmuC&UC5+0LjjDssjKS&vdE-0BO&3ssjMI&vdE-01bfYJqAD*U^>+YfL6ft z=>|YQU^>+efTqB7sv7{Ef$3B?0NMl7scr!D2&Plr0B96Ur@8^qEtpPq1E6IveXaq} zH<(U%0HAp=o$vra2Vpwl0U#c!6CMDz3}?avK>SiCJOIQmb;1Kc{8A@80K_kK!UI73 zQYSnB#4mNi13>&zCp-YeFLlBLK>SiCJOIQmb;1KcJW^j~0P#qj@Bk2x)Cms&@kpKU z01#i)2@e4AM4j*e5MR^@4*>B+o$vqC;R}=F_}*I0ibO%o$v!d?_@gR2Y?33bixk+ zU6kpB9{^e@(+NKS^i!r2egJ5yOeg#R&{>&I_yM53GM(@PK#yfQ;Rk?5%XGpI0Ns}9 zgdYG}F4ONYfZdBT;R=A}%XGpO03Dd=gew5rFw+TF0Q6#}f6)MF$V?}^0nnA1PIv>L zH8Y*?20(viI^hj~Ce3uh8vvb}>4Y}`+BMS&ZvgacrW4)(XxvOEyaCX?nND~EpoKI2 zUIUC_$obbh8kYydljGqnu>JAmn5Hvkp^)2W>R*al4hrU9@Lm`-g5z+PZF zwHW}*f$7v{0Bi`RQ=0*>CYVlb2EeXhI<*-93xny@W&msrrc;{%usWDdZ3e*pU^=xK z0851F)Mfx|5~fp|0kBS(PHhIjPGLH=832og>C|QbY!{|en*p$5n10Ft*fUK3t^u%Y zm`?2nz{X)ZwI2X$hw0RQ0PG&7Q~Lq1fSCTA0kDObPP729H*qFf0AL?6ooE4orNnfi z1pqb^(}@-USWirU(E!*{OeeYkU{Nuh=mLOk#dM+z09F>$i7o)xTTCaq0AP7Bo#+C9 z4aRh$3jo#_(}^ws*kw#7x&UCIF`eiFfUU-Kq6+|48`Fs{09bEKC%ORSHPHnCn~v!} zGyt|8(}_j^c}+9|z~W;%(Fg$BkLg4s0IWc!zi9yML8cRp0JP6dCmI1bZuOrSfOt!$ z6TJY4I%WD#4d4pSL^}XC<4m*zkR_%Q?EqZE`DX@@Z(b)l0ubZK^j{c&xJ9NDO#$4F zGtm^l9XJzB0o;i*(GJBQ6o7a}rV~v8h_GZj(Gkew3c$)D(}|`49>$sI2*64^(?2$V7vM}Z1z-)B=|ociR-KtXYyeg*nNIWt zV0E17L|*{bZK>-e@G_i1UjiP(8T2LKahyS40$zc$$pEbIvLVo#fG2SVtqFJ~&Y(2` z*0R06JQ0O4T07Kyas2`nt<2h3|bRl)s+o_)&y9uW<#Jg0dK$=v?kz< zID^&%SnFj&pfv$jdf54^*fVD0*M126@GjOIp0Pu@(P8q;w;Y|Gj;B#=M z{s8bxaHjqMV5N->QGWpVe4MF20K5-p>JI?F6ldxW0KW`p>JI?F9B1ke0KWof>JI>4 zh%@yE06Rw5P_qHNA7||-vBmL>)8%~CRp#n)J%)X~{qB>V zI?qF%XT2_OlXs{0KJUxECVzKeLEuo}xnNW9>EMf@V__C93NHxX5q>{1H*z3yU*z$~ z3z45kvIP$o&MW*N+7jIqJyDb?dbHS4+*LBSiz2e>iepP zYWiv`Yx`;kYoDrpvu}bwlf__k5Bic7o<;&uNwcv1k;4$?G5eEx4$#7Z{n#*HIt4{E}#5J zrX#a5b9ZLwqK1n$T=aa`15*N1x~6<%%G=!=yI-H$H1!)jtY==&)}CjkIi|fc{n;5! zGuF&FFysCi+1|^0U%z<6#UIVwFe@}`|Ewoxy*m4W*{{rba&Bhs)=TOxd28N*d5_Nf zcz)UZ+4I-Vzjyv?eU84azC(TY_PutgD zX;Ea+1N~k7&o7?6WXX~Nxubgz{$}2ZrIdJ78SH5!P z$1A&69$NXqsnzvxUiXbnmQDLNJ-un@`X$%Du(@h;|K>xRPv0>2h7((M-ni_>C$@UFuGxC(roc^W zZhB`M+qP+Y`SyL=-`lZr$EF=8c09J@#T{?#`0!@a&1E<5zWLFc-`-iYvufw~ohx@f zx2t^D<+~2;IkvzTbo^o0!`)N8@|iih7+6lgzt+VW?%U34Z}ar{@v#9i_mvAXa9jWZXS+r zc{%$e?|C^_?rHSzX?PR8@WPQCY(+7x;dF|pv~WBa^HL4XS~wkS_HwNicdhX>&ty+! z-fnqM>BHewp2?hJufEsvc4j#Fc7|tOeNQ=o43u*A5lZG6A+sar@WS_ArFT)0Y?z`v zPM*dDm@~#psFY(h0fR=>__FMiK8xR9KD*=rJ`|ZB4+b=kg>QD()_Ee9k|)HnB3r;& zRUe>Y1jgxG%30-AP=;hGMy89$X&j~#{&Wd%ZbIRmJkcSVn?hmDtY~$3Oyk$ho0YYy zuci5meVNWljq|cE7xhg0o7LN2>zN)@&))01>Wh6{+ZyKa1|&au)wXM{o`&=ze7|FE z=cK6xk?QtC*(d9!%~^Rx{|%8Z%^jFtS2cbc?`WAetF3j((k;*j$gg|Opm7)!E+xMt zXx!TDrS3xK;f#)yXLB&tif2LeXG{T2Ph~TwvZqe*Q>O&Oad;qmii4P($#egy3?Il2 zAj<$B7{C=D$Ye4CFg%cv;~$5tvKb!UQu1PQ%*s@xUKMMZ7(MQ^SZN|1U1T~NwH6S>hIzZ-lrl}>4S z2>a`}7R3BZx1^ifT2i_8m8n5oiEue9htU|efN3p zt+>~BukYmA`?a7&l&>%6++q>W<(e%za_traM$59h`P0<$;a`^|Tvj2<1eO!I7A|g9 z)!`>PIxM!fLntm+=z2a++M<Hj-z$SRFkl_{qc34c%yHA((f$p>i4^RXR}MkkEii>X(y zyzzz`Zd`fw)R8Ox?aca2X8iyi+REB8ZDnQYj&vE%R$f1&CxV}z8P|_qW)C9ky3WpZ z$p3Cxy0kRinZ^r}zUN@{Du0jFrU0!7B@{4!3|_8+QOBA(cp^@+*4wPScQpHsuc5(5 zC#^oIOi$Kp*`5RV*~BBl5{pD)+4qKr$|uI-6YCC4Co^8Imr35zjh@sXE!|kLg1q!Y z1qlPp&B3^t)RAUyoC7ZBBAeYTULUUH^PYV+JCm-~c6BLF1G-nQk-y^Q;RXU)i$mF5 zoB;{c2D-} zXvEQ@)Cl$7b?XM#uDwnE9a;yI(CGgY%KOTR91iEztb8XsB|C+GXBz)n_Ojvs#=j=M z{>xwfdid?1@UOl5ZuYXD@Ow#~%Kjat$tNgcf+K7!jL?BzHS`XKh#Smw2;UgxREi{l zK=gA@o4B$KBgYSEose>~q0t)ypqIT3jdW!kV>m0hXAONX@r;28qO2T1#NkAzr2zu-mb(zCg7%Fxb6!<%8J6l^jYas-TK7SK^{yJ6> zXV40uoZ`?$T1VSScz>du!4i>gX3%J1{#eRmY2p!3m&D0|fkLkxZLq0U#U6HZv(;x4 zCbV<|T51wDpGD>FuwAht2XeW>v6@K3)M%~S0po*YBCZMX8sdUDHgPwes3a?Z8HQt{yFRnhmR}K8q4vB-#U3NU=sP6 zqp37^Xx_}`eZjh-DGih2VO7;En#E)b$;ksY(NtNpwzjg#m^{K20-M0(fl3yRPx7ax z7uDzHPHzX_^iW42=q&UVcpd$iJnlfGMDZ2d3jM{VSp|uy!EiV@HBm6jR2&N1FnLNM z0XH~Bzr$N#aTU2D5#OZhNzEPGwn;k- zAA)IqXdjnqA3xDvQ@MFUd#cKsS>*1%LQx6}`s!SEyQ{IhBp56yZxmidbxo`;ve|?v zFI};sEN(Ihp*lp*gyy0mp_C`5I?Y~Z=JJYcnHIKeGjX%UHa8Lv&vm%9xgs;My3+46 zcT^>#PFJd`lV6;%F79clOw=hn6yYKoxp-zIs(6a38#uSyOl^tsaJW3trm6_-6RI;> z(A+eBVr^4Em?A!tzwd@_yZu4UWwvDB3Kka!c~Qg$_o-nM-=hpb&e|zXCmm}F1yq<# z$(A;M8sf3-(_-1gXCTSOpgds*Yw>;!w%Yx}DwEFu`SzHAZJTwDGR*PT@w zq%QrtXwtt;dFE%6qZ)Ja`re*`NTi^rH+y(gV@9J5U6X8NMQX}1Xd~qRhwhhxsvf6~ zY=-SbitTSsAot5~W=CO7VdePol{oGAE%!?QKnB^yUy?4Y$-e#R*V5>o*j)euL4KS&t(=1Y%7gf= z4vGVk{>E}}h87r_#H)gf!6o_oC7;^5dd&xGR&ULnvYGn!m2=ij z$lXp@H)myg{qK~d^p{Wc`h4Dr-Nxz1Ce0g8-JMG;zdIH7YNm7ScTc7Hk=JSaSs5%H zVu4L1f*h~p18c!;OPwHlS_{X#k48H??>l+l&M8wm14X6YV6djHe!+FyudV6w9my^b zecfH1Q>N_v^0)4r9DwBa*Ic{(x&`%hHC+qu=Vz!cl1HbNqoBF;W%)Y7Z>Go`mMEbknt)1Ll7l||}m1ke)r$o{4TWt;1sdzj- zwXV5YlnlQ$yQ_0Ww5X_{xv{e=`%orV?-|I!H(-1D(d1OzDpH2Q+FZhem=a3%RCf3o z{

    gTU1wszpD0Vol+NrJp7@Vzx*FkNAYe8bU38_@n3Wpp#$u&Z5Ur}SoH~tsiuXFI!+U(m>liiIMi_I zuL>&hbTY@!H1n8irLB70p$89*tL_#byp(;geop_K`g4P^SSno^=W~pU3Nd}z{OMEY z&6_%X{<7g?V(qfpS#@=@YKKpKI~XrYCW|TpfBo%XMKqZxNsV0gYB-FTe9+a%-b0qw7Lb@YMt}@kOe6C0mU5VT zBUY^jUj*JwYiX!#U^93F)6<1X9}YqLlm0_FU(q`n{5#P5B&f>A!^!LiTqqWg2X^>+ zSisJVH{^9#U>ccK#pDrYr%6QX+Y3TPit02eUaO+wQ6^KUz@Ri?j&f0GLVEkciqPts z-m0qJ8any>+gD4!Q~B!n#By-&=j4wvcNpXtE-Q{jVpfkuScV762JChXc39iauTg8eS;e-N5c1ZhL()% zw5)^`B7R1$D`B08#{ZjG+j$*YY%SIxY3;v>RQdpkaVcetfo6C|0@6AlK~H{W@|r*) z2VaKn0j{iu(SG_WN-6fdkbil3-@Jy##)f%)&*U$bU$vzF04+iu=wI^E(nZGQqNPj0 zluLubuemHwIuw7214pY}=|1mOS;kSkxoGK27Z#Fr1>Hx9y&rW4k6MmeOCyT)sIA1X zgN^GT$RTto9<AV zTrsn^rna`GcjgtB&X~SXTc%#Ls?v6&+3Ii#%eBscE4zkI7Y}x>yLnxwvP{&}^v?Rr zS-sV@<5IWJpRhFj_fB=G+3VLXpKo)!Z4YF>jYt^-$Ey@SMp!dNs*mEReGjIjqf#$b5*X~@` zp>>R_t-g5XNov@*)V}$XJs!061*f(In5tLIx4B%l;j{e9|AVH2oDctZ;3^%x%5CD` zuwv4V==+&cizTK=3@#K-qSHZ4a+Hk@dkhS+c)<%(BZC_QpY%PAhC1maDPt+6B?+a) zNKsOflEsD5L`fu;r)CX$f94hAD$8mW4vOk_(EVDAa5}8&uOsCV{C(u5W8^a9jz4S+ zv#MF85zmy1M@E|L8Jk)k>sU8Kb1tQkGye+J?=|oDz)>HGOrS$7Qfb^7YiR#JY`395 z?}z?uqJ29&1^Jlp#=>4@|9iu4D1qVW{Qf7z`|qA*{mS$whNUf!@eG~&3A|&4wMFYW zF|5$jLVX;DAdM5aM1s&yNth~ea9BezhP0Hz@qT{)D_tl(d!J}KGHKPshD)2Dov?KL zq}7ugD=I3dq*7BVk5tl{m@@E6<~`IbToYGKYF*rEJ$6)?eB}hZl0DMfo9doJndVHX z%<=Zq$}_-8A>IzZR8XO|v{KLjn$zqRxAKnl?^2ukhk?Np{jV)pAPUj2Z_Go>vXAnu zG);-WpH{wya?H>pV&rj;b%H-@d~`k3kYwZqlB=SrCZ2D;mw&_I=0*$sq)IH-?6OHZ_ywY7?skyUvviwF@P~_l4h9Z%Ya+Lz?5kIHY|lO|l}^)G5NG$f{Z# za#7$xHCKbM-N>634uZ{a-vXaUwTLxyCxsPFu}v~@lcM%^Ue(JhXRn>qZ4s&vlWg!T zJ1vv?)(DGYv%0T1xcsW}N${+PivOHH{-g_9PGG{shipl#F3|F^YH`&2?LBjvCfULJ zx$1j7JM$}1yVGPT{|$K&Q^7lyc@ij(U@ zi;B zF!!65XSlS$h2e0|b7D8S7PWwM*pnlgl#)cl1paU|k%<1PYJJtW3zNyh;WO8hdr(oA zA^8NKsA{G}vd|H7dF&^U!s`RJ8oL!s?II!+)e>as`zWg4HiwD6jrkhI%KHKR%wRrC@gL+Oja{KVqP@2sDO3^Tj8a2 zYbLwdEbP9LLZ>#oK`Ba&PnDJ7@T#*gWU)E?VNsc``~ku_OkSvYHmluc8&wrx_}Z2>V%X4q7APe2LUT{e$Mx=SO4g^^NQ+#)du0&FXYGv=s4( z{~9CzHAa5h7?D0O@tQaR{giR2KeVZx!Vlfp{H}E%v;bCQ3p_e73MRvg%J+mSe1Q_z zewWqaKH&`5d?hZvILmC7H{UjEf{A|kXM(Of-CmF1{Z*F-ysxvw>eGI%o1AJqWBAD`@wZx%mylXKa@DKLoLU^CDqs>^D%7=$MO-TZ|UP zMwl+?ycDlTTos;MbX-1WkGuqwhGnc^Og_aDDS10{=AaBsb))ZPTq=n~h=Y3Gj79mA zzN%2Bq^hzs8gRH8r`0s3s)Lb0IP6iAV&wclld^ii*0*Kqwk6 zDX&;tSDcCly$OfYT-E;dRg0!huW3MDaN!qtR`aR>n=9Zh4Ua307E~5ETn@X_W^-g( zCq@bq$+qTnXMJ;lqKJOg0W&{bR9P`09D&JV3Hcl@)n@Bzof;`lRZW^OwY|pTw1el# z@eG@Oh^(13%)5uhL({}V!wc|CE{eeS-Vb{}3h#S6)&}RZW!UdNfENuzIEYsa16YIh z57Iz2UqwTi?DEg%n=KTiEagYL95$hHo5HX zVA-vJz?d|pU)H(i9O!3YF_38W1u6=QlGz$17zq``lwi2A?0Ki#;fy*8><~eo<~bI> zJJM9(scXtk$kmFf`J35S0}<#jMUkkj>dV1sk;`ohS_>i}i{mjz;h1}LNzP9<06i~; z7}SZ20BXt)0m@xNT%u|vhJfh!FE|JXWV%Z=1Y`(>a= zicYkx18u{M!lzRN`H$TKHd-i*6g(uc1TRi0#q+q~qylH+Q=5h6H5%*Fl+JrBpP+}P z+uWwflcD0>cCE#%R1a7K*1Z+NtX;)t{j<&QFbDxD_QTt?0B-Z7a{B$6#_g7U`z&^D zTc!GKU%b?8zTzIMS6wA-od2uwhh9iuWK&*&?P!&eenvc=77V9bVLrl)$zM6)dO|cF zrL8@F{MfM#8#X-m_~TDJF*rCle1G;?e8{Ff``p`azs-AA9$UTo*s|W<&}?RG8J5i>@bZt!(LvS%ZL9cfpMqA z;s|Ao?V7!Cop66L|n%G=}d1?kJ3V>5qh~m4Zy#!p-D~^20|ju&&ldf&JvD$0Q*S zMO#{v-g{bd%Rl09P8-jfd7`Sfzt&{YU^kjnQ`VM~IVgw{^9=dvvAQsw%w`j7PZ}%nan?3qGgR z^-b_PIV!WDQtl2;xpMse%dG*gHGs-ISeUVT1J=vOTO1C{B$LwLuiRD;kBd^X)n96|jwj*=C~)C-KDpqUj%>rj~Q(&Ygga`ZL72L=gp$h7WZ< zR&%kR&_5zjC-QJ^jqVzLP7aWL;aX`jJc{<)N4os;Xpo3ZX&;%iOs|9nvt*oyD%m z6NpzVps(UkM845DH0?aS zZZw^E4eH0?oWTDIGwSz`P#I*;k=MZIyqm+xOfq@V#TVhgzmURpW|q7@k)+d1I*6sY z#95hS;v)GNSEFg?#o3IB7bn{y|I5d$DH_2v6hK3O-8u3H5i_UotCZ346rzXoHjN+A zpY8aD%^G~01@2BW4KX>Epa3Fjfv5=u0cWWZ;z=@2ku=hu)r@c|Eh%?IP>7pc)kHpA z8XEUx>;c18tyb*%f_jC_SY}0TxmukD%2;E=IwYUl(q_ z5JhW>icUJ_0c(FIpn#>O5ulUH7xGr^3vA1Y(S=r*aWx~?FvWf-ui;F$Q7tOv1$Hf)X>TP8m z*#>Wk*H`R?o9}&G;cxT`u0iuo0u5vOC^DO~KIsy-x{W&npuoO5yDF!7x z_9i{{M%g;-QMOVD{P2SA?ib}>_K|>VzY|e1`(1$-{qB8kzdXD&nyT~-d&K+u&f=>I z{B#!Eod{MtgTW%d|A)w490+VP?$8Ms-~Xh11RbOlHyV^(tTxH@c=SjKLY$%3He;mH zR#D~seaFi7)r5Ms^mwuj(TJmd%G4tMDjc2_5u_=FgJs9|Sp+V})n;1?r%q{bgo^mf zLRhBW&{JsWJI4C&W%y>&Q}m4#vSP8i3l}yt=wu2S2b2ow+Lk&st#`xAO)2C;#)dyi zq4jY1xhaKAueLOt3dXuZ8y3*T{HZF@$a_ueapL$2o2$!iFLIPQGR4JV zZ_*Qr7q{WA(BT*#H22bK@ocBR#esw}M|)v1;z@cUC6NvzOSi|=k45S1qtV*J!aCTi znky>!?&5I9s4C-87kENJ?*glLyn*oeI2Qkaa4OnjWNCM5^9bR7 zo3Fz_xVyrKHhIGj6xOzq9bY(Zg6MSws*Jj-9HutZWot7#D-4V)LZMNNRiCCM?Me$_ z+^*Rx4UB92UWxHq!ml|Yb>`8r@gFcQz>|hyxvMry?0rxxhyh1QdZqK7k8B& z&%8p%+DKVhWRtsew#QTHt@kV#*J@-*^y9A5>s{%$4kAl7lhX0}nsf}nK^Wx3T=)Njzza-=S-k z{s?1D1v_a~x|N%x z#c?WX@)Sk9-!%sdg66+eREOK^wktJ%TcehiIo0F4GJK;q;-vgeT0IteLA;>4)a$~D z7ly~RFYp%J?Qpvt*=mc|D=#kwU$ z(xw4e$&4vkOE6p%sOd@+Bz-QEX5uRr7F)3-?sBj7xb6OUg-9lQD(V`7jiFcwDPKHg#r*wm|L71&%McT-b| z-=|??N_R#1^s*+4$!c}RgSD#FUx1|{Uj*ew_;(-TDwbyXLmf|Kp3E5Q=dgY6$1Jd7 zD5 zv0rPN?8iT2@O3oVeByr2Ds8669<^F|pK8lKW!6mJD4IF*p{$7)2GemZbcnwkvX-So zOg)!9cLKN^geFHiQ~~sGiedpFX}20de%%xOfpt%?Zi$d_hhA#K7C<+-=AjSWAvO+= zK=#!o8YrMO98$x6ljVt#I|RR5vOiz)gvI2GsD~P~h)*c(%d>AR&kil=U26#;&?SA+ zA{;@>jn`;Fr$TooXfoV<%{$hh!(=&`wkXb^vHTVRsHY*?mx+Z^E~O{!mZ0ssh$(|`rSMqtsi(Q}p5J};5EKKavdQgl$-ZkV zbd-9B-wXy%1Y_~&nrKB?kUtp6IEtTz2QZA7|e)a5Q*4?WIDbd19<>Vvg4-saEnkheKwl1r+c__xMJ2 zhzBY*;#%ziMvfOHPWe%v(qA`s&|5`4|t)n!6^^Sy6#} ziA2X=Ec^Pt8R9XxGyZDJw!IJDb@Zp1E^(62ot6FBV}Aph8NSV|vXY{Z6L6qoO9k}y zHlkSA4^O-J*w+~yek__wMa9f$r*FvT8w?gFqT-IiWN|QiI@lg0+8gCi%w7yPv;_={ z*-}p-&4#Rld=xQM*m#ULs1C2XLdBogpC`e0P0Axi`njesVhw{;N{!G!E%2yVT`FV2j zV*LG$JmNz9EPq9LkRYGQD{V0k%fCqO;;ej3StvmsxO|pFyev%C6-VJ2@q=#L!b!zfxFcDX4e4-Ojo~UxVUz_?!-xQs8%4kFrD3# zoQOf?)*it#5_#HMhQBgPEat;snJE@e6N_gJe?@rY4YFg|=iE=B1H2ADJjs$yaEUqa z8()o{&VL6;?#qEfCWDjY8m{~zgpAfvK08d8Iz!+CB~aJ|HkuhR%x!RZgaT&6h%=Zc z|6oSPq-oP8bsXuKJbn818P_ac)Y{gD4-UPNzu1HI5ZJRzU6%EB6ZR;sw_&dE9mUS_ znXA^+4j;)~2!}0dUt;qYS(jOd-S(($i9JBq;=V+D`{%dC6N&h?&u^bTh>sa9`6rZ} zrmq_P(-K@{`~A*tm(SyLQd0ndQ#n>@&HGvl**(iM=R*ilX+> zOCr4?8_p^R5EIIb_1sjHQ^;o<7Q_+MK#DHKdV=#9>_n1K%wDx{!A+qD-hAioK;QWG z%q7#NTr#e5O3%E$xzk(QJ34PzwPM1=i4#_=R1VZs-?dC+kMY%F;^KnnxXS%s>6ubF zu4zNLFMtfIe!gmXI~KI4Pyf5JRJjhat^~3-&ARbzX5x?xJBS6gSdrI-f-JN~e8NKp zoTeKg%fhgvp=U#gsqwI}g$8Z`W#q~~a;4CipryeQ+Q{xN&ufNQo#rj26Kb)QnB0Y^8d{I9)`=WtFAYTLO;akSu z4fl+_6Jga-XkTYHyQB7XuIxR|HMXcnv0r76x^r{nzv%hLqbKY^@Tm{Q=WsG%w30Sl zfEkktH>b#XMi!kp9gHW)9`s_eh>lwk>zUmz4h(NjiH_lC#Qg7khqsMyotQ{WYUTg3 zQizW1Onz`}NGwVu(~~FjZ%&?^Hf$~B*Gfdn8rn~bPmPeW{fP<``099{_{#9&apIEU zZ)Wd%_E~<>g!JT8YI6D?_)M`c+rjVN5E4sLl@mHU`FA=yC-52BwfL_LhOhG{V%JC= zpI!qT(4Shm*qNQo@1dfTmE&_o6L};r0biDT17Rt{)Q7ywF%Ak4!IB;{S9r+~(K`1x zY!2iP{npKaSX)GYWR(rlkI($Z#teMd0J5Ery%FP^SM~3!IQ3ArLsX1j^QVq4UsPA6 z-XA%h9naT}xiQvJjqhj`(0BOFUQ+dqxOk}Ez#lO{(*CEwc_>z5*B~rp;bqM&jrH^TR%U?<$tYiU!(z|(IE~O$&{{3?S~;S{m^huKyF9&(X9+7eu`GU1V{w?lGG^Gzl7)=K|Lwv5R+-7a z%b({j@*nfJ`M>dx@$zSFVnM(|tKrmu`o6^`o1%3>lW;&#` z1^q_!YDh!ePpB=WlDU?I)KF;yj7o7pSS^q;7z`XLEFBg^8X-lodE~m|}cD zYW&I2SsE$GL#H-mgZ3+ZDq(~6u;GCvWkF;tSU6q7(_)CLWSr_m!~>n^0{sV!a7p|6 zr5KQ9A?(X=)8H;;q(GKns{>X!aAAnRFw|@KZ&iAks=&s64hjIHWE+}~3bdAFN)ifn zgpw&Wq_xD=P>_ZVnnDNwIkZGemIr}1Fp%;LRDz<9R>%!#L0N7aob5q~+BT!@O*HI6 z*j5qH+T=&AF#LdOt4pNRcpH|ygDvF&YCXCCpiQoHX#EAWWg5-5SV91 z)$yh_ikVt;khUEiT(tD%(aV)44dJ|qhY2b8)|R4}EQ%&99G_^xf>!p{nD99RjVstA z7Z6I!<*`5|iYnY`D>e(wWOcw7Mc+)ZsXmixS6xuVCoGoSxMxQ@m5+;x0Kx8() zC5P|)2uYgPKYcUUa0PHO+cme};W__~Wlv6!ek-GbZ93L^OZ=w3xL`OHo; z9HaIa+Ge%793gJAt9F+KAr1KMolPyGp#hUp;cnIH3i}+vV3{9Px@;y*@fQYFo5P|a zemsng6}@h!&tZvK&90!$XH(sF6(b4GTWqD!l+ct?kJsW<9TA%aTPPj)IH28R6{_8j z@xlcfp<)=rm0DGK_%d(kr)Up)oVrCr2ZCdQzVZiC(A)vc(WeS3z=@k27-bm!X6^rF z?_I#-sLy-h{m<;q?0skN_xnwk)ooYO%CaP{Wm%SGS-xM8Z^9VIxGph{V~k^n;(+54 z$8{V+sbd_P=FpT-%Hg4o>pDb_L#az#LMh?6#HB8Wl01|Wpm}mA(T>00`=6C$2x-sh zcTUgOevx)(XJ=;T^1r^b?E(pVf!i#jHY1@4*GTFx+G`A3UJUY%=OCZlytJWeN>H z{Gsz)v?O*1ny&FBk;fo`9|+E@Y=SPzm&6;u0iJ%ER-RO!oL&>IkdDiA)vukd(At2y zxwbNGk2nW=1leJ{h-=XDgphQS^m|JNSPQg77@0r<^Wtjcx3F#Md+h6HHmYYYzx2}K zm6u-{xtA}6wF(k!+EEcV{2#!AR#<$ zGB^jwVcri?hd8PJ|Xp?!cyC;|H=^ivU zMMv5tZCjBZy{K(bCwo8E)AO+dv=F8^A_QMNl!$dHJ#{0AgfuW9B@!cbJxW)s!Z(`L zy<`_)N6mcWWbNlT2fBppT-1or^XLrD)6}qD z_*pwjfLemk2>i{-iHqvcL}gN#n4E&4Oqd|{uIgB2@=Q<9&!*wlgpK>2RVOPH2LKpU zbR<3|VP92`kMFKbR`_jTe2ACO#t!6e@w{@5#z&ejWi>+=o(;7?3&NGFc?jKFf*0@c z_jZ4dJdC+dHui`-mpZ!h1Bj}9oL zf8R7ZHqumBIyTz$ja0F1u&s^#b!|kPp=RPf74a(W&!ek@WYvKRLqOzo`_Q@mvfo{^ z%wwcUK86%1YALyd*n$oS*=RQr8;}H}-80$mDD>c@Y!&M^ZXRDR$To}EzjpJsiXgE| z6KaJ`s+FfEo~o!YKu%4Hm9@peB3_ShYa}}jZm{?0iBm{3wismjxuf@;d;)9)7@gIL z1J4{1ghS695GJaV?D4Os+lmX@+WruY4q=cUM4W=m6@^`AsqQdUQvt{g!c8F!k-$Jq z7`9n0U>Sqj+X0SDIFne%KR3`Z`~XrU^i}#q>;+V8NCSMI7f_sB6q!C337d^flb@i2 z*Y=U)8R4E-Ks)DWE|;#mguV{!Lvm+h4e_uy=t0JfsVS1kr2-MfT?lr}0sff99Z(Vg zykzThVC#~rJ7-l$a}_~Ajfx$=b3bpj_#=^YJ{^v`{U)m*THZGs6595S&?-hk2?iCkgt8>K=3q35P(C{?#Qlj*c8R;%wDF9+RA z7Ucp-i_?T_MZm@mfT?!p8}&&2YDSuz-s5U`_v!j%JQ_iio7Lx!Ci5;qO2mS0U^-cm zF)v90r$rAo0*++2gd>^M+JMXLu$qmLILXKGHxP!0gVVGm#G~s%U&QHX6~ZxoWa`mW zv6vE9L+8IkeN@Fue7P+>yS2)qx!v>8vaxZK)`Q7pm-mc<*x8L_tG zlj-^U2NPhPB?=x2xePxMz`NbGXiMdO<-2k+eGaz&fo6^!j?i$eRkcGVm>Dsil` z*?SLg%ttIms%Hi)z+G;+V&8uHiRi+aMhUrUf`|Kg= z())$g_umIH#r1?KPBTymgMrF}p#YP)oS(;pLw!&6J%t%G#ST@ru|%cv)OqpBQ|J4z zSv|mvecRNl=PTzcXcs!q%i`aNuTbPnRvVCcZhVvZ;KUYfRP$Xl*r!Eb5`VQxGra^7 zEghTBi5Dcf+|W~m(bpYzceKr)lg(%A6n(b?vGQgB;(AbzE)?)d`lqbUfZMGgQO#p-_LW--4L$SP^d)D=WA5y2>Nbm_0xBRF zUBOJ&TGujXaB%g~8%8$H>xc$qgTbEhN5eTEA5*VEW_%ewiZ#T+xK#{X650_o0Q_U- zY7-g)I0zUx9G;1cR#1cx#>(WpyA0jJAA?Dq{z=!7p-4=pkL1{od%8T{crrOKcYbGI zi_>FsB*Gzw&+KWOGtkwSiuMA!hTSpn1~14tB3l=e$CX^d&{qX_U3Qb`uY{|4B7$N zs_?u*$tP_HW_A8Ao~iEcy}3IY-PU*F_=zjx%X;JBuYbDSvB*?a#hp|4i#u@+PDi<| zK#Rj`KrE83HbJ!{1~e(f+GtTU2(N+aP1%{4$dmxw#GKhMn?#gTSgnM!OqUH$&=)MO zVSRRws8c5ea7!_Q-JRL2`d@0FKh!?|egd3Voxm-9^gW^Ta7_f#kk`%mfiKtJph3GQ zJ+4jnbNwAmuTS4!6`UP>W#*2mH*0sovf5{M`i^G(uW|6o`9QQpYdg7*jzXZEpgN_b zwxswc+C#xhbRgVjvp;H57dr4<>F!WIfO{6k7~FgER>p)WV@4H$z<2m z9SEOctFeeB=cLrvu_BJ#HGCId)d(9<&kOxHoB}aZ>SO7iwEA3P4t|E8r@B&%VsG$L zU&je!q2`eK>VX5phYqoahNykH4Gn!hq0@Z#NmQfzE+0X-C+#0d0~AV#Fv9lE4mnLZ zWgV#wv6pNO^8`}K+w8DATDAk>S4AGd7G)w##J*x2MtxGm zxi6pt9x*afr8|mciqGocJep`0WFv&*aw5c2N%$lN8^-kBSq!0$+jw7XlbXy6(HXuO*+8psj$!a%)Ns_{6 zOxZy~aiA7ED*UwdYk|Nn!6^8kSqSQY*(h~E`LW`St3Z>306_PuS0tMO+6y)q48UXr zV5?QKi)OI_F>`vC`X(|J1yXwX(?R!v76g9nOe=MVFCoQ z)(%&%27(1CY*Qth|CZeS~7q((%s&1h z24LH3frMa)dS0Oo{8{nDo5d4&Y7eA#om=*n^KA|xE_Aer9rHvlq(gs)++(-995$m# z@&eumZ3P`tHbzY13FENTsW*8Qw7h`lz>Oi;6-ul=z^5C@5}MBFMx+dIrZ_1ea-h8t zj|8zAla6A0XWt?T$@D*|*G*J))8F94hZM~JrYhp()TA(3`&!ZZ4G*+d_;bVv6?B8R z8dMI$VHu!B5`M+w4{|4K*Lmr*2<|h_(fF zV!cEF?y0EN2wf@cduyH3@r#>l{q&#r*=o2)0cedy^xH494I{tP4^c+5g}XuhV8PXh zp`iO{Fr$xk?QE{9@norO)w*rnI}3s?k)n0+m)NWBO~$Kg^Ukhq>sGaus*zMe5Sn*( z^KUx+wb!p*(1*mI!T;jqXveTs)Jlh7VAt@TpeRCNEa$T`wM2Ba(jlS-05x4wWa>p; zNklYig+riQYk*K{1xhyG#Wye-+9coVbixF%yy0EL#Rw1uTuOUGai2ucz{G@bg(_n3 ze;ls)Stf)fx(r&Cq6pElk_?Um3P#KuvjSj-w4eZHV(ff(ElETR5iS`tL>)~4(X`)^ zz~*jt*t?P(0xO>EvO6|^a+6{&Pj4vOl}+6|Yhx~Dg2dE!+>uB=9QFVvAso&}B5q;H zP&u0A_*vO#d1z5Nn&DqE(eff>Zp@{84djgUhU>yJFKUASjL)R$^c26UjjLAOa`Y5| zT@hQ!Pp@RBSHzTEAJg~g0f8gH(Tq6(p^JJ6xfFS1v(N&o=&_x#CI-}$7aZ?w;1&iGJWBJRtW`Bzg``n{OIh)ao(kE30oT4cs~2u6{4u(voopP^2Q@&bG8>J+umU zWsQyj5#=y!RVCP8P-#(9MM%5kri(b)G4eT5(8_S8X+xD~af8cJdVIMPkBEm8PdeH;qP8XgztxGJ89Uo3$yPH>^xRD@5* znf>5*lp(TO1I^1?T9!2zmb4n!>3|ul*w8rKY7l_H_mGgS4A09Xx>CZCmFj>V-zr(i z&B9Nqt&uPJq5Gx!5Fd9ZIRs<;=lG)ED=UQJ<_yj=91wq_yQhfRYmK}HZ& z_3dxped~f!z~RlMTN^uCI-1++>LOuJ)gydkpn6qE46rNAb*R+1q9-&zkVstu)lslYIT!|Fl+^1mc8ex2-3aOOF-W$LMd=6S7Wx_f!dH{Qm`b9|f z#ahd;81yZ zrO|-!`XMnEp`*mOkq?556Y6L;)M*6XNC;uGV!5%X? zou&f^qV@GrH4$m3b4J{*hzlo^M3_}vCUwM(@(t`slS^I4CK6C@;E)m24D<;20Tsmz zFBe>NFAD%I;`_jY`TW)FdWec;Gfh%^Y_g|+W9sotv6vB;W4XV&Uib#L<~;`MURqq4 zZmT}_2!2RoU#}Aikh^(R56mfidx$m@jd)djAGPSP&kgkjefqvCVNheKO8g$Kh!t)# zgVmyz!H8DZ@;2R&ts%*Ree;M*GL3i%S2PbZQMpr?(6SUMRdKSyo&A+m@{>c8f^Kr? zlgSjjQd7z&YFakL3N2({Vq#=L|CnQt=KY{!tbYOBD|pwnABy*jyOAH&2ix0nULVSj zm`~`rAnicr7pSrax#YR7iWLLsI6SfBFGlu-P=@V_Ds**p0)Lo681YDiY3(LXM&rdm zLI<%qcKOfQV)FB~_(Lo+cmA9dYlNN!Mb6xqE3)bjO9ipT8)RO0Z+BOkHM9tsK$xYw z`@7Sh^~GYvWNw(H8Z$|#;V^dtPp&N?{N?EbLM3wHPn_XcYXWA3R5{u_&+%&q*X|G1 z2fV@^rHO>`bjHEfRgJYX;*gl~{k%Y>=`4uBwJ1XlX_Bu5kS@MJQq zP=GSj6Ij~_XQ3CrY8E?%)viKYQ_2nZkQqiNqupU})g=`vl*>Dm#ybC;@tcP|b!*$B z5m=XDmIqLQ#}h21U9PpV-D|gdAN@Z6mM#PXj!?w><#Y5kG`xD%K*8Y>PPtsJbW^|r zvyfgk8QNrwmGmIG=^B_A;asIHi~~>0l5?Db&%MO^Orh zQ_aU=RG&Z+FA6iW2gLQNF0l20K-Qx7-s9sFSP6|H<@x{b@%OWD0=c|t=>|eD2T3R| zkF{Ecd;99@=JhT%x5k!rN>b-CZ0le)W^Koo`zv2sU$=O?eR(N1@AJ`bobY7Z!qrD3#k^nedDtDYL$+8YgZfo=<2{MY zISC|GJyjnSR>c~{R9xI$_~KV~$9q4!tbNPkI`y4c<=)uuslOI3<^7CK#8w3w?0<_m zCK;%2fBCJ!fc-{_4?C+~junKu=mkANn`!g@KjCwcK5|NY6<8z`wX=X*$*=D*1nbOn z8Nz1%wJwAEqYMEtN#Ht8o)2ah(#f1~Q{SBEEnm8KRc_%}+mb$eq~}oN^l!M+&B5w( z!Pcx-@VeMdvRyV?4F>f|HgZ=i^|-+%>D4E)5ur6wFR*y5`ar@f#2S{)O@@>8OK<8_ z$C}043Sa!~kH>pHJ6hVZIA8d?=)B*EKCJ$FxD8!PeH&sc(6@h6>)Y@D(SXk}4&QW=8XfS8pBbib?necfZaCw1p^-_bp-`*YoMx*zDS=w8*mp?gR7p6(iS);rl3*q7OV zVShw97`ZegCW1?X@fRjBdXWmj&6wp>E-R(wG9)nwA9?t>VaJ5LrNJ`fC6YcUf||@^ zaRy&ok>XW3iUSA<)pCOR!SR_8@P%qx^y1YTct8x&D@i+n+pj~5tLfyCGM&ulh4#xY zgI`N2+}=eLxy4cH$1oDUdX|n1s5Fd`%xNk#m#ly_q4kQpV9p zEuo*$&Epq_R1StbAIyMwQlFC$kCB+s4h(dh0GsGv3uDORIQmcL;INd_XaOFY%*|?E z!iw;FaUEQb{!y_PYjDtF9k>;~GC3%5ZhT@v|8%7?p@(+j43voDmqhIX2%*qUlBG~- z>=L!FAivrHegeAE@?=Q*&9MSBZM)CoDU3FUP^XU>yjEN1hK_|Tq79JQ@GM%JmaY%! z-4ME@P#~P_*wC49?+eb5BjHR&tc{!0F{>vd9F+WGfDK~TB`G9H zp{v%A6jEQ7Jcz2T&{DmMWk9`%Ygpey0SHO*3CGE3Fm(^2m=UoBYXm&8UqbOb(GXxd zJen0Tw-A_d5Hr;Gc6ZZ_BUls9WkBeybmT6{9$8w{efZgH4GZs9#e7_s4@j&+4OYv2c5ZFZs*W5^#X)TOhL zj>hVXh4!()uIQc3W|!^y9ameD$(EKo4;1LLaNy25;C30%xa~O!XNNWoM?1B9PP&R% z(N-VY)`M_UW>91kx~fzPu){dYmZeUFi%&ErIyZLCDPbF>A{g+faKM)4 zU@sm*6szyfw)*8Lp?0fAL=ei;?!O&XdkO+ zZLMDA8>*t4I^frEL3D+Y!3ZRy#s$doWxWlp9zYKo;n>z%5*OzU*&RUKE0ClyZbZEy zlQCKm;jQ<${h?$&(`*kIshco1@FeRN7jwKbDY{m2xo`sNfcoBWBAmhf7;#~}$MKb} zx?O=aa|*p|T`25{`W3rnm)##s702G(6}X|Ju=GwfHM;|)1&U*?>Aq;W^HYt5I8bG{ zJ?B-(2rqHVo{k}v!T{83!1y7bgN>_~*o*8%EXOImLVQL&@wj?|bv?%psE40ZpM#(O zNp+<9T88{e@KGU53^vsexRC|%F>vvkK(3OAa5W*sK*K>tOff>ll1ydK>LsA~J*`)t zVtvLbG&}2O{r4VGpAp2nU_m?~RLoZOHTB0frx3E*Rh`|+Jca!S)OR7D^ZR~9d*GxS@m-bq>fQNhPXuP(o@kz(-?DD?XS0trFIYG_Qo^aJ|o82vyHqWOHZCW|2^Ppf-G6>s53qgw{AAjDD_9RLFYF2PNdvO76b0qMF* zN9vh9kw~&76+2lgc_e(O!jYOd?TV3`J?>=vwQ@&vZPI6cC~knw&JPQrTg|R-HKJ#aDW1vt!OVTe$s*#o5sW4 zc)gA>THI=l+Kkpwd)RKWUXT&vCl~ngHSGk?8YO-LDHt~H|5r{R+pj-?xbeDcMC|+; z4wLQrL+BbnxcawTqgjgJR$uc(2_oy4odA8uZ9}kae@&NyX0QxB1qVPa<^}SO@SzBr zGDH>}fuUI9O-x;ZL-Og_2pg38m=3-}ARZf^BtPC{(z{(QEXYl2brUD^3!4mEjdAu5 zleq;2dAm2M9hG)(x2)^d4*C&5EQ9KqKq?br`*NX?P%e?_PT}_>cxNklU?3M#-I+u# zgc!O+*ATW=@J2*mM-G+mw0VpNB>SKVUMn3ul;pvH;tART`*kB?Vw3JNaJqhyN`d+a zeLn%8^+XlpH`)Gs#JWZ7uNq?Nw_^?LukKJ%QO9@HAnULX#Q^qE;{)P@;@=?ynKWRY z?Ur}ID2`D}qnlJD09fN6xn`7H#uK+dZ@C->ykW)z%m}~)$B0L~ZLK@!Ej%!^Q}#JW z?QT&qd707gFoiRVZr{0i?AExesiD0s31+PqtdI-LG6GZ(+>F!~o5iHqWV7(&y*swM zET(6yk2n<3E-JR|(J(vOI$Yk;u*&OQ(0`$MS1f6=76KOJPa!(X%qWKn(4$6~3CPHj z&3F(#m%G3xlBkSD_wOd^qJ^Y`5~1gjO$BO5kKs+e(CJBfCrueJQO8t)*3k@_q07Q7 zKyIlS7Z#ZiD54Tw$Kxw0eo~9^>_voPma7VgErIKkNFYKxv?YCkdxfYsB0oSF=>sH` z?PBleOQn1j!C<9)NHGhS%m7cSwwo1JP;YfQ#KR7!x>tR(w7#QwL&x3<$rIg$Zll|f z7)(fZmvIEGZA?@WHmhteHn)2UQ>8qc$hEfvlrLWzV-w`d!t*Q2{jLP1-6vd=#kEDe z24#oEkgF7A#nhea#(52uA%y;Q=h~5oX3td;1q6NoJLlRzf>$rb?EJ93{eze%yrvzY zop4~q4}E^rcD@bX?<|gWGe2t-|LfGH_3J;ie*Nw1*B@NB?vs33{T~0gecd|j*tdRt z^<5l7k_&rn-MXVwCzpuZg?lg?e$>5Q`&+Ya-MTE^^tWbx9X766FN{t7!y*xg8bo6_ zfB0)iI9bZ#psDduVMDOKb7sml$4<8glm(;+^^nurXVHsX2=6bAVjm>Pxu(vhP}eiD zsaUMJIgxlg)*KTD7E>_$i4TXqe~up;Y6{oSsTO0%;9&|DG4%v7VzQZNJS~P;xC+H^ z*CZj0ICjjENsLSKor;E62i&FPhQp?yj1viPn+22PhjR-e~PY(Jf&GtYWH zoW7}La!xIu+r9PXnNz%Z^HzW>K=!H8Og~8o?6{96qOSq2Fn-2zK)~ftBo554bZChp^>? z$I`F9i}b!gBSElv;XgFnze@+wPw4jkgWMx*Ze$}R$zBKV800vLjDV-iEq0LWSy%nT z{cNjxdcUwj-TKp?s;Ajj@f1?Fs>sut6piY8>U$R_=y~C{<@VNth&c*?O6GWFW0HYL zo{+Z84)T#FvWEUw1%W)FL%oc%PE+>Gy6Q79NgOF4Z6ctw_-KR?BdkKq)1^N zl)Qw{kV&D!E`eR+=zsXyq363zHk;c66_g#sKET~fz#WHxH+b$ex(z*u>Ojk|DpD33 zE=o54X&*O;Hl{Pf?TOm$;RZD}D8leh?f|{6`aCae!0SJ&ZwnLKkF0e0yb)i><^fEG z3E`_#bXOCI9&Od)#p|j1^S&RSRbN_dG+7m=&u1Ye(SSxm=*6`M#cQy0`p`o2benm0S2eaphXd~@PN!1d zRB$x5HrUm=%at|ZdVhE*IB_r>-o7ijI{D}7waWv`+gp5w;GLh2jE4WxVK)R^e}Y8S zPtP|REiR{NS+U8B+FNUHLu6IX_KZ`}`zKfHJ=Wzex9Gpe>hFu$Z3eINJKuk5m1moy zp(!skpI;{JcGMMeLht1TD@)CODg2H-*O0T9H?+Duu(Qwq>xFA0O&-4(yz8#WNMzS7 z33J}e*yZ`l8`~la1E0Pt9R4e%p^&v)R#nTVD=>SQ+)m@N#@5K9K;xR*=$Zc1(b$}4 zzcsl^@3pMJdcAtp;_rzo`G&OZJI<$8c(*A|(f^Y_SuXEZ6g{~of7NgQLHljmulz3L zwmyz{NtyxFbD7-3zbx(^2~0c^AJHKH6H)iV50@fiG_=E^(vp6-d26q;qxkArfm->UM6~M zU#1Nt2XmUckK^EJa%TxElx@H=x9rUblaB^<3-P)L;%^&&yYReAU8*@w(P> zW1VkcjICa~Ka*N~<4{+3%xwMms^zUsOH*}?oWXP~7|K$C{-hlpV>Wd(wq zf*66IihXyVSM{5Rgv*`7>VEZSNM}F$){*%EaUZ+gO-go4E0&F z;CBMI2B1a=5rD}(4~mI6Z=2Dl7;oG;zq4SdS$G!l3dS2dwna9!7tM7C>DzD4QCgBAZSQRpdK;YymnC90Y zHwX9^aUMPpr=20-NaD`nEt@WGLV9O5i}X%yHJ8h&<#2Pjdo{|=H!7ZCkK(aLJaL<1 zR2uvtN6@4o*)b&4C)=B%eK&SQ{PkgRa3&LU)0X>ihTMHP+r}-`g*Z_|cXtCm*yc{J z)9F3nwIRvGVs}Qo79W5)^ni}&m&`u5Vm6gF?r%&76p|HcvUC$F^ezKlHrazd{Adtf zh!vBc1fz}IKhyaF^1oHI9yD49tdh+b@J1b;d^Q|)22r9ZAjBgptb0)sTb50VH?Cy-=v;zp5M|^X%WYN ziS#}C0Rf(i;TYeb1!yZB^zXU4G05NKqp49FOf)T3oDTrl{qo#kOWHXO;^t9gyYWWk zaj-RUtH$pJ04#(gvn zg?16og+4R3>G@4#p9w|NrTq3v=+=?Z$45tQ4OI%c!9`mvO`V01Csd3F{g!15`)>-S z3K_LwsBiAVh5JwJU$}5?pRnVW-)nAdY5v{qmZr$Ae2InD-jmJcviGc2U*9yZ5(p+C zyXHJOuREp`8YhG0=__M1#X+h zLj;t1R`4aPRtI267_;lmMr**6iiUlNkhW$!OD*m|9{mIDprPP(J6uL9&^%><)uH5d zFqlq`CgWiripc2|XDXcV_-!%877yi8h1N_m=yACp6~@)KnNod-dDJ%_up^m|5k3uz z$X1iZVm2FH?wmJR7gsvrkxQa_CyhOu4M+iYdmsdPRLW)(fb2!R8=w+IGD)`*@OV*} z)8@`}<#Le-0^ooG;7lS=eVVtr(4I>_*q(42)aWY7_L@x}1B*`*YQ0)oCq=W)wiK$X zV!pw;><0w-N;bT5rFus2LHT}KiP&jEm<>*Az}1#V2~l|9WTV+!Cn@frfAP}(U_e2d zrN`xaLBr-J81W*{QtXT}ZkWNW}8cq+nC^i@i zCDC)&1KPG56|*;L^+-0ProJJF>bEQjcU#I?2)Seo7;9D4bW-xA@9=Ou2!DhR|VQ&t)TOf?iV%#>M ztKrc#m|cxa9w?MDZ7IaOyX~^uYU($d6<GcCk41oIs09 zm-vUa{+#gQaOV(v{!;Zm?Gt@ZJpYP#1-Ysv-D2H+x`$vtqtY1EceAhQZ)CTqb&(eP zFrC#YlFH3<-D>_fib?GhOL7{WON5O7j`o2ba+0WRhRCXMIW9^NVT2e(MFg;>u|SP? z8oaaV?m~!Al;GZ%1O;)af^4!%D8c0rO;*`gXG%F!zK~t1PXb;zl?{ggE}{$?k!stM zEA<*d0ewy&gSHI6KRVLj0rtKF2>r-icBPDp6_mkfUcUBZdVVhNM=F-jxwy5byDI~t zC*Z|Uzj1Y6Usri)lkmk8!zWG*-;V(YoMohA8x&;eqH#>{tpjEY#$pUvlT!&r2l^de zgV|_s+9OfHkxjRRGp)qVM8r;;UZ-$XnQvTQgL%A!^_It%^cM4!M$hzaTB2f@+;*ll;ZMa<>V zkp|SHECIyFn-+9im)&#o&6QwfLt!}IGSQMBE^NTJn{U2n*;ciZ=5m{cg&0CmTviCRY=wCY~5K%7!znRy*0)rA3OcRqmR8NoL}6UbK3#eBccME-I>cd z0WD?_E5fARoog)vW-Hnb*#1n$ZZ_L9>`Ew@a0h@xJI;#gbK{A%0iW5GS-<1GRN%c7 znt|KnP}A|xux8{jknk?KS+K{pnHd%ewl)8FEbc;*a zqd8HM)IVa)k1xS@_IK*>*9;CL>}$LK#$@`N-A0GuHNHyC&UqO3V|jE3(B`~Zc?KTG zCg5G5;aJu}+`-(Dm6va;DF}R)fm-I!@@=qnwNXE$Zj&wczA}N-kI0&<(US0KLug+ANYH04L2F_kc@7 zUN$*k!Hu@ttqzo+Gr|xI-i8oN1b>@TgghWw5HxInB!RRcm&sCKtoO#U@D5#J=2Cn` z{pM1-7F~4dypJz;t@XlG3=}>4yc|*&MYG@I2l{{mIAAaYIO^nXmnV>Eh`oXHo2Q~DBK(jA_cC&UZWGI#cue!$>*TuwnM#xTI2=3oHs8FOy{kq-g*(H z{MT9dS}oE2k=HA%^5R=HdQ;2y2~hP7Dg}V_n54|jKS_TF>~|V~3?=-+F+{%qbje#r zM6k9)oT!vdl6xx>(IQvH77B|2?E83Yaf=2{o(rhu)00ckI;$!$SdLcBRoG5ImB^q z${VeNY&=6xALJRfu#`b4B*rv*A`UK8hMO7slP>7GrgPOn6svQ6-W3SA*xCl_s z0LW$c+T1~xy4DqJTmu*3w4A&aykSO8&Zk*YOrokl@^6{E^Fg7%`c%8{NPG1upBnnPCtidEpMkUlW(cHz5>HAHej)yT#4UR$;mm0tM3%5CO z>U2IonqRh00cxh(=JYG-J||l5-}PG4yz3MYu(KFTc#w~N6g)4U6@WfCKxka^i;uIG zHLO{)cI}!qtoy^ybo=P&vSrI=`t{%ATC5hk_b~9iX7b{>tO_!fgLlafcMsVb@*=1X z=deV#fRpx9vnd$Pf37TR(31od_D*e7o&|)s?rof9E*->p-?0N#IST0IFE250_V}0r*5HQ zK8N3ao4tcSw*RF16(lhCFz4-~Z{v?WRDYo1U}MjN)wP06Z53KSr7roih60>||DM-^ z&Ow74&qZ-)l%J?W*c`{!#Qi%N`TA0MnS#X-Bm$gB*)MEA*|Sf5>oebG)_Gs5IOoSw zmUP&D#@FVX@U{AccTQjU#;2;!_oBf4`=g&+;qx~cn}YL>I{Or7pObW)f7k1ge^c`* zYyGCc?@E=WlZb7Ck~Uo=j8V^JspF_hBfTlX`*Z9~)g!P+)z$PCZvRpBNAN(8v6D}z z*?|G}je&u`8W=d(_e$kzg|)w_VY60uv!~TV>@Mxib;a51TanjJ*XP$JeeoBsJA2KK zy57M))>mPBXRmd)dV%$+7p}XGo=4f%t^?FKctr5dGhB^;-N?b6$6E;gsHz(iMxH=f zGlbm&%yR;j;3q2dMLhN9)SG(U#;LQy@w3(Qla)$^CEyA{*I|bILVNy_mi#leOTAB^ z1z#!8w%*rx-7_{e^B9^x^NRQebZR$z^l24Dk)G^k9SMiX7U~+_+AEe;%t#gib-#Djv zMcWg(`PuCJoOL{v>qm9KoH_`_u^^lDKuWSoDamH@P$ItFg{X}X$@#G7`e52?hoAxz z3uWo+rJNLEqYs-G?wGsaw*FM&wgr`27l`Zuj^eR=IscftD7G%!yt1`*WoyHdqP(A- zikB-L@t&S|=e%;9UG*dqR=-IP=uRjVDD8uCQx1zM3|unNG--1HF%17kgSvrW$#@MQ z>HeME9&xumAl?m0lh9a!X5v<^!^0y3D>$@dD1mZQVE}^%F=pr{UJ3~mu_G<{OURT0 ze@X{{r6WeL*faGSJErd0BkZ|U{mBYJ*`w~M9y7_i;TYK6)upVDF0l?PU7}0H4h?^Y z4i_VP+WV?+uMnJ<*fFK6OE#J0uCCn(;vcpyiFOemtI1yy$#KBiz!>++M32)vh@=Gc z{`b|p*}=Q2cMAt6Xl(+B1ICLJ7vIA!9zs$Z-&e#5jKd7#A$|kn5BRfi+Bu*>60if% z@zS|Q1m2=}uK+|lKPBAYne$~3dtf9%O(csA%d(*ZM<8x3z1 zdL-v{WSSvUBN?KRB2%;EA)$q9tQeyNBU~d=&m{Ev9PGahlw^|X?nwZ_x`BTK=60%Y zZ)(@@b1+O0_&5;nBn8l&68<^H9a1d-9tWU2o7H6o$SgtQ>0!PhODe&>>WwA`twZ@E zGYia|s0Rh42)osWtYH1)Z&hCwJ=G!h^|P#~?}OYgumLQ_#+jiXaCJj?Z(V;b)+!-U z0bwTC4JA?n<~y0JfkTJ=uo=P9i?Ie+ZUm%Qq4@G_7Z_$ydP*X6JwZ^6gcA>}JQ$OV zR+rFu9k~FFBU>5u6UFv?T6Yhp6(@A}>%Iy(u$)KC8+r!FgHV0uB02>PD|pd~cu8r9 zOW@AHJ1n(pc4`eim^u#auXW+Hotx%ALQ*jQK>@IntZrVy@4QDXfP6}7MLl~cHEcFx4Q&oE^q`Z# z;o&bb!bXm^9)LvPUoj`W>Q=%VJdkg6a|xrMX5IO~^yZ z>xB0I3zJj5%J!(o1X}Qw{@JG*D;y4b;iB2&@(d2z11>9Ef08*MnhbDrW)MPe zMB?R>`!WLq!rL>v;|;he&h_gJCOFbllBLZEs>Q?skS>B;ZNMqcA-xahtao@;TTHU7 zKcpAjHe+seMINySBZ!{dffoAk;Np74^{quh0pM0h3QcRR zP;YwqjonhK7Y>x&W#12lGA)nU{Q;4NqENx}KzL>WhOgtwc~7z%+Y zOgEduKRD>}K=w39mMD01fHxXY=VeiPVsC12ki9xHIH>GIb$6}tWVCM}P^6~QgY|!~ z=^PGMeQX(oNb?~*ll2yhHMU%9x>>zeh8~nfT+1LTk8VPX$t_6PDtS>XmAtM{!?LYy zTqZ&QHAW6Z$)aC|3=g>qkXo=qBE@+gj0Gf`LmjA%q?x9|j_U@L?v~E>y3e@pQGfob z`uA+zedv$J+;(sXIl71~K=B9oZ@|pqdIn%K3f&k{ z>4}IHvzuK3NL5xidrT&y$Ki&!3)KsU+x4fR7()KFLKv1zs4lLDw?$-DlQRI%s0}Gc z$O*0;0jU^OgA8~GlSm#J2+ZU*hm;OmxZ;$}xVrE-DkljU$l#F8M12Oo$qhG*+{@{! zKxE?V!z8gmS~N*k#mDoZ2oIY<_!e9+-a{``Ql5Yd1%j-2GMLO{NzoUm0u!DFWCVUz zBAhtdgo;#j8YzJgnCacXt0TdX($>jM42W&yhvWQk{L3g0PcYj%AX9F)qQ;1b#dfsN zQ%|w;C~873MK06Q!$rCN(!j5>-V{AuFA(p7c97r^Wd?qo*=-i0;uo-XX=BE z3<{XAq{x`nZ8g{|@mQ&;rQK`wne5Kk!nmjH+li(Gpi(tn{QuwQ*XYAB^uH0-p(OM@ z*pHD}q~&tty_9N$w9CAfCg?9=iX-f0c5Hk-(VR*(CwAqB%CTX#_*08FEL+;t!iHE^ zdE+>H{jKU1j5g9|&-jz6reyNF!}0Q>JdXR#A=c8gblHZFk8dh>{nd;JK{5b*57+)y ztcsMM)kL_O8Zjbf^r0#uS<)auUqs^L2(b{!=H$LUXjR-Xyk+B`ZQOD~i$UG^Os(38 z+PKqek^my_balC$qE9joPY0#W=4at|Ja$z})oL=sM+-nduLBiTkC_o;S&blDi{ek= zGo!h5O}+MG#7#e6lU;&{Vr~b<8JAi#j8|x^c`Z#Ca|Y!Dq4e^kVeMNUcMe0FmUNca zY;5Gi0#wLxVRv=rt-iQf7F>Q~>oLji(#vN*@a^8*f_#3#(t&(_Ag?8$A=p;jy;;4w zS$%Kg&<+_jFN~d!83n6X-n&!wTKPA<)oVJQ?;q{Y^TkiY&B$BhPp5NCK5auTrwAx9msK{A_+9y4|fciWd*z6?Gh4 zGZmYhj3=+@+Sj+Yuirt7eG?PgR;*zExaju5!P^(Lu227b{`{Y(Z+N$TZ08Lf9XIS8 zYgbggjOsSd ztX6+2y2LwCN${U#S;!fHim_KT{jL!)Dt`t(YhZqqx%*v{xKlLUua{XH)ROlQ&#Qi` z4dF%yE#?(^+4wMa2=i8$EeCOmHofs-*kexZ`0$1JHPs}1T8B~VT~fawF^kM@H7m0E zRoMc=-K|J|{ae&KJW9JwpGQfH!?MGmw;#4x<8!?8CE}aialuZoAzas1L}jU(a8D-Z(q3Z_Al%k9Nc$Y~*bqjhyr_B+{-dRnlmZ^`ngJ<$ASG9^?8_Z_8Q9^E&1*kCwiFx*H#@*^jP^Qc$x zESKT6agt}xKMw*guVOjUFhpqVqU8Fl6+c=u=wchxQpv%&42f|29G%=Kish!as`-eSkmc$b4bI+x?+W zq3676KYw6mA%6Azd3OH1x<&igz&~(FeqFkSv$gZW_fU`E2*a!w5e^6@-dfEFSE`v4 zC&XJ%;7=Vo!494{!E)-$EQj2Be5!{j_V?OXVAH1jR}c9JIUEOKEC8NW_M>VT+N(=c z{K=$$>TN99e><~G{jU1mWoLF96NLm`toyMM_4}-C#V2qZzTaXvkBPl(U=U`TRw z|2%vj?VVXhz~tISVgP(2JHws~4HrY|5w<^6#677axF_{Cc81@RdN13@?@1m0H{O%@ zcNiN{RFTku#~^l^mOX}CySZiN#ObMZEM&_>d7Z_#Wgq4QAO#=9N!-BJ#Oa5-n6EOd*FR6-XMGr;}|k0x)Y36 zqF|x2n?Q4kQG<|zbF&|r5~h2B{Gh%G^oJKMxtvA)d#jxA37x)#Y-K-pINo-|;|}&! zHxd<8V06V|1xyWXK3@?x;yJ1QU>+KwhQyMDkFHkcj6$7|GlfJvU}3=T>;5I{z~{!j zX<$W3bS(sSSm#K7@c2a38xi7OA>@w(H{Bca;&s6j^?IY8r?hYTL!Ro_-CpQ z7p4*N^TGw%E^6S>$N@nf9w+Z$j+{f1sBA!i&QcPRv>$IoGI>k2byBwt*L@d0Rrut- zb@BMReV@eg$E^-CGa7@CmdvP@mJQ+cC*jy%p1DIj7L8B+!yUc7!j?++0rkEE2hJQg zpoVCPSI>d!w%V#V);N7OoU>s2mI(pjk4k!*deudz3(d={YuN*Dv=FdKYP&G!zu)$n z5M94#&mQ%^W5NF(;Y&0VwG$ZX2H}68okGBCD(T9g6%|;;haj;o*R2LZ=tkW*M*9cb zN%Mzyl-uQ*X3G7NRw64ewbJ#i@(ZoBGCI1f+vDjT9i8j(d?jHxBBjix;pmd#@vd3TCw7e6)V(lFF(Ln>Q|@>YOBJZM(IR!y1ApHQR4yF zjO06vlUAoQ=yWy|D@&GC|B>Bn(yPz0Pdza50Q1Zp85wyBZ~k}N68huK!fDPAFc-_Z zLCU}bARF1`kihTmfG6G!p<~AEM#L2!Z|*XfhbmlTdLdGp&lw0(fL5U}BPi9t4K>JG z;kj6(L?i8NV$HhxTs&kA-Ss50diOtZAYu*2a`iW?Y4V|pv%_7VYp_QBp@7hQ|EXqq zrN4f$3v|)tt^2lAks$_1;5tzYj(5JqN{WuC6S zCm5eruZ-sGVTWgZYgb#bkVWM^#p+V@1D9SHFqGS|q1e{-T*MGh7do4|>jnbCcBk8B zxm6nSC>C3Ha|cQnaJiiLo$x;53ECh@E{BI;mu@#ADJZrCI3TsOygYFi%~F7Ju;384X!vnCY$1CQu#%Ibb0p9J^Le#BR?~B4Genmez-Jg5X||$qb-OyxHq_+RP1p zllfF*eI#HF+nW9Upx1!9u%5aG_Bsh(Q~lz>sk_;IL1YNPrVey+iG|>$VWOhM_J?32 zw7YyTAR=f_Fq#&;-)%LzBCYFN1HQ3zSaC*stj?&usm&TQ_eG=D6mS=XroRw+P!QrQ z_X(r@Bw!txA;pBzid5OS6*dcmj*>45R1Z~)lQ0Q$^4^{YZdw4Ji+%jIQ z%f(W<2Am4%y#=_XXftj?hQdjul2PJqYF9-JRUfJdSF1T0a)veMa+%G1VP_9ty$Z~u z7n!8KfA#A7@Ej!4eOY)xDkGjjRA|rkrKLALhHST|AWXHZD=Y7-iHfib#nmk)SI%sv zx6%A)A=I2GcnVUcH;dBs`VrUYpoH@z>~DJJ;{T@`nrGi@AGF~&K;HrxVv zNWHY6Not@E8DBcuu?j1jAM2R3Zb|?ovlq9rVuJ`X0md)zREd|8ISx8}XBi_H@fJ|d zH5)uk3}mmBghKU2db8Kf&WHn_N8QN^!qI^L$R3hChKgDd3h}W2oh5f=vf0dCzg6iQ z9`393C42#|)1Ik|rXALJgD=#WPWTh3Pi!+eoDszyP3Ie%#MI#UNN8NP`{eQQ#*U-o zp~8W2cPVsq+!gW)!KL#ToL(@0X+C%N>AQ1zwY$9?Ay6Q}!e7|zIsk3k63MrGMxr>lz1MGUt=iz9LPeY zz&_KnsC^oLZUaDnJfOzM8)SolDdG3=F=-c;#VPAC+B9ey)g_*0kAo4 zOEeHb3Jt|CQCUbC*x9Jj+voQn-4K>u!6tLZ3gwMOVcQp|T2!ttCA^>QPO6nji^*ZJ zS=7Nvvurn8%oipFsHn;AtnhxSFISzg*vt;uY?6@HD;qNK1z8gL*Ndv7c>^EYlH#m z^Lq?vRlTmlb5bWoof^AOvbv1$-|pN2IDnAlKC7O2V0Jt;eFRCy6EAPq+sz^4P`?}u zNX9YQ?QE;m#?AM{MpzvviVn1lrP4{tdmzD|x~-WRilroGzY|t3p z#e<_?slJUgj;6TqKk(5w^~UH|1P21rjB?e1$`#`Lub%4s&V|2b3)Mdn8}x-l^#~3t zB!vB`hJ|#{F*;TfJ|P-*KmWbPpZ#1lF8u%aeXSJ;Yd!$}M)@O{Q+DzepfO-<_svL; zG$m*QQC>O#$_wc!#ZKX!ZQD!>*7cj!-)HO0{p%KdtD&y}FZGq$cD7Fa{p+?1^PB5R zrMl*PdwU-MWV`cu_3;mH!7u`EK&_^y#S7?5!W!&`w7VWM4CNegt_d?S)#vUYGp!qB zf5tliYz-1!DCGzVNuc!<^FTt0$Jc3SB_2RPPktY1)ty%XQmEc<0FvN1IZ+=nBW4Y*{gd#r>H*eu^qMXooCu_ZuXS(h>Drvy zyEk&vobGMWxO(i?TLZ&esOs#de1?71YJAdUG8-SW+5;yHP9Rv{r&r7dsI;I9D-BMd zIIk3t4eON+xWavi;&U1vf_x5(fUwdanDkDA>KX+0W+D|J_!%0LHQ%?0-uF;!cotpj zo;8zolxICzn<>`&nbH0GNB6%q>!bYHD0_}J(bnl8bUHU|0pRO|94{&o@{GaeJ|9O^?b|`wCT;qc=-Th7&Q<7kDp&_o71RyFJc^O zI6t6ZMEf<+G^_|c1P8~uk%sRTVli-o=A9*fPVzU5ZG;CHKU`D_;Ead##p z?@O0GdY379&T4gcxXyiD>1dFZmrNlPj(ST`-g3unA=68W+|Z$X{hX`AZM9C%g_E%B zTgVa$iz69SO)QUmhsiO57RQ2B#?(nHgicl&SD#Uz8K)iNtebU@Q@as1gDwbPm6t~$ z=uoHw))%=(;IzPZ&^y?g((Rq3%17B;)ORZRKzvZJk8&iL2NHxu5KV&Bqh}UGMx3Or z0t?bd5XV7;hy)QKEo$=%cAv-5PdZp?xfd4vn#5+AjjQK^rpk)o!|ZLP6=IkzU}n1` zi<(W5bFcuo^bYSLq$dg2etzw@aE?>BXZT1#1!haD=F5KO7jz?E{PcLYBerPQ;V=Kz z(S556qsPzx;kUZ)WR7m}RAKeLqrdg#!@Cy69Npue{^H2?^T$W4?PuoFUX7pfb5F~_ zpj{nFj%Qe#S!8<$Vj-pwrozPRGE%7sl`7g=oy4rfAI;5IQUCEJ_#wTVUXk}ti|gTn zAGcJyk!VW3W{52;K>+G=%A0Q7ee(@#=Bme;XVq`_?_k#F*~!MHZ1%IFHL`cvim}^n z++3d1QdstaFcu4_1-4mjexv)|5g@Ej)UJz*tK$8*1DUtbG;ztxc??KGzxJ2?n(rI( zyGPtRr5C5vGe-{}YBz?0Cgb?=BM0_Kp%998*{i37ZAYe#ve1bm6XS>=i&!5&e&nv# z5k3=!3O7A3dUWKE(ILZ;u7!LSl6TYPq+i@$RgO?H0(YcdT`8PeDfXy5GpEActL>AM zxM`fHCOgZpSaXe|WMU-)L}Y(@=5){p==@YM4h@fjaO}Oa$5vjgo%+~WTu3;D9;r~7 zIJkyu7eJ3tCJ?m^U1tjYdmi2snC>}*eA-0ucfWWUkuHKuF>s-oi;V84iyWk0rVD-4 zH9#M)T}As}=2D_No39Bp=ySijjHxwat%kHXoyUVY2eq>-eq-&_g?=I1k;w)nv2c`USzPTdJnXf`qeFIg`2T6|O9SILt}~~q=e}n!Cos70qe0Bz;!O}F!9ye^ zQWV5XH0Njl1I)$g9zvjK3zlrjw=G4M6J3!NId*7eop@y>@kU;(4_fg?UPZAto2;xb zj@Ro|vWcC@N$ilre6M>37*dp1$q#L=Il5kTS65fp@!qRf@4aGAHPn$vSzQl%MYsfd zX2hIdvxw`&)A3@Y=m47;ztE0eNzU_WdgmeU$Mh%a%Lev`-gEpM`}|An_{9&fJu5Ju zSr*X76L55jk-c(xMSxdS@9B>6R(5pm6xJ*+E#pH|hY5txQdmYAP!RAwRE8@4sMXmZ z3F{`vqS5bY2Ce;TVO64BbB%bW8+8F;oj$^J^uy<>4!;W*rl&7l zUXn3x+bU4o{t@pXkqyy37HyOi*W_E@a_%8C)1TX)@strRPG z|80Ga558s~tEsS;a6^p^TuGS*WRo}+nt0*QNhj8C(q2(rq$80^H|>qI73pX?*3ERW zb~au6u3$YN_+Sl?d2CkAe)rkPl_r53?q^&Q+4B9@P5#*Y#e+^L!6`3x5k#oV>y6V5qA)pry}{-2hxYb)U?p&+5cc>6L(O%eMhgT3B*VLay@npV28XEpNGC=GTU)1 zdeid0=1BQo!)Iz-{~Qzt2gQRov&ZOSBhs2WkA1qaW%X9xr@4@+q*ML&;QgtOX!{7) zK}LEjs3Fng+COR;ay=4|T=Q2YGUF&GN#NBEqY2=zm%l@4+AolzA$?c$IuPe-Yyv(( zMqO@Su)ZPG($q2>Y8)9{FLt}lb@o889{S4N!{XSG@EBoU`dpq6K>7KK8o}YpLvY_> zfj3dJuO(>n1{w~GTh@y2iztcN>aHC}-wKMUWp9LTIi&%L;3y^v}zR)Tq z;gQ<^tK-1MXyrlulJdfMYZDi4?&+8q-vdT)&-nI^UYiwyMsHtO`0M&UZ==^|vz4D~ z+uWru|4``O#9m*zbx&WrO&@A&gAGx8-<~5&iCtRS{ zO~IgkZwg+6$HyMN#opW7S|1=2V1KC9;VU2O*?-`q#q6&SM#dM#fTz;}O$TP$ylKlP zZ#j5(n|njPceKB`t#hy;2=|sSMEKP7Y&roGtvXNruBUdkHf(5sw>4of7^*KF-2ddH zd&AMb!A`6p)|+A33jZDDn_ZE{Ee>0xAs7e`*o?55;4q_UyZhjwC%0_cY_j*xM+Q5a z+xka(TLVG3qPkDI=|H>H0?T>*z}fYY&}av&!3>8!J~rO(@uc?Z-Cmc);)hGO#@1Fx zU1bdYdmH}CZbQ%k492RDpgPQyqL?2*f3JPiL!2@sSm189VvC@PzA{CzxVx1HwJ9V} z1*v8tZ4eC1=FN?5VQ-VuRNvm}W4kA^6Znmu+~JyqJ3Yd2WE8SfT?;F7yM z;jrgv^B+;br#)el#UK8Y!3`ZdM$Jm>HJUt={8|wkhfI7@4t;5 z3Df_rRPI6u{%voi1JOIR-~JQ(!P{0&Rb~Qy;q$sfI-LkK0I~_+92()IKrPVj?MV6!exZC-Hyttuj1jm(+c~_2!!?H0(Cl;dx4OLg zjmsN1+8Rdov^TUj1RWj$dvxlLY+UD`%Y1jv5sqx>Y;JFEZor0OHdnZ*t=z;fKlRA| zp3wUBJJ*kP_l0nS8>%2aS2N7#94@~ju<^XFv3bPoXz(?4v^BNZ_2DhC%^k1iI@-gL zMkd&-k#J*6S95zyOOx}FgVaRooCw0T-`0^oP2fSu4&Zspz*gAG@|ETCGLI}n90&9A zl}nVK)>5>+naq&ojq3KPa(U8=^cm}_mPxdZ4ky=uEX)SY z-q+v66TG$$Q}t$TA0~G7^3|V0rtyOA4CYdrEvLqf5yPdmab+?Eo$4x|ru7**5^Jx0 zHRS+O23lq3w98=7aBJnXmLtijaoS{jVcV#&G0 zfuvrvE4=)4pWpb!%)nqzS98!<2fNu&pe=CvXtBjv7qY+^ zy=VDzf+N!95I*;=ez(hH2n0LZ_KhD{r|fR)!|as$5OBi)))VdOx<1L~G_tCZSkqRL zD1a?Cb)h=cHQ!%P?U;p>~6gG0)VHD?Gb zJ;I8$**nzU9dO~Q2|mAJ7;h9>>Kk`O>YJhXLJq%S)N3}vy2%yjZXfbC!v{0xb6ChK z&%aFGEWVLD>msk)ZkuUq)onL?D++y~`auUg*$mcuhXmNn+8cy$ozsFuHa9ukcG<~k zbQ=yr;N=NzVH+Ke`XI*mQ-lGrkuX+E@C^tbx~%Bf)hp_?0kWR3K*rSs)dH9nkO~@R zXzgwA%yz_Wv$YQNyIFzd>UT#&CwF<<-EeJ__^tK>=dAqUvOFob2DmZ?hLK{r;{vFpfE z1v33n4VgFnI7acO zU)LxMOK4x5R#FWlW5U32tEM9eDHawpgueoM$Fe6xeB=!Z9|JEx7TDGwc=gIY_NW(KLG)RmP(kzX&7ckT*757m2W^%O@idYz*Gp zz<%I#yLpH`gWlr~@2)RDSbh)zykM|r>@6)VmHJU-NNp-*MXjL6wZe`?bt*t41EdzR z3mDDu&cY_fVVXo$$akzom6|Tln#ov6hED(RS}oy;0Bi z;RoOQ?rqtL$HT~7Ym2w1GgRWAamA;F9CS1gR<{#4fnO4__P}c#- z)6_-lH9H?j(#X)~%j^eGY4tWXmQSrS#wIvwQ@P{JE3I%c<{o}1esk5PN0+7EXi zU&3=E)c2^%A?O~Z?l^|phVL~-KWqtJt$6f7)%RbeRl2pioNw%hEEU{35PX$CSM7&a z_PrVuH-*bjQunLrh7fYU<$fpzSc2C1(Gf8Qul@kM>q}UL3B$7v;gzl`>p`+5m9a3@ znZ{xFWnkmL&w(npLXO0UR}sqPhmDWlHGgn>f2-HdMoK5{*^}?LLK_d%?uUAKpPa|0 zAN&m|_zTQ@9{U_ed)E)dI_mFe3ENFTJLlQyOW5Dyew^UJH|-YXLo*~8DyKUm41 zLdu4(un8g|SCPA*L+-SiOQ%<8rSq-j4;q50(;NSq4v0#i@PxJSx?F!|xv6eQ7m}1i zsZO+V(^{ZbZuJ#V6T&hkKYV$D7NC)TnPky8(6@rGP%mVQid71%YLoIZip?jM%M+M4 zu@xSHBh*Svr&sr4(P*Vh*8!^ov=QwC4Aidrvua`ntQ63SuEqeX5Vo#_gx;?T*udhtc<%Xaz8IK24cRB2cBj9{2~i+o7bKFnKLd-vti()erY2G;JPUA7=8aKGp(o*>*=dC z{PneI*WqXu)2`9zj=h-dhd1mP57{{n*UYxIJU@H=Z0lIDzB=2wt1{dA!ctFPXIry6 z+Y_ypkKvcvWN04TvE%jw8*U#t^TMY3#`>LmZ<;#S)4XlRmL^wo=ivBe zd!PemFqYnXw|-3?jP>@khJngW&iY_SNV?-(o6{e*!ZEt{eP0xuO+8NGx9%JCxKR?)4^&@h134qi;XZefKztkTmKG z7c-dH22Db6E5~$}NE{JCFppTBZR_T3GheuWyV1I5>WqAE=b4L>w~jt>ET25RWvj_J zoO$5T{K}TeKWLhcJ@Bgzi#6OH`U=!(9e%e(c+`C2(UqC^<`%YYvt&Yu$DSvS5eq8?_-v*V}or^c~B`y#mqr9Tfxh9Z%n4V0ujv#V>O zvvZ>BrCqx|h~L!I|JUbU{Tt!?&_^e~JCl(9eHicij}lf1H(J9rslseB7RK(~b;hpl zQQ#@knZVcYR2TZjv49F2Cdj|mLGd2C6@hWA5o6&2X|Qw%rp*`d2e>YI{Pz24C%gM^ zKYnoyOy*ACF}7jD*d3=|sRFrU`}g*XV*lR#pRWSPTt1(reM5)E=T|H~i_>LsTkUS_ zn1qNCre<6(*0uJAqej?FTb_U3>eYKJ?S0`9_@)XP9m1Edf2vl1%gfh1S1ka)bj^d+ z5=>ZpK5Q6{ZNpKDvJRH%Mt_U1x4x;z*BUfipw|wkiP$3M#DUY;K8CsLJkU6HK+&DC z;{$MP4Y#mRImO4VyQp!CIFh(t<=QcEpk1#uSO65MzuEi=V@wq**BlQNlnOQjHlbBa>fxNaR4gU$~o^I2UUmZXv{hhq`& zJm4gD?-sF#cM|a&pcyq(u+y*vKSw3lp2pR*Z}q;n{)A~fp{SGbY@|24Sf}cNMUr zwGQ8EZB)|_s`Zpb59QQt@qtyqjXvygOx*-b_Y5#@H9<28TKLf3wljySO66uA1{W#J z$NVe+z5Nh0x$B`K6~SDeoD8;LSBW8BVb6Y?AGO2J0?1#dgDW*J>~?mP9b?DY2}p77V5eZ2cbdg9`%JPFlOPM3Wpgae=Gg)~k7QYnZWlf8@G4KDlL>>hS6dk=drw2ba&?_=+0A7CG3A7US7A7LM5 zA7c-&2iecDhuFv2!|W66=h-i?N7$nbPHxx}>=)US?33&%_Dk$(_9^zu?9=Qs>{r+Y z_F47}`&ITI*yq@iNZHA91v%_;PcwUy}XY5xSt1j zkcW7f*YgG*;f)+F!g&jC3;YZ(a+xc< z#Lx0YekWhz=lEUxJbx#D7r&b?^LO)m_`Uo+{Js1>em{R7e?R{K{~-Sm|1kdu|0w?$ ze}F&8e~v%IKh7WKpWr{we}O;3ALWnn$N3XF^SOLJE9OgzNd?k5iyFpDO5S`<%8A*0 zN)nbN*}Rx9F3e=|iw*+BLOi(;pOs|8VtOGR)6>yH2T@9;74u?TNzSEnv(_pgMolUx zr4SZ#xa2sSmKH@Nos}}_oMcmDav_seV%9Y{xCV*@N<~qLCo+82s7W$uS#hb* zOevF*lSN6&X;+f*VoG0sHK#vys5L4%NJ8pQA&waJaZ|R$tM>ilqQ!}a7g8m z7T4+h4a!nMk{gu8yf_n2D*2*_2AGp_N_r-pj4Pm0jX&d>7!BXxs&?Ov^3<+~(K@9V zPg7%vprLXpqX4uk`BZ#Kdt2F|pggM;s;AcS(m}+H$pyMmR`P|q>rcgtivI@Z#OQTr zi=`YrJ$P-}%2_dLRMMy~#ij*fF0V-T3Y<-&fvOj%%T-}&9A_m_a!yj~TaoTm?1~i6 zqV?lB&~#^QM2wo{QdX4HvpH)OKr<33p~;I*St+I$@XB+=d}(%0Pj76LmAF!p-C7_P zr9!?)m4}P*qKyvXOgfX1QjQuJolA{L*@CiUUjy-?@|jY+D4AsBB9;mkHKaFjX^-PW61edfF)G^7(U;SqsFdLC&CgEb?4_5#zTg`BouuE?-Qa1D6udc+`{e zOh&9QF*4myRFWk{Hpp`*k42UgdMkNk6&hZJV&>{qcNGv*X^i0bk`)8(EXLY`w1nij zl$edDGdP(cb`1|S%2K?TL`}xeO2%R-k&uc)QI<_bjJ9mN;4Ml@shAVd_X@p)i-vNv=YCDT~D798gofxMV5Bi}BfF zyfB9=6{u35Yw?UUqnJP{sPgT#xXo6>KN|^7rwlY)Wjl^yl?XU%BVyD+QMpv0u_L8y zxx84VH@FMs0`HApvSi6&_$D*?5|UIQG3s7}lj&kIBk57=vX81>9pvb?B03zsq9I$7 z(@6u`JuT^}^>M&p1NA6nB-xnFC(;?osA80u7DO#soI<_iBx^RE#FT=n%$}8svyzx7 z#&gLzXKh4`>hYkGiJpeKcU3}Q)hvOY>*DBaSxHhymLV&p;u+kCBaluu4$@kb;wjrI zgnCk88mM%|bxjO79D@s!jvNXlRcq5g11_c>qsB~r7EOkLaG@E2+CKoq38TcSKvYj- z!jd6WHy6*P1dLu|8h9d|^rQO#sPt|c-07qwJJY#BNue=M6gg!`=VtOT^%%u5k-yWV z9)aD`S!!YgU>IUr5EarhNdx|3)I}3GnmCCv2DVf*&E;hkm(Jz0l4Z3U=;zWY$w&v_ zw>c?Oh^fb@o?z1)Y6fV?LLv3e;Z-QM3Pmk*@ob`mHY^%ufy)bK^$0X!o6YBEGm^?2 zm}WD1Sq2uLO)Hsr;vH0d1kaT;*ii$c@Ut3<1RVs?lTt349@dad<4nF-%E|~bz$gwa zKs&0qs1l>`QoW+JlB;q>i-B%b;_+0FkwE=wj4a z8^NnqqDlE|6-*>&s&@bsqqa(tILM1ZWe4mS=otGNMX+LYOGRK|S#qy|Vj`ZJl{_^k z&~PYo-5bu(18A&*DuS@-iIK6Sz;6=ICz(?~JVY8CRY0V!VoRYd)ghWe5?rQ{?5qN! z%BFf#c~B5Zi)d)vbImEjxu&FCa>)sPT8V?XOUH8<4@i)a6v?3lkg-r7 zwxv)st-P{z4Hm#QIFcpwG<5&8lu60nN-QOv1syFA4m2i9MQ|==EkFY#G1NtsrrA|c zBi*t-nJ+9k=>TRsiR#WNvKgIM0c$Lqh*!;LBu6C#EeF+iT@%B=M0_SaTPjN8LN1?B z?@CGq1=(al(4-gvYQ`vp24Ieo%x6m3oQ%Rys8yV;5}_(Xt{L#=t86>&r8tc`1pn`-OtbpRlIci*U9CN(coRqRw z0U&`@5DX?Lj5=VDL2MO@TD5Zurm(IxP^2DU*WxOtIbItXtBs7-Mn-BQ!?ls>BSD{S zTE2jQ6Ev6}H&O!+*TAtFIO<+YuXS0ob|Q_cph+tlW;IjlJJp*B#=|gvDqY>G!SrB< z2F_zdr)QSzS`4!gpgRGrVa8u&qODbcDi-I~>fU{A6f7G?Z~83Q)+*0wizk!$5=J#p zm7@j*%Y&GNrbEv{dPuwSkcEkme<_fSR;A z`)5y`Gyg7NlHZ|mJ(VOSp`f8Y2N)L$<$v>Xd;%^N7)tPSsZJ3^>!YN`&Ittt4fxC@ zK11_+kHUtTy@}H&77hgkHvt8O)gcFCVQ6LNZ3zX1pbiCPa}EVnQ3Fh#jJ38fF^7V3 z`Ja~KGk9tLN)cOsf}fb%XHM}MG;oPuTCMHfygsqy&)g9T>Pw+A*zP08&e801qw5za zD45TpFzP=t$~WvyygnPdYkzJe{|pKk73f3<6MKtK?6Uy$=b>ThuBdZ=I61n0Ht=YG zfi@;B)87IEQvw5LLcYcX2KJK5f-U0Btxb%LO^q!q zdyrvf_0|3(5#bD&wfubpMh_<2l?fHk<)D^Ehgu~?rT(mOwq)i>f=n#A{nqfue)X)@ zezocIi6OgN{+umcCc0d$K4O}6me#;Y^z8~FZgq=LXFrnb5$5l0(;yE*Gjq7PGFfxiigG2KfcRc-}>!vAF0edfZt zZVN{)d`k;nODlBnfjQfO zCE0ekxe{u>5_`51NV*b{wGv{m60^P%EW8rcxf15T z68Fac1C~ELnE$5)e{?^85H&wIvVcF-j6ZglKM;pMB8fjljX!3NKbVU@s-8d0l|SyL z^#@98cvS08xnE-z`cruNqZ;zNHdWiYRl7b8TapetmJZvR4!a)bTZ-p94(Hp3=eq%9 zTViB8CS=|JleEui6!h2ge_;ja6}mcqu4{l+%fU}M)`WJ^M1 z$4q2fO=Q=#YfG+c$F^%*uWQ#gU`r|>{}+D10YSh%U%(;8`yTuI0r~sBXfc7tLNP>B zt+D)mAx}WF8-%W$5=ge;4ya6+1fecfw>Y( zwJKvS$lQ&P(H?H6wO?X;PFJ@MYziB>$6Ya`TGcau3AZy!IHRw71A6=zLC0MYqY~6M z4+}q4P9UYL>j!%L9ErtUQK1slH6IQ?)lML#uiFKB1dS--uE>C?1a-_y!cS4hF3t}K zfgW@TSvuxcSSva}58i|<1M@@76@H)xTSAte`61SdH_$_*@g4OhY7HN=m6gFoPkOJZ zX2c#VVKtwsc@W?b6}6W7Nie$T$?i2ZjMx(E+B3MUem1EcvBybREv9Oo z1UO_ytu=iTj4rFPmDA1mPtUwmMw^D2~xrZDPe<@@IgvgASFDI5)Md-05pvWn#Ki9V}qvg zLDN{EX*|$04rrPH#EuDK#|5!tgV^yw>{uXnJWxqwLs~>bT2zBpcmr4~vOz1NVGaN( z2SRKC5L+PR1OPb!LWltnVjv_F0LcVG^Z*b&AY>H)Sp`A_0T4kTq#Xch2SR)S5MLnV z1ps*gLJ$BD1Rx{~00{#^qyP{pAY>Q-83sb=0T6m1qyzvd0Ya<*5Gx?$5CAy@LI?m5 z0w5#}41lBoAzA>477(%ofGhzad;ka^5Yh~QGy@@?0Ej0L@&JH503jFv2nG-m2Y|!@ zAxZ#<5)d*CfJ_4+>;MQm5K;|*R0AQ70EiMptZ)$~aa)sbGy}~!C!Z)qLH>JX?sv*G&zZ1=v2i=BbqKh_b5H*p3 zoZh}1t3p}BnL22-eAYv`=&V$BRmS^aVOA%lDT>KnO9SFi*08Pt@-3acS1&p%l3mqH zX^LaAH`0Ivlr_9*fDlS&(bbDc3uOhhQ#`_%&XhGECS?u%8X&3CS#azpQzR>>o8l48 zbf&EVaV~4v)d10#&MK-GWqnF?QamDUc0Qo22IQc`>m) zk-Kk}&wQ@!SuP*xPr_D8KEE~i0H`$?sU~|t7h+oaJM;N!}1qCJ9Qlq6Q zig;>AKm|U184q^@oJ#_mRz@*Zo~tcrnOzOWP0jisn4D9q5SfnUX%w7qv(uxI6**0DTI55@^$b`aJ)}O)kr=>8O=R)V0 z!y$J_)<9OfrE{2xU8z|kcw(VGE-XWnGz$yaAy=3G)G4eHQ2w6Pj=N1km$kqD`CbdH zv~@NK4&A(54QQV`=SJ5+39|pzq3vkkU-M08WD#MOahho{sub!q2D6uf`zt zi&2d{GtZ-_OC7~Xq&>q8!H>jR+!o_1{VAZ(yb)LYJ#&2aS|@RugvG|_;xYBiWrBpo zT+=aZ<&geR<@|W;abd9OikwW@agKVIo0@+vI30^b8e`o+&0S5ETW7N?N9%WV--T!^ z9rC1&_i3>vQz>atG(EqwyZfD}H~PW1!1`7qzEI(!GrkP_!UU|#)ww|KxpkNc-lwi>K?fJT8sR*>8R=ykth4hJt=AwM84Ep?pnBqNHh#iib9tHaKP}W6J>hIhhtg zu&%Jhak5(Rx1RUgFI^u3)0R4g>w-}Nn#O-z?K3BAxglXNF z-%swYx$kPerN-cWW)G8*_dk=68{)@P*a1fF>_g2f46<;({rRbogBf$yfHTnfiKv)BuX{ zoyqo2R;C`URM_jml|5{I*8uY@*#7m9EcFqGt>@PM#x&jr_jqOgr|nn}<0SZa;)wh;4+s9EPLFJHL309UW4Wxir_JyZ(~k6tD^EV+dOE6pf3G*^r?H1x`UKW@V$ z7x=1zQMf`$zFmb?a|I>dG5*+ui>HOg*#bg0C=rVde%rArPUFwlg59P30sh&wRUmD& zoN8Nr+?~hcdc}Ua9rQ*3HX#T-Gg{s(Ol=ftU#xqx>JFPW)srRac_<}pu9r`;9UtY1 z3A3=XC^WS>+g;TuOG31cA@MzeXf>#?m=VNppQqVcA9gz&?v5=+>$>x+iHT(+6<^_T zU1l3;_XA&A4^MY$?obX}zcP^bkj2__R=M2=?Co_(A`lZ`*cR zQuQnO+Le9eQ_7ay)j>dj+Zm__;c~o2MCE6g_Kp^~`M%O|p)2!a=)q?5+2brH*z9#1 zbHTUGh|7dyJuA;fFi^CIU$ikaa)2UI0-rPd-FMOZ%YFGz8Ne;A%&)DSD`Lymq)TS( zD!?nD_Y^Vb`O<1T<39J|HzL zfZ-l()}cjU_4K?Krg=7kLf=r|f$Bs<+CoB`$-xSCDP<1l0+_~~s_NO&r$cn0e0lAVh`+N&$Ncn^lQ#lW#Rgsf{}4Y@9Or&gJ@ zgSGjko^WGAahvP5jEEw8B3vY4PHln+vT?Hiw!S*v5Vn=CK0A9`TaW)$Mswq%#W*KA z;c2$=mJsY_iUj8pX8BXd!hqG%2mmTQE@yt_P#7^&aXT&{2Mqa~?_*5g8)?GzxNX04 z3a0WlII&|0eSq)1d(cGauC4sO|NW*NqxC_udWg}A@{V!~m}px{H8L2(~vg8TX_tvz#}Hvt~zHyy=M_jwT~rU+AbF-@4?<|rm}Yj8sA z6Gk=e)ON?X-t?vFVes(P0?OR>^}6Jx_OeP~`P#Yg8g#HG?l8(Va489wN7$&XRIl=I zE(q<)WN*|-}@D(KLXlt`+FZolF8Pf~WE27jxv z8AsYrI|*!YcJMBoJ`ntt$ssfHHE&b}@WFKdH8j64HfWhq#OHQ3Dr)?p!>Lfo7aVBu zXmIY9@7yhR7Pc9#4xIcpNBw29Sdwl#+=}Qfpun^~w1I%qqSj+zm-7+2eeKd#q=GFj zJ)aUc?8N)aO9zF?Ntur^$PZMjo_PBDeeAksK^?poFC?mu9P{hE+{(Os*-16lR*-@* zb@vT5pxniW*$hAG?mRvsABfY~P$dx5qZewIeBeGj8dX;*$T;n6u~D%%_UFXsOH-{2 z?P^6~R`Q9!*wG9TyjdIO)hf5vp=1l=o^I)_S5{M;E>>@hH(9IntO%kbJ(Mja4Kl5) z#wEB(+1so&dN%yuh`jf6SXn0%Tkwr#r^6Hmua%|ZuV25AhUC))K3*SB4s$*fxr%%l z<&=NhmUj*sy63N0bJNRasR^{`dmoEat`9Sk|M)<8prrGH^W*}lNk1+_&6D_d@uBmQ z|BRk0wTSnLZxV0CW8~Bj#iCBcQ>7D~VvYuXt5x7c3IRTT;lwqKKtjup)H}GM5hrEg z?SiS^nNzMJ&=^;gQ#EF+vq#C8TACIxvz?l_mQ`zr))zok#gkJn@zIjXFD<>RM^IH{ zWlg8sv?~c(nG4&a2v#Wn2u$Hwbh4(2WHx(UB z3cFGTRg_R(0{7K|Z_1&?V+ET#1Y`1bk;_m;OU_IzeTp!Zp)|EHK#EaAUeHmS^776SJcyW3bj4~W zSpDsm9aA2rNeezMYuUJ?FkAq-m~=%2}2!qf?wY6%xX-W_0!;ee|6c1bTa%Mn<$bPCd`S)-+Pb zjq+Bu)y|Y2)n#LfD(b4Lf2IUTcDn|N?C=P2a!C721ka0hy-hj>aItjlvpNQzCCd+2 zhc+9{IvDwF`lq?Irwxh*-R{?e>ut5)8D9B?f?CmBgp;Mnb|kaio$aWPPaEbiA#)KN zvNl#~soGotxTqrF0Q#euW)iJ; zn6X#*rW-`Q-o~qwW+#-j(KWVn^>fs7yP+aMS@IA2wKzjdqi4r8HQ}~~mX>ry_Pgfs zx3igdUPFQH0SMYlS}OjZ-lWNE=gh%0fl-k5!C`!;NL}89ZPA|i>A36POSso2?j4Rg zl3Rh8DIZZQu*_jqrTq(dy)%p;o1Bc0?EP(fdpjXvKVdr|F6Qsm2!~VpfMf3N_V!f* z)>@C0l;qA#!nVb0Ke@yG88P8XGX~$wePyiE?@5k*B|^pbg(jVk9Uht~8=wC7h~Xo& zWTLNn5u4xt8N3|r>|pEd5G>xuifZfX=mKK8bPe{)G}OD&jQ1nJz~@R9Hiu;xIhp%&iF#U2#T{)$Q5q*iAbLN<|m%10-0~s^d&6XXUv~#aZT9F+ti23n_ zs0h~;CdpF@U$x1bZMYog&&l~#$x1eA);v>ywR`b61^HPc?qfQBu{*QHFuV3q1DuAS z#Zl`ke!n}K^k^!W@o14vu+hW6xpF*~EBD``k#<|(RryEL^Xg;QL#-;OEn7sz6lz4X zp|mBC#pTP|2A>_H(My%@RD=ilW0pi%q%F!CcuM%9t*K)l&36^SLuxz>J%zosaANk$ z%j=iy5W)1yh$BAXFI>s1W6NWZYj)WVs}(>^>3j`+qA~8J(8%ay5c=nH=kC zM56)COKh-alV0MWhJ3Qu1!+HLG}RE?e5kLG)ceO8U9|O}Yv&%PD2HL#WGIKQ6EBAU-H$;0K${K-Q|0rPZMtXacC z<6`!dE0qZk?<>)V3*Bk2rGT-PmX5mU&ZEcQaoaPtm~lSlH~B*Ock;HBWkt=qH_UGn z#uu3S!PA;APb_!dADbrY-I+7?(5}4!>jUpX(90-bJBmwj)^AEJNMvyrKZi}pb}%l4 zy!8wlSX6$mb^1Fb8S5k>zU)-@+}?W~uHM@j{Z6JGOr2is^xx*GW6&GR`29pOaLHgZ zOP24;W?x{PCkf2MF4A)k>ZdHrsr1F4N*DgNN=C{k>~eSsYW&r#e|7rr*QM-7##tu% zRH%s?m^PaK07K-7ozG6#{=tzWYkO520HeMu~>?h(l8JQH)p@DWrcc+^W+Q3C`k|XO~?T3-6VRx9fv&no0LLr2^ zyi>`4B(W@bapl7SebL|tGZE`9h6-_jRW~0$*U{NSoeoCT;H}az4*Bm#$=BGk$Ugx(JSk^R zW=u&ka1MT*#9!Ff&fp6cj;;NO*0RP5HTsq3e$D%I3k1u3Emsh>p?n51iemT^o0?6I zfYs?dLTaQFw)Lgvyxua(-FqibJTrz!p9?|*!b~>)92$sqKNDpwHDIYt+Y)3I9l(lp z>ayEbYb-3;SiIS2AYLEq5P-bb^@pj;!=*@)DZT9!I9I+BYY{M0UP7<(*f7Kx7WR}? z4Y3Y#;64_c4os82Zrfn&sHzm4>AHalzO8|jRZ#4r2=>^ z4!BbrPPk&uvv|;BIQe1|V;0nLH4&nik3JFIOf7Vb(Ap0%u$Vr?Z zgUZ$1w6Zot3uF^dr43}TZ|W0aZqAh>nxQUq`u|*-8(AJdvM#HIG%fWQA}ER6g8#l; zbllAHbs`~so9fvdxX?E|7rmkJgU;6XrHgqe`BM@$_6niCG@t0j*hMrP%*I;r?HbEg zNx0WP)p;xFummHFVF=%L37$t+4^L)!R#{!faIX@c9$pQf>XEWZxCA2&q7@*Sqn7b> zdi?Xh4n$y!X>y2Z>bh@4Bz`WZ*>Azc_4P@1WN;)K!x(>( z5W7uMM`0JKJLQ#|dZhWj+t$ z$@4D%3MKP{QYa7kqr{|O41D&BbrBy7`|%|#K1#C{zrJgUn1`h$Y@#9b_c$>EsLcSy z4@1xs<(FhT%yLKpCLEd&-dPOz2(E`3_EBN_F!*t3(Xgj)oK&^*BfPYmxs|? z0Qd4kjD+MdG5>R6Rw-29IG6vGQJG%$Fq4 z-{_}MU{V$A=VVchWH3o*5$Y(j9O3@zb_F4w8@1~fQ5I=6de31a*yMwdchb|xs$$+M z;%qIJGo@N?K=TDLq-~0W=h(%+>9zo!ZW$A{h_S0MLCrtYkhztkN}kYdxH*~pOiDuP z9Eei<1~1^3SL3^%z~<;Z7l!KU2rj{_j|Zj;i!~;Tyiw%ZaBQ1I6J#3PE4=mjBPey> zCGEP8VK0Mn5h)^d`V-s;N3?~K!}OwH*;zo5Rc~jBk$6s5*tyX}41JYPd5@(g$Jp$0 zlCr9(f7MC9=yA`2BpTrUYM`M4WeF2$qz5?mMf`E>kEOGaz%B~^xUL0bL^PPtEXyn1 ziGJ!~P4K?IcV4_*4Q>XXU3rQ+Llid2gh&@!v^ogD7u9|*ravCPqfGJhyf?!-iE(u~ zU5IKL#WcnS`Q2S4@NI%&ri_NsCUKO7E5nJ;d+>~Tx(W<84XZDV8QGi+Us)QOhXv8e zMf`?I!!Sf&z^5j$S0Ut7=wRx5H*sXj)RI`py2$LFZNMbG1w18enT^5EFzHdQ$j#XQ zES7YScJ(o9a_@{Zj!J$hPOJNvGGY#h=H4APRSt+gCLU$v0KVfY&kU>EHUMWSG-4=Uo@4WC&zu zWPFt(wXZw{AJ;v16%CxlW*F}*rsJXvNgU>?FN@L4Nxg9z$ zw?ee~rn0WI3PqnzyW&I{p^1+vNUw~%q0!AwO0cv@=facV{)TaNTl&&sf?QC z55#K=Btul0!PeEC$JC|OYE@w`f)h4>i!n)11J`1pI%ld>i}o1wkrrQd8aA&}yC%Y7 zMV#`Yc~G$!9}F6X4#^%s71fZK23yqxa}c|bI!na;!O=$JzQoO6%aMehDJ@V>KYw!R zs}VOfLZtFMwuGpt<}*f>!Xvl^j?o>t2vb^AJW-^Ek3gL-g%b9;_^!7=aUu9@jKh*XYzs(Czj9n^h~rte*$S z+bCu<8RF-4yrE3O{RTamnEaS!S;~-zi`ys9G*3|u@1vfq_NxYSWOlN^f)=lHH}O$a ztYeQtZi-_&!C`&KQSaoUF2;Gts zd{Ba5#K+Ce$9>z|%ilDK8c@=WpazDvc`bxrKh&`msYo}AXut9%55b@w)JKCO$n z@63(5mBE$ojyQ6yh3MypKy9(ubg5^$s4-0kEUY<)!fUQpEtf;*7ykKw$|I@XndFD< z71$$LUtWAJipqKmY%WWQ3O~w-3S$;HE*w`lkG~b@@tQpo>r^1Ba06Ayn!u_}DNX3O z)h$lw+0MToLt9-4>BYX^vFvk<+gyiJL9;Csi}?5KOd{Zs>Me1ykc}A8Q~HjijJv?=aw^D z#ev&AA8rfsMy8BPjSA-Ub@0z}vUMYaTD7M0)*=avTWqRz!5)EgO4udJW679NuH(9T9(^*=LtO9S%HWT#F8xxHK z9UYEaCC=mOsvHD(% z5Ai6ijPd-SU(`rx09q()U<0&tV|dhJb8f$DGwz8#Mc5TBoMkU6G*$Y%KV0U%5O2T{ z6oN`zL2Z6H_hr-#f>oW><+Kzw4HWGZ{B|9swd$NJus4gomV>%TZ zWWYGpaG%UaU^R-FP6%qyA(|+*H%Pr_%CO9gJ^BwHt*>$=wF?~Ue;ZutyKe>YD>_{yMr zr*`HAk0AEoc|1e&y6*Sg;*XMh%JhYCFV0hO65CywIp<1O92KlSh}S?YQGxffSo3Xz5)p$ zxAz0CFz;1dP2M-!^di@5A-kXE?(?=<(aOq|2Qk_5N8ogPafbt6e+9XjM;G?uH4Kv~ za(qH+<+ixd!l1}}R1df3nE)|gWz(}wIaMr&VNasakcMEW|;xlo1O?-k}UjVlP;?xN;K=s)^V0~)P*AReR0;! z2be4lUp7Yn^M`MhqbCV7hcbFv9VXfI+``D}x!dhDNO3=cl zrSbn5FD!V4ul2~jzY7m%$wExHYUAj-V0x^7Tb>Szz2?GPTe#R|Bsv&6RDVL^X(o3;LNBsn9bhZbO;Wyr^2A#>bHkm2L>6JH zvc3{?nb(R^*(I4-bb;yFB)EldI;kO9RHZZoN;Prs&(8I(tthR*Yej4O<}p_z(mzi! zHoSHqCq@@<87ChaWO_Zeh%J?xqqCh?T40NkSixp#vnqCX>g*qHUvIiAs(kg>>YY=I zyo%a-;p&O1Ihy75@OqYq`@cXel9*k>zp;6X1x7}YkzOVn={F3zckj@W=E+arz%MW$Y z*yr9~@(AbMMKZ9fghX@2lxJEx&NiL=i9b+8O_l4?(^tyq0Up6ca|E4Wu4@_ z!y7KL1`}ZNF+f>;p|Hi~zUinK4WbfM3}C4qhqsAV?4NN(P;o-Pvv-V8@Ca(p_NDej z@Z?+cTt6Vba}Efl%sq zj4(rDC{SHt@2stil45R@cPNKanh9SWP)vJMs&ZKec=#4Mf>M^Qj}88=u8ze+k$@nU zXkmzBuZ82aEo5o6>urQNtI*vT%!4*S9^e30*aE6FqUj~4-;ml&-U=@Z7{l}07iX%R zSopl1jA}%p^a{e(m0OPdH@yQVfFX4MpHQf1DRptKqtAI?H>SD)n{VolO}=^kF(zkbTGksM`{XqsV(9zs05 zG+LXm?o13k2T-S=)Q=KsPfY_6JxR6L}jxQ<4y&u056Re`9hf zSx=x^JzP@@QWw|alM_6sxGFUUJblIz`GuLOH%i3-#9Bz|Zw!wT~H8#bGZ+N_H7Yj!YD6q7w## z22tF;IG)T$uvoUe=-4)%C=4cMK~nMR!zrzHk0`Gb+^$Hp1sb+N)m+s)*Qgd7*^f^D zXhhr#2WNU@;NmZXQC(ofLuMjKC(USlJc|ISG~}E@Uf_M%$V1o>C`2nC1tj8}Hyx(M zgdp{w+&{7mzjJERE+hhJpzVwd`|-kms(jn#66j?Y>o}Z|+E#gmZhfSy%vFjtvAWv+P=`PKGZm0zgXOO zUThy4y4Utr82=D0^-N#U-mkg2j&i~NlA&3{?uxwDrk~HtP=MMM*&h3XcKzB*RIbE0 zGocB z=34$R!lH0VXY@foTS-j;_9A7>Yiq7+OM};U{a~L)2A72w^C%Hu0>raWOHvO+)fFo3 zV7ftO|HG@}D5DxqBgYL#c;J0fvG3AFH4i;R7g%CL+T(6>OGPgS1FI*8d&wwm9x2Nj zeh0QT#w)LA!!y*Z;Y=W`CBpwc>yCyzyfp#8iS^6PdFD-KZbT7qH>m zFV_9(n&VAZvD9ys9oWvd&wM)6KV3SQ|3j!w`?m%V>!LpDMCfW$+YSjRkUhcbtYvD{ zisUPY@B)2ot@li}F57@leE6{Fr0dhqD)MB(S=b4OS@M-VFZ>@KI|s1}5>Xc6!ImIc z0w0t1H;BGzCw{vFwH4wCk=B_Vo$u3zPJ7y(EE=7y znpJmha}NMnm(nQt6m4(MZc=fgeHl$K@5M2PV^nizU8uu_OPP6)W>QIJDuO!+tzS4Z zYgA~26x(+S`0-oEGzImFHAP@tok@Z{7^39dbs^6w&+47}LwhA{Cseof0P`>T(Ym!2 z|KW?vgGP&M=DPvBfoWbx^XLWbFDBjw)6^YToD92v`!V|aAA|dBcXA4vZX>Lwt2sQL zBhcQI45#DFn+Cnp$)BP^Ms}@ZzRU+oAE<6%od@4#czL7h9*Rn0akG;M`!s-M1)V-( zu407v$S%UxUv@9zvptmDok0@sx19&N@3uxA&^RXD^ysy3o9}4ZV6vtP@J-zDU3bOO z|N(5nPFGcJd?+n)B+#+NCK&hxJ{K$7MABT3_)_8^E&`T{&6g>N(~eAU2>f< zsb9h7Ie%DfKMhwxdxQ{T@TrK4C@Ep9fN%?tN24Q`5JFx)l*&L9ogYv^;2Za&QKW~( zo;$JkTl%#Nd&p+@Gx)gYA$YL-701Y{!Anwr)FKwVTKgdXuuAahU4LgaRjFNCU*v~9 zzVf_wQWSYdpZ{>=dw*67=^OH4=v;dQbmLq5^%;rOUiMxGeAr9^)|F=D&rULq;-YW; zSyb586jKMMz7E&yh6=}nM8wSCrXf7*i?;Xf9&|uWZl|+ou$fnAR_&7ATtu`?{x{;= zEkuTZKAB(D3e07d{#FGFuW4C73l{pc?>B0DPsda}oGuN@Ns4vii;D2p0!?`YHUE>d zLP$%6uODCO#Y?@%NPGx@>q6F|wxV2-KvkNyQpV{q5pbjTusHSo6?Rj=NS9*BPFakC?X2$)eT1T)(&x&F3OmL?3%mrGS?o{%4N zWnD?l(l^=k^KXKeNVgC8Sm$}c-9WB%gRUzMiHuGdGqyzcP>}elzV6^7!k#R|$9xnR z^G{V;&tc5NB5>)Jqw-K5K-raec};HWzaAn4`gxLj-xw?iyP9drsT)rF3PR?+Ugc^K ztGimR0XuV()_p6={lXnv9mU_PJ3H7%ewAmr57IZx7MT)BF!U|JjEU zDnw|NmFkX$1VukKAj?IjBB69xL%a=Nom*ec#=*DTIAqy=5AF2pSab0W^ZzDTv%RC5 z4=(P_9!d8C^{^DyBx~uB5|vT|)|7&np5)1|sP%9ywL27dZj|A9Z8l;s@oBES6tSE8 zSSTWtFyU&Iop1q)mjgpnI2!`( zTGi!86WP$Fr<=r=J4;%vl(^{21p3$#wBW>&ehf88+XIb{@sD{HwrBx;K;=0@>ykPZ zETbG(`Sy3?t;heFkHr?jEMF5XQIKt3!IGnd#MWa?#ahIHS~S7(yhVjjyjhL8GQRNl ze`m=B{XN#JXC#pyaK=H>;k}NC!yc=b=Z`MAdzU8Pn!x-MyeP1nq9h-Ls~iDWRQH>k zdu^pNwdop`2|G#Y8j*pg?geRxIvPPVzp*XEm<7JhHcIjSygOv7xe_y4!90Nkfj_q3 zbW}T|1OFM|G7RC-{L+6Q;))4KE>}FDQ5hNUqCN@#;`k$OBsO~-E|qSUx(>SIdwNbB zuhb(dL#a1mp;36gC0y(8^K>XVrv!?l{Ic9J<@4bIUB-AAeuF=SjV%9$#ZCR8z2hh> z9Ek|!%9$83Beij87ixMnN9^Ut#=&BpWFy`YYeO|0O?e|;QTay#sg^!2Ez{7KWYgH@<2#PN+m}2 zyaYpZnK~)Na}7(>cgf(xOY$|?<%yh5Sqhu?xgjU&DcjGlt8prWEIZfh8C+m#CRt-` zXv~}2SjstjF-mFuum7_aJS@@$_JU-FSdoqdkUdQ@n(ZdskuxZbIJ}I%gX%cLxrm-P zZG4Z}{pIXR>%46|Q3bj~-5qZU@us+plE(z@xR?KSfsJ(k?s4657g39O)UZJ`jl86iP-y7J!MW zm8$VqnJ-0Q-Ib+ZZQo6V{Mb?#i*^pfk3a*K(0wL4_jpB89T-S+U1g;;>Nwd5KXj5> z1%l;>2zi5Kd1el@$pHmLCH~TbJ#J7Q=_; z`u;H$uwN|>c^y-zj`8n8jB`=rc0hb{5rd%=KszvsP$g5MTXeTfR$Qh>ar|Yu>g)o; zmavEbwq-rzS4(#k4_n*E)@k8&qv`M?@sLP9G4JHNvk_p*!{js( z5fsvJDsQC$iwlDFmG4to!yF3t>~Ui{2^)1){*G5!A*qHCG~DhT<$?S-3K^y`MH(p; z1&>9;WU!^KF3NMZH6G388T}occOTPg$mGt+wZs>LSS_tg7ds2>lM?&-)tc8O3k+G_ zbU29)N`2I{+*cM2?7nU?OKVpfiw%v3-4CQDB2;ICZMfOI=j_vreO5Dflu|*_6|bW( zvza1RBMg}4!;;3;H&oYlVw~|ga`lJ%>+fqAKPFO5r8C~VM0O}+&<88?jyt^M+(Dox zYxjh^h3@Z$H|_r20pe5U^?xXT7drvHwhCdd2B7rStOKql9YeR597Ok{vbGLIF$6?k zq&Jtq$ya59=^lwK4)Jns-Ff|AUYRVmS}XgnHWkn8G`1=>F45_eSW$`ZYBMF9&a+9D z_oQ7eDk4((^reeZR=VsD19;!FcXXFa6nCfg(OuGJtX;TF>&4;Tw6Q~ADj83s&uSmN ziZc_9VBv-zhHELlk8Du$Az)A2HNo1^51hz?2a?Hn?ZpY}qj1N{7ie;Fp~$>7+`o;i zDBRFZGe;vhtiI2bGf_($F8*k>->8EaI4%p`hT0NIJpJ9Od;$vARXY`(Y&vP|FnPz<6bCk|mQY#bQL>3g;8Ym<68uM8z(CsIO5Ci>I=zk7mYePY z<7x-HVn9wqdw^X#zxpv6_)z5FH`v51n;88AZhu+L%YqO;O{=VYZN@yC+j7?g+$F9o z2#@zunQ|U&{A$zA`(GX_$Kyh#W57SkmYiRbT3b!44uZ*l6?e3bm1&e6i{l8fr~V#& zjWacUvFiXuPR^u!yL@_)95Z5xtD$LDQtkO0El`y!{Sx_$-7?boV@LW48$e=7K`DU3 zD$`1%#$p+J*lIDaYN_nI-s74y3hsIKy~P6jBql*NOx?_$hzbKheNCfI+Eol3KC4KP zAy7Lym2-g@lzJn12ZBl2>!daYQIyQDLAd`eM4ib{??(<|UhhCdM#Hf;?AkfkaYEo4 zs0tc8L50Cf98uVv=;U{~Psfo3kKH|B+_~?s`?RaL)%x_0bvHW0VcLLZ@UD8+sR+RCN>CbLUz0kS|*<$)2POi=2!!i=1#p9H%qdRDe%_=wl8d zmN?Ws(CO&6YgJItzB8A33Azlpikh{)CLZEh*d!;M{QC>*zZgfmo~*a7AMTH8-zNTf z{pQ%sNGO_V?r11b#LkiI1SffMhXjz0PrnaZMq}!%YTcc@kIUTAPk1 zu9rnwGf$lKf}Uq}b`Ctx-eXxI+3A-4b=24SE9@_`eY4N54g>2c+gczj z_7!0(sEnZI9ybfZ-ARgGP+6>!6;f<-2s}?Om@>5XUCNmnxT~SkJ*nJipeOj^8!G_ukhzgi9~>{m4cduB zT)>^LRD$@m(#fTby(k+TXcV1k8;$X{TM<9Y5QMFlVWroxjf&^f!ITB#ayr>{l_6gT zRjxVkYBou}n)nv{ia!{s$&-TqdloanWJ43Mf#hTO!07Zlvc^8{oQB$rUE0=aIB5mzOkY~&suR_w=p6w(P3kWr3F+T zNgoA^(`aLF`b*neMB&Et&U;1D=%`+0!)UTI)feZ%!wz-_d6YY)3wwD2nJZ2J69$F& zc_&kWK%mdq0xT#`CAaTv7Zd;b$GX9t#K(klhW4iBoc3HZS#Mqsg{{8!MGaj~yGD*W zpCs{{2CZ!VuO#V%GKZ5Eeb&fgR(Ql(*4l#b$jSz7Cgsb6^fF>ur6v{fNZdlaC({{T zU`OWcNfIg>PRJc<6Io7RRd#$}soeyWgULni-oC@r9r(g)1yy{zJE7MH^_cqdOVb+a z4mbL;I+ipxAgIs{N9t&T-XnSF3ojrTBurZTV+s2PRE>4NIb1vBEQ?@g>U}x`r*bkY zN$K3~)7njc1$OW+K8Cz33Y34ZNeRy%H3)Q?smjT3~yOSfn{;wb9Y+Q$f`2g_#Vm@yY%^^a?U`2 z!VOJ4pSzU;qs8vGm@T-;%=c?Nf|Nq0v_K1Q3bNL?i(F^QFRcu%8+%(x>;Shf|>@_SPLPCK*) zYhgLRYn4GYI(Eb~hkKCkv7a&{E{74|!@qT3c2t*jr z#{7xlXFPoW0PT0){DE7R==Wd{iJV$d;S%X*RpWkMc_MPT*Z;~uEVJi>HOaNjL#q@? zG*+^46HMN5sAh*he&K)LF>UDnl%!<%?f|aoewutVQe$T3j%<1!z64*c2+7`cuHmg= zox`8=wOX8eoI9Kwp0BULt_812wTfaFG^HYS@HvK~>lR{}Q39LY_r{3y|dDilpL-EFrB zeubT0e-qF2wIdW#_}8UD>ADgIY1RolGzXi~704(+ruCT?kj1ClMwx*fw$(%$Yo#-? zKhu@!6x8378`E6@NvoblnwloM3!)57>)RrGBnpBiW;oN#_zFGMQ|kCYyNjg(fa64YGPST39lwf+T9ff2Vnv@Vf)H2H|wjMseFF(^Na4X_>Ky z;n%d8trR&xkEYQ~rt}TjJf0D0Vqr6+;rTv;V2~qZlYQ|v-?|S3-pJn-UFUCSUO<#`4CE}jH=LJT5UM`TN|?iD0eT%qJ1 zK^M&X1wp=rM{z6|u$vbk-YE!okXwfGEWTY3%w-zu)HL$`5Hgigi9QQ&7ZrsUwl4^2 ztO`66rE9*N$s{)w>LBuDAXX&Q@2$}(e|ozpq3$#~kj)^V!ZMs$7zsA#y5_K&^~=FX zAs@s)2=ZfQ*Io$MPaVm+?&SR3xa*G3&6h=eil)y)&>&bos=vwwZP8dOQ3 zYABi1&LR!@q*A)f^L|(vS4@$rRF!$UC6^YlJ?IWW(00lFpTYY$o6B%>+*!!!j!p4_;o zXP39xXY3d##NRKpcwK);P(o7cAwsJ%G;v+#6ae)PG!4u_Ma99`Bw3xrY~Pd?u(AcUvXi>R3>@Yf3M?1+F9b| zzf*0u9QmKotErm`(=A^}7GE{!^bi*-ahb72z`(2Zo#gJQoYJ=k!^pd{UI39LU^` z1+riH=d3^chx)yWm~tyg`@SoEID_g9 z@*gFcRXz%77?S3BU?V=gFd~E!b(M|E@$)EacT7#aSttzJS*cmBe`Ye3%7B!028(3s zak5hWEpIKzS$nV`{9d(NsdN{+)oK?;Cr+BctQJuprIXT^ zmY2UIu@g(>_I$g{5+?JWVsSeP&5s3M!$EDBY&0~A4o5!_?q>Fw<ZeHcgsX3te z;|k#%dcCC>EYT%)9LeiGF^-k+AAgbd+bHZa*srhvxB5}+d2 zBZk9)^K!X*E_ZQKx(mn8*nh^j;Ti*TyXOW5<_1OwWJl+fu}$M=jDKG>%#w*0t4@K{^NV zk8=Tph8bkWe^B~|kjl5FTiXoR$$9A}xIxOzxsdX*De!Qocg7rF4gN?iO${`I3Fpdd zQod=-?F}39QO$DOX}391Q9m!$Cz{aYJqnlb;@>k|H%z4s(@llQ>iYP2g~gpU`x9r?fukPtBe*w4D+w(-e)yf}b$>L%%2#$^G96~ zB>0giu-G`1m+&Jz#--0Qo`x76#@?Rz>v5oXVb6oeL$>JAM0O!?G5&u1^wa8Jmi zLIfV(6F;zfH(VUQc@~`6zox|RbUJ;SiIGlkX0y7MxnY`(*Czrc2DX8r&|D0xlIpnI ze_eNz3CS3X>!IoCz^gc_Qr6YWRkiGSW%saWdyeB-y1H+A`p_XBZfV6|Yb`mR=Xf-7 z?YN4Twp`D}W3S?=`Up(6;@eo?`6>3D+fhd;Gk>2%1MJV1TLB+vh7+HhWZNBBz5V7> zXLGJMP#GH-DOYmwo$$(f{8Mo2Pu#I>f27*2mj^N)#i+>gHrNqgvAvGhX+k*bzu-}8 z_C+?&4KPpH<5x0t(_i`}t|1L9R@Z;9MAO^Qy76Q(oA}ziqKnmdd1aA|<7>y<+MIdc zLD`a{89xioopQsiFW8({H~M=17=`2y^WA0uWPb3oJK^=%3N%uDdwoR50! z^qT)+pOG>f8v?5qo9Y_tA|b_qI1zDKX5VhZvx=JXi^WF8aVm{s(N8(mFpU4hRAk6L zSZK8hlc|jDRf@u=Sp@%YE3)gPe=ScOIb%$8Excq+-F932j9D&}ADrAiIh^$-+*GD~ zZ?>LYlLJ3km#cYhknC;EWWK>^Ql0wsxPE5i)#Z;R2}|RU|28(ClkQN|Gv3RT9(5VfucDf1dUoiXcZe zl5GBP^U`H|GSN9R^@Yj&dsEpkt(!qLF!gkpO(na>Y{;MIe!*3dPG^u85?wCbJCRC;1WoxypS5VZ6E#sgx89PZgj&(Y0^wQf%EI@Ojvgtav zR^y{d=clr+{(SY5yaj*SZ$m^4X#}mzZ&2#ctZ>KxLKX`Y_M)cWcVb^=?u1oHJPB7; z$h|PWiXFgN$4*_f@&fr7;&F1cHfLOnv_|6{f9nzTW*dOpal`iQ zH{40dj@ik0wK~0Tdho$PLdWvPiQ!bUr{;}202&FEI58yKwRBXCU|J?g5CRtdMjTE z9ZeKfBU`9P1Ga6Ne}+ySR$}oEK(m&~imK|mVVIWnYT0&7ap>*irP2gkITXLS0vW}! zgIw0n6oa&vPdSD(N3nYNm_+P?e&ng3vOQUrP*e(Yb0EpGQ1*Ybf*^D)F8)dQSHuy6 zY=oHuHY;31i5m6eXGUaGPs~9(T=QMsIMhbdbR<^vb|d+(e<+D%?Y-TB_Cdw!(&TNJ zNHs6(c_tmkzr-z>@VchAiYcnAf^OkC!-L1$19t+n2d<;XuCtuW=)TL66Y=?m=bG2i znd?m#ct^jEPH>4oEA#2SyU%;e+?m{aj`ze8dK98Wl+jb_exu&0ca%ArTYP~h-ED^4 zY{(Oe{889^e@KaoBJvu(*VOaC7z* zrrDJZeC2l}Q7BUQD6Txs%%({AegQ=Xc|B5ur;Xb8059^|ofHi!vzSn_M#vO`V^R?W z0ehUp!axO?MS7~TnFOzjnrza)9^qASgRIOU8laIz@;pxlUXrfo9|M)mwQ<~}f1 zeKJk>)9m>?m$KRP!7tEE!pHU&X>ZX^Au6HKfB5~$IDPzw$@U#K{VTO}8UfAH(U;}4Se-t&Ox36 zYiqVwAN!|tz;Wc=80$jVIcWe4)YMQ|KUbHV)SU6g-^GBQ7-C6)vcFmg-Vz% z`&mi%OZ8&KbIR#d>dE>A?HxC_Mx3i_m4lt3-QAoZ%wOCa+gli_U9u^4(yMn#LiKgd zkgP&&Kx#}>49(Qi8XxIUsY$g-*D_=~e`9>VH71H%X8m{UbB9MoeqipD!R~nzqA-k* zxFgM7vu*ld-wz1&_=Q9o!zR$9!nEjr=fkgNf_Fez>V?~rBCE%5h(Sn$g^ zo!2crpRE<6R7T}XDv~HUa;TD}+NPvBb_NwF%?Ju-O%IPZ>Ul$`)C_?ilWAToe~M4k zmCz_;3Agh(1XEI>9F`pXOj zBT`E&0BoxqtQCi;qlkMei@ETtsP?e?5Qw(f9fe~J|6!BpNEh1wXuNylMlg3WVZsF8%K$xur~pp zTJoT_b;nk3=}>h~?en!gwfJA$uBO0QH)iJ+rc+MvIuP^wbCAC%|9{P$g0kkLnCQ@j zm(Za%@E3SKK8NYeAH#I(>(6;TE=-$VKO29Y&b_{mk1@9xwxUiw%x&jhe@*{0qt~Gh zo=g>&I5gTkB45A5;AE%oi%X!AV($WJ>~eWg&j$h^sqdTSGCa0mjp?YbW?S+#>dkVN}5tyRz;a2Xc08v z?fMm_VcV%@Ni*@Ze5)j?f3l?&Q?jbcf`%%FsLM9uoSap^TrmPQTip7h5}1Z2OSa`@ zh6f7H|JU2MfXPu^XZET0tE>7|UEMSNn(pcDdB1wPTbj{~MsGBFpa%jCl3;>(8SzkT zEMp_0Ar3e)EbAC0#tx79jK0|5fHzJEByr3nn}o#yZ$iNFI^G~0e}~WOT|<_9wu!M@ zd(OSpJv|Z_$bP#s-Bq`$Z{51L9`~Me?m7Q&nHSw)8Kpwh3MrZ_Irhmvm8EpdB`Y_v zU>Lgl(JS1nW6PRlT6PE@=8zM_r(05(YOl*Wxq1gX3;k9!sAt;o<->tupcgfy8sjR8 zbBOI)i5^uV9bu@te_@KLAi346lu?T&tBAVnXT=R+J2WviG(0jOIAT}-@K_GSS7*+g zIgz`3=JMQ$B}T;8pDZNtvyUOBJRoWlo44*fsmj_ln`d{-i3)0&jisr>>+roeJVnk| z-`c|sgO_j_k;hWJ%HE}f&t2%!U86Z61}mX>EuYF}^_sL$e*|=NJUcpk{qR^OGlr|t z-^!1UZWYmZfBO{wfFX9#Xp$`~*fZ2OE zjtxZ=cs@RVFB^Hwc*Rr{kGk-gXMj;I*TE|;$F%ctX5h@smEXZ30W}L!!(oOf)y@VM z=MQ8uw=Ut|f6pebTFfoZ&o2@M!{YqH{8J;Vh_H{(lRwF@O_(hj{%>s2s0uLS=?Sr; zWP5TUory*>>4NOpr4EtrOD-%V`SxPgHz;Q+u>Id{jBee_|ITcK4r(%;9DSjArwAaJ zIgggv6hIjs#oP0hU&GsT`uZbBHuPS9q_l}GVUvGLe=a*#t5r{Q1#2~XKU=nQuZY;| zVgDPJ2O(TmW%Bx@C9n(r;1#sK^mqIyS|TSDj~qv66s(oX%!on1vA`2A=9B&?UYy)o z@ZGh6Am?blm9VDSKPIXrg=4S)rvqX>$0AAH<+?Agm!}0LwPWFU&{(yul<<9zW2YOd zc%?D5R#s8kz^37Dw;YSB;|0ZYSv){(2NW@dnQc_a5ONgn;U0n8CX@Qxqn?8kIf~+v&H-c4>NUT=~K|qi#{F0ClTL1-d!ZRTJOi5BLVz1I28D)BbAHx6% ze>6cP6#ygy#5BPo1O-S?(1swHDAMbwV=4wp=Gf7jvOvHrYMACWHAR=ScqU|mhN8NT z0|biqDh>!iRY(B##>8i2C@8zr$z?Wq8)OwTu&`8o=)!STlD`7L@Ln`YFsNFpoy6ME zE?z5jWLRpOSk$%0GRB8Dg=M(|=_L5Hyv z9aN1}4~d*d4F(Z_6(+?=J;~10ZYgMd8Z{CLb#7HQRD&YO1X8d-42ev!(nLwa_QB^x zC4_fDpinQo4yeossKc0|DxyjRDi%(v7@<0#daf@Y$Ivqq_8BahKx5PND*!11t)^p6~cj4u~bysf&`xkx=xxD znFS=QuG+h0KsP=_DwineOs68)g|xutcp07wdur&4;gdqFg{0Pzc1@2G4yrQ!qM#s2 zoPrcgrxP#_wTppRP{FdGW&{eee{uxWAB7Y_q6sJifKHF6=0bv9Jwee~#8K1#eGN%e z#U@YU8t^$bmwyZEjOi2BoIQsZGE7m&UUf)Vfma}&k5{lbxV3M5|M&uaNA`~0#phFU z`%IqL_;Izidl-Kk-+%SRRS{;`RLl%t@$>xz`@%Z{28-$^CwWgHdq8nHe+g67Ya{df zUV(_8_}!z`VR?_W{d-R|6HQtFO{SBjvCYhEz-+KJ3St>&aYu1atyJNQ_Vk|pd)9X4 zvqm~*#yxLf)pR}HrEh)d&HPM0zjoK$?yM0@8Q8c4G z6Ji>np-?Yf#d9pe?#7p6f6&|b`^T@iVlmyBjYhMb5PaqNx(UP4SSp))IhRW{WzwI) zrLFQ3?@(eH$NER#uGDLw1d$a5XVa&@{?|?Jy0;+8>dn~^lB5B7m0|EtA-A6bvg`42 z`xCN$#~{=AF7#f0`ERE>GLcB8C6R&|VA(8g!SjhM$I8t_w3#5^Z|=`XgH*nWKZirm=eh<5 z*A3wfArUHQC8rcaSJx>9=<3Z*razPE-^5p8zB+~-w^$NwQ;>>sUX#lbm_b|$#@3;A zLqqF4@1rO~f@Kwwf2(xt4gePshmOoF@m1pyzJ{=3%QaNef=X5WeYK(lHGw!XH2=B# z9_kjS7{d<5gmLA#!rvKGtKDjcmr+d}(v7hou@9FOD>F)Z0TJ6A%v{+BJd&3w} zr5X-hbV0BS`dVC@*qv`Y%T|DjhCD1AwlpF)KEcwMZ$yG@_w)sRksE3UZ#YOv3E$hN*n1n0p^ja28Q?!R z)~$x8p|NfiJUs(XuWqb^JK2W+j5P5G0>yf{i4IXvy-E|?Yl&FA78Vxy>Sr`Tu#m%z z#f6+N<9-j1uLfoV`vRBy{I){%-2#Q%xozvEVvU)0@_hCxBQVVLxQ8z#n>;U9n%uYW zk8(&)e?&@5LZF~vhBdcLed`AW6ZLJ(!-oQ39H8+{9QhSPvjmbZRD&d&0YT`JVQ~6| z4|IK`@xxttU8BK1+@!?~h9MY|-kud#(`7AG=;|t5jRUqKk;aRqn;O~8Z%bI+rg!6w z-tTb2+yLj%yZ?RSfd=Gv!0i;-4B^Ue(Oj5@&h+FQ~r<3i|X** zt^dYltpe_5U;4kx{|*f|pTqkh=eIY|L?T_v@fi}%EZ-a#ag1FcuY{rvEEX=zC&lQ+ zSK&52Yd5}aM`J-K*;!)J4jWE12p0sSj`3+DZMMx7X?UHx+wd>F!jM?5@@Vt|*9@xM ze{}ZA^6H+RRXu-oDRghVWMppp?7+~M=U{dH(EQP>56#_G?h#V-d(Xj@@QBxScm%e>8qdxJKiutL(h>!Rx6bu1$;y!Y9lQ4PS=Fe>ZwI z^z>}lwXs~@C>)3J4K>Pv*>VybHw4YnI*#DaEYF6X0LMY5_vAO*Fkq|i0|C~n^8gd< zM{GD3{Z-J-HuTrFt-FQ~;-)2TNua_bz>$$tBcB*9RwYvv#MGPwiYZRkBohUC+#>YX zU#;CN5sJWEihlHM|KGxTFX9!{f0^A8pTlUq>C0WD2@0$vIdh-WfYYC9oPkle`bx3! zHI#C$x_Y4hFm#UHW=P45G4nM&n?#{Jw-A$sOZUstqoVwIK@u*pOQn5{|6ruTqPgY! zrW{I{O>Q1w*rcmkJPjyqk}a8;j$_%TdjLU*FwpigqYCtz;O*m8d`5{me;D7rBDr(0 z4!0dp3C>D!+lY5Xf?cRhj1D>yY89GVB`kz+1ftPG#7me7Gem^Q6LL@oJ!mwpgu&s) zv0uBm?xSS>K`5ul3J&q^yifWi=e~D^Amc>wGxTQ-{T!sv0ITDOSIwFz(=$JWvmYgQ`Q$_kEJ;m#q z3Wr!-qjm?+l2*lD$}%MDSzgzCL}zu~OEv3BLs2nYei~O1I;kd|f*Rp9A?PBiiEf5@ zmZ&UrP?of)#CVoCp>1H6Dpjo`!pGM?W;_uj{}a7XiQH?Jf9ZwBD@*~Xj>DT9w}m#w zQ8g}T-*=@#-Tj{sv2Y6xYzS@JC;=wj_^Yvcx8(j0kWhUN`g+#6K3h2)3n$*5ol0$= z0QK58>g^juqUn2NeJP*6ntdKM)J-&4;^Jyu+ek@VT(i6vZoz|Y+1Lo2e2xApe89Yc zucr8l$8f`Ee_?AIzetRt+0?kog5Frj8w*<-r(n5yi8$0%J_5SjUuijAZ%e~(#=FbG zi)8tt@JQK63=YPXy>_V>j~7e!Udc=syJ9)b2|IeUGqQAE0@PT}(VXE>XgDIJhx;om@}O(e2?#At5=r@9U1HIeIV}y@mTKQVMtAe{MSx;dsC7UN|UMR#DqMz~TV| za+^@)hVgwmhuo6vvA#o9mMoggduc5&w7giQ?kOxblBTu@kGnEWYzpN(M|fmI1Ix)L zzu?)%jq$FoIDFd6kzC3=I?%oGokA0>M%x z90&kVe*m&~c6S@y-5dR)JSrB>U^zE7%WQlY#CX9I!4#d2khCvu_Bvn)mfdSc`VtP7 z69fZQ;hv*M_ZIace%dj)R`Pkb`+T%9bFJ{YSmcoRO(%#?(Q-b}iX}yXmitBpT0YB_ z^AcOAyiMp*>nu=3R3?MaQ+= zokiYE;-y%Q2R)J<$mQbI&K%L6=4$cgGJYp5;Id!%^Zs}?JD9C`*{tVhr+o2RC+@{h zfAyT78=qhCbJI6_7T*bh?meiL0;(Ypm_2nVIep&VxV zzgj-%b~r&to>#u?AHd7s$g}Zz<5y5m;CaNZA|W#bUV%SvOw)G*+rv*uH(+wtBsO_`rdK2RCfk z(0Jj&2OoIgLm&FkFOO}jRJM&2i$(bO)WNB#gA)UTgOeY4@B<%s@bLB>JNOv#b$nhP zrziqqLGj8eSuX->mp)s6;DP#Qm*DXyq?@0-;f5z~mRdLqghkx6y9J6>!U9}&f7U5@ zF8?&g|9ZLkBv+e>7H$k2o5jCmJio-ote^7FFo1M1g zc4*3_N{}a4*ogL$MCp5^P?#p+G5D5v`R;fkVG5FTf7SDnCSvceIi?#*x|X7%*ktB9GRfk2Dw{|Kv7jMcvMkds zr7Q~tC{+3sRg=3q3YHUfC-dpJq$qr>_y=tBAvT^42d)b&22T4CQIk*`^SEEHT(LRl zRhoMxs}*vIr%6GTZF|hX6?40)q=>bwVzm|yUV#s#G0$DLjd?C!e=&Jvlv0Hnzi@2M znek$YjFJBJ2{wl&jN$ z6jv?K98G~}5ZGNJKeSRIf3iP}S7N*;W70%hhTIs7x19P|Ucw8VVF1yYzHyq_8{9lv z*^mLvbT0gdLn?)qq%!;Ds38%Kprm-lu4E>NN9hN?y(ftBN=9srD`)V13zB>ym(Q_s z_&x;S{gNg|e-qm1DK!xj)u)&p^Th6rH)^geYO9{m#h|Od%B_%ax>fG;%%_4dU^x_U z7R2QuAMVRvlk4l>a$W9NTFD@6t$II_x8N`jn7`-_=R{dOdEOJ%h z?hRwhC-{3sDHi*`a8vMT@~Cx_b$r{cWmz7R9lW*Pe{2GTud)-L*ge)iP%J6GeUo)G zfnV$R?D3*(V@4SO65A30>Ur&Yh3O#?hWYD?gfq>;QW*IctbeG+Ap3_JFT8MYXmx)- z1dlZWm-NEvgJ1k=Q{MV2dL|*E&LqU zX=(NIt%q~f9De$`f_lCp{>dFEB^id7FBtY)^FbDYs)AFIJ&-vxux2xMz2u^yH|WQZ~jaS>Du})ikX8)rvSGXofh@N40G<{^nZ$Ir$OFH+xX->SaE@ zt$Ml5dQr71=hunx-=(q?>6#@}ItCGO@zz0cMB0#7CIvD$uEMMO+-b;Djj}KTRHMP( zO??Avu2RKe3eO(wrP}O0eY)M=!{^^Bf34cQpLsVFMMn3Gj_$dF7Ng6N6zeq8bWGzS zRXU^yhNIxpgrj~wT+A-JOZ=Om&5~(jRyAj(St(=*@~rFxn= zBI7x5E9xaYJ_K|IHC=B9q4sSIKgMzR7+!fNu$jdh5=Yui6otj2!Du?3Xpr18fA^eS zMw_jUtK(~dK`E;EN)Ue2GSVzL*LRUeU0toW`9NbP7LDkuI_+%DBK*8@@12UK!JmFz zlnf=Ohji-FCBUadfJ}cVD2j&8$c@BYE(pXeMIgkWr3WKsB|kKj$3SQ_=7j{Pha76$Y`=ICIE|5Y$mrKZq$i8pTwb53S7Nv&#kWco-V_e{aLt`4f#- zUWV+ixS32}It>Tr+2&BDF9YemOtX*tI^&u_^{yVSgmFX`m~(fPHf$l!{isoOx^RuA z=K5Ck;k&#hF|=V`nHEeNaXmo!sOZ8qdHuR1ga6C+rp?O;TvSM}aV4L9`otCoj3pd$)_-njA zkMWs~<>!cl@~|M_A;5=e$bYWz>cP?S`tli=pBY|1JX2o(jhao!f2tu(fyeNNF#;eQ zBfPA!G2Coiwp|ROMiVmCpt#a*!~I3l*xNC?O-pn1-f@GOZ>Bl^;`BSD;rL80Mv2s^ z^Ab%?fwM4=Jy7cH{BheS!}>R`zi<8Ke!hA!N00^#*WkJ6mU6LJ-V(ilR?pC04tcv!OEjnYF-9-{4>f39-}RuQYKPw5Kg{>I_1_b^cmD+5AnHpl~+?O z5ppx(&eTc;ANG^fHi|sLzH*G56vr4i&6rCn4!L70s%r!JGjd}-kFsHrU1Jn?@Rrt7 z8d9_A9jUCG8`ScHV!ESSRTMQF4u!&5&_Pr)u1!)~hqo@#f5AN0U?7(cha>$2*fuiy zuaYTENxIyF!+sBTe?6}aB;!&!9*cQpDCOj#Ey;vnS`dqjMPhCIK7;q}_X1N4^RZfaTTF7MWpU>A5(Qbr zSNJHff7j!zf7azkjfCBm$b>C&jTAKp1$iA+rjFEwogJh=p=|GHMB5>Q8Ofx(?Sx8> z2~f=bQ6Xy>YETbq%8;xXPE?5LLERC`RvPu!c-krp4i2NJ!8oYQ4=GyEv{lQ}Gj66M zJ2lmmQ@;jp;+W6**aPHzUH!$)ITvER)f}IE9OhkT{`n;+e&i#^8~^&j7mpo#@q>RuHsqh5 zeFJ_BtIzXiA*^9kRI6$kOOUa3^>e;ZyzB0}<9FQgl{?^r_c#Ck*S2jtAK7x}wrzKA zfBDs2)#}DtZ3A0wu2x&|YzN!U#V||Uwr>=#%aZ?x0|^c$&1O;`&&H3p@ZL;eX~E^X z^6Ss;O?70HuZLl|{z8D&Zq40T<2&#C%AGJZH+R$A+|jwYQ&iy#?wFmunBX6<2(l*43^qcp1M(E92}Ru5H{$-+*}b zt+USvGWK1Z3kt8Ui2bmju-Th(6a3&Ovv&u}_K_ntj=ZPS@$YWNKlN^qIy#&&T+v##e2l+OcFlKUyfXczjfL)*49*e=86Q z#<=r=AJWvC^(80%aUWx$I*x}xpj=2NVnNdk#uDkm&i0LRc5rZda4<_QVWD_D7uWSL zs6jIt3fq-+CMcgFx5XRhBZB&b={CCip_WUzv6xTjX*9i9H`=W zv8#=-#cNWwggGe-sxPc5qDxf|e=~*w{5i@(-+WUDGl$gi@-joncx4nD>XWvh9M4!= z7&i-NZOLV)x@QK=dcIGFYh)>#>%2|ht?i2J(s$`|)jg6SLAVwMNrF+IvIVk?vjt{2 zJIm8A6KhN3EhmC{1cU?-Ehj08jqhZ$lH9oki}4GqJwpE5kt!BuNUR@df9IiEEYj9OaS43!h1BDVj1Y;|%l2rpo%<)= z?B-G>Zhqi%e*-bf z1Rw-j1abs`1eye>1iS>?1nLD+1*`@*28ITj2NDNhe+V83S_sAn@(D%>zzP%!b_%iz z>I)bPG7EGIpbO3m@C+slQVenom<+ZI`VBe_Xbr9n$PMBS1P(3^$`23^P7l%$2oO3D zx)9P4KoQUqLK4IiP!oI;<`fbXL=>VF*cA{JHWgSEfEA7voE5?q`W9Rk;um}u+87oX zRv6A1f1Vm78l)Ro92y+H9Nrx+9o8NG9xfhS9+V!&9@rloA5b5JAD|z~AMhY7AWR_S zAzC6DB19tcBMc)rBbp={Bzh$BC0ZrACD0}CCLAWrCkQ7_CvGRKC<-V{D6%OoDOxGA zDiSL2D@ZGTE3zx}EF>&KE@Cd;FFr4xFT5}+e=uY)*f9_>9x*C0PBGRo{xV21d@{^3 z_A?eUXfxC_Ff>Xuf;6}^?ln#|v^I=3+&3UMWH*90^f+2LdN`gq%sBWtraAyRMmmH# z<~tZWK0ROo>bc0rgy)IuCWK0QV3EO zQZ`ajQixKjQrc4nQ!GRE$*2EmZ(jL{(x{oK?hD5>{AvoMT{QU|`f_Y-5mP z00AZ-<^nUuCPRAKI6KCOUoP%?JaURa6 z^)AGvaB29s3@(eyp^pI$;t(#v#kd5Q#}#lzTnSgkRd7{Y4OhoCa7|nb*T!{lU0e^> z#|>~p+z2k4(3^&Iua7)|@x5jO7Tigz}#~pA-+zEHaU2s?24R=R?Awopp7-5VU z0*A4K1Sv8|&uG7x5*08DGIy@ilxM-@rHVEqoi_!FTaJd>=o+ z5Ah@X7(c;J@iY7!zrZi?EBqS2!Ef<9{2qV6AMq#r8GpfF@i+V(|G+=-FZ>(-VQUPG zu^Mw&ow=;Rn#^M@)@B`l)@41m&NkR4+hW^n58KQ3vHk1>c7UD8PGTpsQ`o8OG(2_ZMi;3n-l9j7NSU{ggN7W@{Nbk01>~W{qJG?$E!QW=!N*6VRNZ%4@@LMhv!lix@C=Gnse=jrP5Mug~U&p`VrsdiOfx2x--{E z@Fdc;uq;|pP;j4usfzXz>TbjnPS%Lx&y`zQJsOI@FO;C5CA<~!oN~aka7q&l2R0*F zQepW^j&2=)=doArnJgqSh$?4uZnh&8jD5;Sl<;n(WNu#glD25hEiWqbM1*uqhex7l z^E41ib>dB1n7I;~Hj5$(S8M6%@T@c>G0f6+PTQ(BKWf58=HqLxXOa05|>eMq&X54qezCH1*Qr% zEy@*flQM2rYFUqtIWMYdhG;G!TFe1Jxc&IX0(DO5GeQS?2z5TDQQ9gLGJ` zF;`xH%!9~qzrR3(1v=O;h|121d6L)7qi>%yMNpzt7*Cy8ro0gotLX?eF$!Ig24mi@ zh5-#Gn01j2<X zAnntig8_lClAl1U>xOcD`y6c3lQ@=t8LjbkncL)AwV?ed!a?L&%b*NnTV$V%O>hJl+(l1$!6WmM7x zCzXmjCY^P92zr)UgnKeRp$r9CW->_iYj$+VsW&nrPMF9tnycEv(aEI0NI;v6V?6VJ zX&c_nWHG-YkLqMm3=N+|)HXw|pq**y}rV61{Xwvw>EG_4+Z z3!C0d%_-;oxNf6R%SGnUMWzkn+nBQH7~a*WG&-y0(IA5^KdDp2Q}3pyRMgwMvy)ZI z*qm9qk&`S59k+90yA>L0QFB~BQqui@T>Bh2bRD@dFJ~i&iJa)Ig~Nn7j71V{E?jhy zkdrKU3lVS$5wDt5b;9(7c2#~>0NhzADk4(KdzGA12!~T@u6yW);uzKIP!>kGZN&D? zox3D_B!^Z=xNa!gA`SAI(zIbY9Fi{RfL7Mr*93yN=~2`o-*C8P3W8RDqB>~m zs@k8qv0Bk#dCxM)qW}i7W4W={0w(RCF4ENm%?=3`1yC}MkDKb^s zV%t96YsGWxe|<7{jH^qZP)otxrU}B}10tku~i|^0c=0U$CbAga85# BUKjuX literal 47080 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 z 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 W(8M~d#r{~cXwm-w&cN9D0001RE9>9@ diff --git a/frontend/src/assets/fonts/openproject_icon/openproject-icon-font.woff2 b/frontend/src/assets/fonts/openproject_icon/openproject-icon-font.woff2 index 76fb23abaf33d8c94d289653960a167565dce607..806f8f3f51a35a729be885eb73dfe30545f905ad 100644 GIT binary patch literal 26424 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 X@Ug8#|08ATw{U4~InT~al;y7yHuW(h literal 39208 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 + @@ -7,1980 +7,993 @@ units-per-em="1024" ascent="1024" descent="0" /> - - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - + horiz-adv-x="1024" d=" M409.5291733333334 343.3429333333334H767.1167999999999C803.8655999999999 343.3429333333334 830.7199999999999 371.9509333333333 830.7199999999999 411.1061333333335V700.2350933333333C830.7199999999999 737.8824533333334 803.8655999999999 768 767.1167999999999 768H261.1234133333333C224.3754666666667 768 197.5210666666667 737.8824533333334 197.5210666666667 700.2350933333333V411.1061333333335C197.5210666666667 371.9509333333333 224.3754666666667 343.3429333333334 261.1234133333333 343.3429333333334H409.5291733333334zM242.74944 411.1061333333335V700.2350933333333C242.74944 709.2706133333334 251.2298666666667 719.8118400000001 261.1234133333333 719.8118400000001H767.1167999999999C777.0112 719.8118400000001 785.4890666666666 709.2706133333334 785.4890666666666 700.2350933333333V411.1061333333335C785.4890666666666 400.5632000000001 777.0112 391.5306666666668 767.1167999999999 391.5306666666668H261.1234133333333C251.2298666666667 391.5306666666668 242.74944 400.5632000000001 242.74944 411.1061333333335zM454.7584 290.6368000000001V304.1877333333335H170.6666666666667V280.0938666666666C170.6666666666667 266.5429333333334 179.1470933333333 256 193.2808533333334 256H830.7199999999999C844.8512000000001 256 853.3333333333333 266.5429333333334 853.3333333333333 280.0938666666666V304.1877333333335H573.4826666666667V290.6368000000001H454.7584zM378.4349866666667 435.2000000000001C378.4349866666667 512 437.7984 575.2490666666667 514.1205333333332 575.2490666666667C586.2016 575.2490666666667 649.8047999999999 512 649.8047999999999 435.2000000000001H731.7802666666666V487.9061333333334H686.5536C680.9002666666667 496.9429333333334 680.9002666666667 507.4816000000001 676.6591999999999 516.5184L717.6490666666666 545.1306666666667L686.5536 593.3184000000001L645.5637333333333 560.1877333333334C635.6736 569.2245333333334 627.1914666666667 575.2490666666667 622.9504 584.2816L645.5637333333333 627.9530666666667L596.096 656.5649066666667L573.4826666666667 612.8942933333334C563.5882666666666 617.41184 550.8693333333333 617.41184 540.9749333333333 623.4350933333334V671.62368H487.2661333333333V617.41184C477.3717333333333 617.41184 468.8896 617.41184 460.4117333333334 612.8942933333334L437.7984 656.5649066666667L392.5687466666667 627.9530666666667L415.1829333333333 588.8000000000001C401.0491733333334 584.2816 392.5687466666667 575.2490666666667 382.6747733333333 564.7061333333334L347.3403733333334 593.3184000000001L314.8322133333333 545.1306666666667L351.5805866666667 521.0368000000001C347.3403733333334 512 341.6866133333333 496.9429333333334 337.4464 487.9061333333334H306.3517866666666V435.2000000000001H378.4349866666667z" /> - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - + horiz-adv-x="1024" d=" M836.0106666666667 256.2176L653.2095999999999 423.3557333333333C653.2095999999999 424.7040000000001 653.2095999999999 424.7040000000001 651.8656 424.7040000000001C686.8096 469.184 706.9738666666667 524.4458666666667 706.9738666666667 585.1008C706.9738666666667 733.37088 586.0010666666667 853.3333333333334 438.1482666666667 853.3333333333334C290.2941866666667 853.3333333333334 170.6666666666667 733.37088 170.6666666666667 585.1008C170.6666666666667 436.8341333333334 290.2941866666667 316.8725333333334 438.1482666666667 316.8725333333334C491.9125333333333 316.8725333333334 541.6448 333.0474666666668 583.3130666666666 360.0042666666667C584.6570666666667 357.3077333333333 586.0010666666667 354.6112000000001 588.6890666666666 353.2629333333334L770.1461333333333 186.1248000000001C790.3104 167.2533333333335 817.1904 165.9050666666667 830.6346666666666 180.7360000000001L845.4186666666666 196.9066666666667C858.8586666666666 211.7375999999999 854.8266666666666 238.6944000000001 836.0106666666667 256.2176zM438.1482666666667 386.9610666666668C329.2736 386.9610666666668 240.5614933333333 475.9210666666668 240.5614933333333 585.1008C240.5614933333333 694.2818133333334 329.2736 783.2426666666667 438.1482666666667 783.2426666666667C548.3648 783.2426666666667 635.7333333333333 694.2818133333334 635.7333333333333 585.1008C635.7333333333333 475.9210666666668 548.3648 386.9610666666668 438.1482666666667 386.9610666666668zM331.9620266666667 621.4954666666667H545.6768V564.8853333333334H331.9620266666667V621.4954666666667z" /> diff --git a/frontend/src/assets/fonts/openproject_spot_icon/openproject-spot-icon-font.ttf b/frontend/src/assets/fonts/openproject_spot_icon/openproject-spot-icon-font.ttf index dc8db62f96af47ddb494ea51b08619e7a69b6082..8b48b74f6ba0a4bbd8792375003133b962b8acf9 100644 GIT binary patch delta 10687 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 diff --git a/frontend/src/assets/fonts/openproject_spot_icon/openproject-spot-icon-font.woff b/frontend/src/assets/fonts/openproject_spot_icon/openproject-spot-icon-font.woff index eaca14836a824472727d44a888272c21e152409f..7aebdd212efcbb0ba7e8389c6044e8afe69d9018 100644 GIT binary patch delta 37830 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%0Ai(Ve(!K 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±k6*+zAR$ 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 I2k5>Qa(5?TfB*mh diff --git a/frontend/src/assets/fonts/openproject_spot_icon/openproject-spot-icon-font.woff2 b/frontend/src/assets/fonts/openproject_spot_icon/openproject-spot-icon-font.woff2 index 056f11fcd163ecfd1672d30fa773607c3343cae0..ce9b656ead60309846ac684f1a49c8084466a22c 100644 GIT binary patch literal 31508 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 z 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 Date: Tue, 4 Jun 2024 14:32:41 +0200 Subject: [PATCH 160/176] Fix some test selectors and extract the subheader into a separate component --- .../index_sub_header_component.html.erb | 23 +++++++ .../projects/index_sub_header_component.rb | 44 ++++++++++++++ .../index_component.html.erb | 1 - .../header_component.html.erb | 60 ++++++++++--------- app/views/projects/index.html.erb | 27 +-------- .../storages/admin/storages/index.html.erb | 3 +- .../storages/admin/create_storage_spec.rb | 13 ++-- 7 files changed, 107 insertions(+), 64 deletions(-) create mode 100644 app/components/projects/index_sub_header_component.html.erb create mode 100644 app/components/projects/index_sub_header_component.rb diff --git a/app/components/projects/index_sub_header_component.html.erb b/app/components/projects/index_sub_header_component.html.erb new file mode 100644 index 000000000000..bd09217edd2c --- /dev/null +++ b/app/components/projects/index_sub_header_component.html.erb @@ -0,0 +1,23 @@ +<%= render(Primer::OpenProject::SubHeader.new(data: { + controller: "filters", + "application-target": "dynamic", + })) do |subheader| + subheader.with_filter_component do + render(Filter::FilterButtonComponent.new(query: @query, disabled: @disable_buttons)) + end + + subheader.with_action_button(tag: :a, + href: new_project_path, + scheme: :primary, + disabled: @disable_buttons, + size: :medium, + aria: { label: I18n.t(:label_project_new) }, + data: { 'test-selector': 'project-new-button' }) do |button| + button.with_leading_visual_icon(icon: :plus) + Project.model_name.human + end if @current_user.allowed_globally?(:add_project) + + subheader.with_bottom_pane_component(mt: 0) do + render(Projects::ProjectsFiltersComponent.new(query: @query)) + end + end %> diff --git a/app/components/projects/index_sub_header_component.rb b/app/components/projects/index_sub_header_component.rb new file mode 100644 index 000000000000..cbd16be7fa47 --- /dev/null +++ b/app/components/projects/index_sub_header_component.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +# -- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2010-2024 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +# ++ + +module Projects + # rubocop:disable OpenProject/AddPreviewForViewComponent + class IndexSubHeaderComponent < ApplicationComponent + # rubocop:enable OpenProject/AddPreviewForViewComponent + include ApplicationHelper + + def initialize(query:, current_user:, disable_buttons: nil) + super + @query = query + @current_user = current_user + @disable_buttons = disable_buttons + end + end +end diff --git a/app/components/projects/settings/project_custom_field_sections/index_component.html.erb b/app/components/projects/settings/project_custom_field_sections/index_component.html.erb index 6a85a3914204..3c31b3294e78 100644 --- a/app/components/projects/settings/project_custom_field_sections/index_component.html.erb +++ b/app/components/projects/settings/project_custom_field_sections/index_component.html.erb @@ -11,7 +11,6 @@ icon: :search, size: :small }, - input_width: :xlarge, show_clear_button: true, clear_button_id: "project-custom-fields-mapping-filter-clear-button", data: { diff --git a/app/components/settings/project_custom_fields/header_component.html.erb b/app/components/settings/project_custom_fields/header_component.html.erb index a9fe5181caff..d05b23f37dd9 100644 --- a/app/components/settings/project_custom_fields/header_component.html.erb +++ b/app/components/settings/project_custom_fields/header_component.html.erb @@ -1,34 +1,36 @@ -<%= - render Primer::OpenProject::PageHeader.new do |header| - header.with_title(variant: :default) { t("settings.project_attributes.heading") } - header.with_description { t("settings.project_attributes.heading_description") } - header.with_breadcrumbs(breadcrumbs_items) - end -%> +<%= component_wrapper do %> + <%= + render Primer::OpenProject::PageHeader.new do |header| + header.with_title(variant: :default) { t("settings.project_attributes.heading") } + header.with_description { t("settings.project_attributes.heading_description") } + header.with_breadcrumbs(breadcrumbs_items) + end + %> -<%= - render Primer::OpenProject::SubHeader.new do |subheader| - subheader.with_action_component do - render(Primer::Alpha::Dialog.new(id: "project-custom-field-section-dialog", title: t('settings.project_attributes.label_new_section'), size: :medium_portrait)) do |dialog| - dialog.with_show_button('aria-label': t('settings.project_attributes.label_new_section')) do |button| - button.with_leading_visual_icon(icon: :plus) - t('settings.project_attributes.label_new_section') - end - dialog.with_body do - render(Settings::ProjectCustomFieldSections::DialogBodyFormComponent.new) + <%= + render Primer::OpenProject::SubHeader.new do |subheader| + subheader.with_action_component do + render(Primer::Alpha::Dialog.new(id: "project-custom-field-section-dialog", title: t('settings.project_attributes.label_new_section'), size: :medium_portrait)) do |dialog| + dialog.with_show_button('aria-label': t('settings.project_attributes.label_new_section')) do |button| + button.with_leading_visual_icon(icon: :plus) + t('settings.project_attributes.label_new_section') + end + dialog.with_body do + render(Settings::ProjectCustomFieldSections::DialogBodyFormComponent.new) + end end end - end - subheader.with_action_button(tag: :a, - href: new_admin_settings_project_custom_field_path(type: "ProjectCustomField"), - scheme: :primary, - data: { turbo: "false", test_selector: "new-project-custom-field-button" }, - mobile_icon: :plus, - mobile_label: t("settings.project_attributes.label_new_attribute")) do |button| - button.with_leading_visual_icon(icon: :plus) - t("settings.project_attributes.label_new_attribute") - end + subheader.with_action_button(tag: :a, + href: new_admin_settings_project_custom_field_path(type: "ProjectCustomField"), + scheme: :primary, + data: { turbo: "false", test_selector: "new-project-custom-field-button" }, + mobile_icon: :plus, + mobile_label: t("settings.project_attributes.label_new_attribute")) do |button| + button.with_leading_visual_icon(icon: :plus) + t("settings.project_attributes.label_new_attribute") + end - end -%> + end + %> +<% end %> diff --git a/app/views/projects/index.html.erb b/app/views/projects/index.html.erb index 88c3662c188b..de20141c7b9f 100644 --- a/app/views/projects/index.html.erb +++ b/app/views/projects/index.html.erb @@ -38,33 +38,8 @@ See COPYRIGHT and LICENSE files for more details. ) ) %> - <%= - disable_extra_controls = state == :rename - render(Primer::OpenProject::SubHeader.new(data: { - controller: "filters", - "application-target": "dynamic", - })) do |subheader| - subheader.with_filter_component do - render(Filter::FilterButtonComponent.new(query:)) - end - - subheader.with_action_button(tag: :a, - href: new_project_path, - scheme: :primary, - disabled: disable_extra_controls, - size: :medium, - aria: { label: I18n.t(:label_project_new) }, - data: { 'test-selector': 'project-new-button' }) do |button| - button.with_leading_visual_icon(icon: :plus) - Project.model_name.human - end if current_user.allowed_globally?(:add_project) - - subheader.with_bottom_pane_component(mt: 0) do - render(Projects::ProjectsFiltersComponent.new(query:, disabled: disable_extra_controls)) - end - end - %> + <%= render(Projects::IndexSubHeaderComponent.new(query:, current_user:, disable_buttons: state === :rename)) %> <%= render Projects::TableComponent.new( query:, diff --git a/modules/storages/app/views/storages/admin/storages/index.html.erb b/modules/storages/app/views/storages/admin/storages/index.html.erb index 4dfc4ffa26a9..db38dbc49303 100644 --- a/modules/storages/app/views/storages/admin/storages/index.html.erb +++ b/modules/storages/app/views/storages/admin/storages/index.html.erb @@ -19,7 +19,8 @@ end %> render(Primer::Alpha::ActionMenu.new(test_selector: 'storages-select-provider-action-menu', anchor_align: :end)) do |menu| menu.with_show_button(scheme: :primary, - aria: { label: I18n.t("storages.label_add_new_storage") }) do |button| + aria: { label: I18n.t("storages.label_add_new_storage") }, + test_selector: "storages-create-new-provider-button") do |button| button.with_leading_visual_icon(icon: :plus) button.with_trailing_action_icon(icon: :"triangle-down") I18n.t("storages.label_storage") diff --git a/modules/storages/spec/features/storages/admin/create_storage_spec.rb b/modules/storages/spec/features/storages/admin/create_storage_spec.rb index 08434f5cd136..620e1a3eee7e 100644 --- a/modules/storages/spec/features/storages/admin/create_storage_spec.rb +++ b/modules/storages/spec/features/storages/admin/create_storage_spec.rb @@ -50,8 +50,8 @@ expect(page).to be_axe_clean.within "#content" - within(".PageHeader-titleBar") do - click_on("Storage") + within(".SubHeader") do + page.find_test_selector("storages-create-new-provider-button").click within_test_selector("storages-select-provider-action-menu") { click_on("Nextcloud") } end @@ -193,8 +193,8 @@ it "renders enterprise icon and redirects to upsale", :webmock do visit admin_settings_storages_path - within(".PageHeader-titleBar") do - click_on("Storage") + within(".SubHeader") do + page.find_test_selector("storages-create-new-provider-button").click within_test_selector("storages-select-provider-action-menu") do expect(page).to have_css(".octicon-op-enterprise-addons") @@ -213,9 +213,8 @@ expect(page).to be_axe_clean.within "#content" - within(".PageHeader-titleBar") do - click_on("Storage") - + within(".SubHeader") do + page.find_test_selector("storages-create-new-provider-button").click within_test_selector("storages-select-provider-action-menu") { click_on("OneDrive/SharePoint") } end From d5064b7e23e4d87e57cf876b8dd0c3a039d0fc4d Mon Sep 17 00:00:00 2001 From: dominic-braeunlein Date: Wed, 5 Jun 2024 14:43:46 +0200 Subject: [PATCH 161/176] Revert "Sync `package-lock.json` with `package.json`" --- frontend/package-lock.json | 2636 ++++++++++++++---------------------- 1 file changed, 1000 insertions(+), 1636 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 152a7800cfff..f368c4bca0cb 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -54,6 +54,7 @@ "@uirouter/angular": "^13.0.0", "@uirouter/core": "^6.1.0", "@uirouter/rx": "^1.0.0", + "@vusion/webfonts-generator": "^0.8.0", "@w11k/ngx-componentdestroyed": "^5.0.2", "@xeokit/xeokit-bim-viewer": "2.5.1-beta-28", "autoprefixer": "^10.4.19", @@ -102,7 +103,6 @@ "typedjson": "^1.5.1", "urijs": "^1.19.11", "uuid": "^8.3.2", - "webfonts-generator-casaper": "^0.5.2", "zone.js": "~0.14.4" }, "devDependencies": { @@ -5328,6 +5328,14 @@ "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==", "dev": true }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "engines": { + "node": ">= 10" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", @@ -6398,6 +6406,172 @@ "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" } }, + "node_modules/@vusion/webfonts-generator": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@vusion/webfonts-generator/-/webfonts-generator-0.8.0.tgz", + "integrity": "sha512-1q17CF6umBEjlAtO37TzRw3aOCCAyFX+T4HPG70BmM6qx8s6H4/LQOa8eHFZq/oiMuMyd0FehKgUt/pqYlIMWA==", + "dependencies": { + "handlebars": "^4.0.11", + "mkdirp": "^1.0.4", + "q": "^1.1.2", + "svg2ttf": "^6.0.3", + "svgicons2svgfont": "^10.0.4", + "ttf2eot": "^3.0.0", + "ttf2woff": "^3.0.0", + "ttf2woff2": "^4.0.4", + "underscore": "^1.9.1", + "url-join": "^4.0.0" + } + }, + "node_modules/@vusion/webfonts-generator/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/@vusion/webfonts-generator/node_modules/bufferstreams": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bufferstreams/-/bufferstreams-3.0.0.tgz", + "integrity": "sha512-Qg0ggJUWJq90vtg4lDsGN9CDWvzBMQxhiEkSOD/sJfYt6BLect3eV1/S6K7SCSKJ34n60rf6U5eUPmQENVE4UA==", + "dependencies": { + "readable-stream": "^3.4.0" + }, + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/@vusion/webfonts-generator/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@vusion/webfonts-generator/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@vusion/webfonts-generator/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@vusion/webfonts-generator/node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, + "node_modules/@vusion/webfonts-generator/node_modules/svg-pathdata": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/svg-pathdata/-/svg-pathdata-6.0.3.tgz", + "integrity": "sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw==", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@vusion/webfonts-generator/node_modules/svg2ttf": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/svg2ttf/-/svg2ttf-6.0.3.tgz", + "integrity": "sha512-CgqMyZrbOPpc+WqH7aga4JWkDPso23EgypLsbQ6gN3uoPWwwiLjXvzgrwGADBExvCRJrWFzAeK1bSoSpE7ixSQ==", + "dependencies": { + "@xmldom/xmldom": "^0.7.2", + "argparse": "^2.0.1", + "cubic2quad": "^1.2.1", + "lodash": "^4.17.10", + "microbuffer": "^1.0.0", + "svgpath": "^2.1.5" + }, + "bin": { + "svg2ttf": "svg2ttf.js" + } + }, + "node_modules/@vusion/webfonts-generator/node_modules/svgicons2svgfont": { + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/svgicons2svgfont/-/svgicons2svgfont-10.0.6.tgz", + "integrity": "sha512-fUgQEVg3XwTbOHvlXahHGqCet5Wvfo1bV4DCvbSRvjsOCPCRunYbG4dUJCPegps37BMph3eOrfoobhH5AWuC6A==", + "dependencies": { + "commander": "^7.2.0", + "geometry-interfaces": "^1.1.4", + "glob": "^7.1.6", + "neatequal": "^1.0.0", + "readable-stream": "^3.4.0", + "sax": "^1.2.4", + "svg-pathdata": "^6.0.0" + }, + "bin": { + "svgicons2svgfont": "bin/svgicons2svgfont.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@vusion/webfonts-generator/node_modules/ttf2eot": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/ttf2eot/-/ttf2eot-3.1.0.tgz", + "integrity": "sha512-aHTbcYosNHVqb2Qtt9Xfta77ae/5y0VfdwNLUS6sGBeGr22cX2JDMo/i5h3uuOf+FAD3akYOr17+fYd5NK8aXw==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "ttf2eot": "ttf2eot.js" + } + }, + "node_modules/@vusion/webfonts-generator/node_modules/ttf2woff": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ttf2woff/-/ttf2woff-3.0.0.tgz", + "integrity": "sha512-OvmFcj70PhmAsVQKfC15XoKH55cRWuaRzvr2fpTNhTNer6JBpG8n6vOhRrIgxMjcikyYt88xqYXMMVapJ4Rjvg==", + "dependencies": { + "argparse": "^2.0.1", + "pako": "^1.0.0" + }, + "bin": { + "ttf2woff": "ttf2woff.js" + } + }, + "node_modules/@vusion/webfonts-generator/node_modules/ttf2woff2": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/ttf2woff2/-/ttf2woff2-4.0.5.tgz", + "integrity": "sha512-zpoU0NopfjoyVqkFeQ722SyKk/n607mm5OHxuDS/wCCSy82B8H3hHXrezftA2KMbKqfJIjie2lsJHdvPnBGbsw==", + "hasInstallScript": true, + "dependencies": { + "bindings": "^1.5.0", + "bufferstreams": "^3.0.0", + "nan": "^2.14.2", + "node-gyp": "^9.0.0" + }, + "bin": { + "ttf2woff2": "bin/ttf2woff2.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@vusion/webfonts-generator/node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" + }, "node_modules/@w11k/ngx-componentdestroyed": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/@w11k/ngx-componentdestroyed/-/ngx-componentdestroyed-5.0.2.tgz", @@ -6561,6 +6735,14 @@ "html2canvas": "^1.4.1" } }, + "node_modules/@xmldom/xmldom": { + "version": "0.7.13", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.13.tgz", + "integrity": "sha512-lm2GW5PkosIzccsaZIz7tp8cPADSIlIHWDFTR1N0SzfinhhYgeIQjFMz4rYzanCScr3DqQLeomUDArp6MWKm+g==", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", @@ -6685,6 +6867,28 @@ "node": ">=8.9.0" } }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/agentkeepalive": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", + "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, "node_modules/aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -7175,6 +7379,23 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz", "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==" }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + }, + "node_modules/are-we-there-yet": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", + "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -7236,6 +7457,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, "dependencies": { "call-bind": "^1.0.5", "is-array-buffer": "^3.0.4" @@ -7422,6 +7644,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.5", @@ -7439,24 +7662,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "license": "MIT", - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, "node_modules/assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", @@ -7481,7 +7686,8 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true }, "node_modules/atoa": { "version": "1.0.0", @@ -7549,6 +7755,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, "dependencies": { "possible-typed-array-names": "^1.0.0" }, @@ -7559,21 +7766,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "license": "Apache-2.0", - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.0.tgz", - "integrity": "sha512-3AungXC4I8kKsS9PuS4JH2nc+0bVY/mjgrephHTIi8fpEeGsTHBUJeosp0Wc1myYMElmD0B3Oc4XL/HVJ4PV2g==", - "license": "MIT" - }, "node_modules/axe-core": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", @@ -7832,15 +8024,6 @@ "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "license": "BSD-3-Clause", - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, "node_modules/big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", @@ -8062,48 +8245,6 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, - "node_modules/bufferstreams": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/bufferstreams/-/bufferstreams-2.0.1.tgz", - "integrity": "sha512-ZswyIoBfFb3cVDsnZLLj2IDJ/0ppYdil/v2EGlZXvoefO689FokEmFEldhN5dV7R2QBxFneqTJOMIpfqhj+n0g==", - "license": "MIT", - "dependencies": { - "readable-stream": "^2.3.6" - }, - "engines": { - "node": ">=6.9.5" - } - }, - "node_modules/bufferstreams/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "license": "MIT" - }, - "node_modules/bufferstreams/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/bufferstreams/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, "node_modules/builtins": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.1.0.tgz", @@ -8125,6 +8266,79 @@ "node": ">= 0.8" } }, + "node_modules/cacache": { + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-17.1.3.tgz", + "integrity": "sha512-jAdjGxmPxZh0IipMdR7fK/4sDSrHMLUV0+GvVUsjwyGNKHsh79kW/otg+GkbXwl6Uzvy9wsvHOX4nUoWldeZMg==", + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/cacache/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/cacache/node_modules/glob": { + "version": "10.3.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.3.tgz", + "integrity": "sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw==", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.0.3", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/cacache/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/cache-base": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", @@ -8210,12 +8424,6 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "license": "Apache-2.0" - }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -8405,15 +8613,6 @@ "node": ">=6" } }, - "node_modules/code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/codemirror": { "version": "5.65.16", "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.16.tgz", @@ -8448,6 +8647,14 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "bin": { + "color-support": "bin.js" + } + }, "node_modules/colorette": { "version": "2.0.20", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", @@ -8466,6 +8673,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -9195,22 +9403,11 @@ "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", "dev": true }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/data-view-buffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -9227,6 +9424,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -9243,6 +9441,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -9411,6 +9610,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -9451,6 +9651,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, "engines": { "node": ">=0.4.0" } @@ -9698,16 +9899,6 @@ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "license": "MIT", - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -9931,6 +10122,7 @@ "version": "1.23.3", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.1", "arraybuffer.prototype.slice": "^1.0.3", @@ -10045,6 +10237,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, "dependencies": { "es-errors": "^1.3.0" }, @@ -10056,6 +10249,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, "dependencies": { "get-intrinsic": "^1.2.4", "has-tostringtag": "^1.0.2", @@ -10078,6 +10272,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -11207,7 +11402,8 @@ "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true }, "node_modules/extend-shallow": { "version": "2.0.1", @@ -11264,15 +11460,6 @@ "node": ">=0.10.0" } }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "engines": [ - "node >=0.6.0" - ], - "license": "MIT" - }, "node_modules/eyes": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", @@ -11591,6 +11778,7 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, "dependencies": { "is-callable": "^1.1.3" } @@ -11642,15 +11830,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "license": "Apache-2.0", - "engines": { - "node": "*" - } - }, "node_modules/form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -11780,6 +11959,7 @@ "version": "1.1.6", "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -11797,10 +11977,29 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gauge": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -11915,6 +12114,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dev": true, "dependencies": { "call-bind": "^1.0.5", "es-errors": "^1.3.0", @@ -11936,15 +12136,6 @@ "node": ">=0.10.0" } }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0" - } - }, "node_modules/gl-matrix": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.4.3.tgz", @@ -12025,6 +12216,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, "dependencies": { "define-properties": "^1.1.3" }, @@ -12375,55 +12567,11 @@ "node": ">=0.10.0" } }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", - "license": "ISC", - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", - "license": "MIT", - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/har-validator/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/har-validator/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "license": "MIT" - }, "node_modules/has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -12473,6 +12621,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, "dependencies": { "has-symbols": "^1.0.3" }, @@ -12794,6 +12943,19 @@ "node": ">=8.0.0" } }, + "node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/http-proxy-middleware": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", @@ -12912,19 +13074,16 @@ "node": ">=8" } }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "license": "MIT", + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" + "agent-base": "6", + "debug": "4" }, "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" + "node": ">= 6" } }, "node_modules/human-signals": { @@ -12935,6 +13094,14 @@ "node": ">=10.17.0" } }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "dependencies": { + "ms": "^2.0.0" + } + }, "node_modules/i18n-js": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/i18n-js/-/i18n-js-4.4.3.tgz", @@ -13198,6 +13365,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dev": true, "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.0", @@ -13241,6 +13409,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dev": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.1" @@ -13276,6 +13445,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, "dependencies": { "has-bigints": "^1.0.1" }, @@ -13298,6 +13468,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -13313,6 +13484,7 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -13347,6 +13519,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dev": true, "dependencies": { "is-typed-array": "^1.1.13" }, @@ -13361,6 +13534,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -13499,6 +13673,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -13519,6 +13694,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -13595,6 +13771,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -13631,6 +13808,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dev": true, "dependencies": { "call-bind": "^1.0.7" }, @@ -13656,6 +13834,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -13670,6 +13849,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, "dependencies": { "has-symbols": "^1.0.2" }, @@ -13684,6 +13864,7 @@ "version": "1.1.13", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, "dependencies": { "which-typed-array": "^1.1.14" }, @@ -13694,12 +13875,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "license": "MIT" - }, "node_modules/is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", @@ -13724,6 +13899,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, "dependencies": { "call-bind": "^1.0.2" }, @@ -13772,7 +13948,8 @@ "node_modules/isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true }, "node_modules/isbinaryfile": { "version": "4.0.10", @@ -13813,12 +13990,6 @@ "ws": "*" } }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "license": "MIT" - }, "node_modules/istanbul-lib-coverage": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", @@ -14268,12 +14439,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "license": "MIT" - }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -14307,12 +14472,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "license": "(AFL-2.1 OR BSD-3-Clause)" - }, "node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -14327,7 +14486,8 @@ "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true }, "node_modules/json5": { "version": "2.2.3", @@ -14381,21 +14541,6 @@ "node": "*" } }, - "node_modules/jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "license": "MIT", - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, "node_modules/jsx-ast-utils": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", @@ -15152,6 +15297,39 @@ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" }, + "node_modules/make-fetch-happen": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", + "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^17.0.0", + "http-cache-semantics": "^4.1.1", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "engines": { + "node": ">=12" + } + }, "node_modules/make-plural": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-7.3.0.tgz", @@ -15420,6 +15598,33 @@ "node": ">=8" } }, + "node_modules/minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-collect/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-collect/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, "node_modules/minipass-fetch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.3.tgz", @@ -15891,6 +16096,30 @@ "node": ">= 6.13.0" } }, + "node_modules/node-gyp": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.0.tgz", + "integrity": "sha512-dMXsYP6gc9rRbejLXmTbVRYjAHw7ppswsKyMxuxJxxOHzluIO1rGp9TOQgjFJ+2MCqcOcQTOPB/8Xwhr+7s4Eg==", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^11.0.3", + "nopt": "^6.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^12.13 || ^14.13 || >=16" + } + }, "node_modules/node-gyp-build": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", @@ -15902,6 +16131,25 @@ "node-gyp-build-test": "build-test.js" } }, + "node_modules/node-gyp/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -15919,6 +16167,20 @@ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" }, + "node_modules/nopt": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", + "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", + "dependencies": { + "abbrev": "^1.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, "node_modules/normalize-package-data": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.0.tgz", @@ -16168,6 +16430,20 @@ "node": ">=8" } }, + "node_modules/npmlog": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", + "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "dependencies": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.3", + "set-blocking": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, "node_modules/nth-check": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", @@ -16179,15 +16455,6 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, - "node_modules/number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/nx": { "version": "18.2.4", "resolved": "https://registry.npmjs.org/nx/-/nx-18.2.4.tgz", @@ -16395,19 +16662,11 @@ "node": ">=8" } }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "license": "Apache-2.0", - "engines": { - "node": "*" - } - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -16481,6 +16740,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, "engines": { "node": ">= 0.4" } @@ -16501,6 +16761,7 @@ "version": "4.1.5", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, "dependencies": { "call-bind": "^1.0.5", "define-properties": "^1.2.1", @@ -16785,15 +17046,6 @@ "node": ">=8" } }, - "node_modules/os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", @@ -16802,17 +17054,6 @@ "node": ">=0.10.0" } }, - "node_modules/osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "deprecated": "This package is no longer supported.", - "license": "ISC", - "dependencies": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -17187,12 +17428,6 @@ "node": ">=8" } }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "license": "MIT" - }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -17358,6 +17593,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, "engines": { "node": ">= 0.4" } @@ -17611,12 +17847,6 @@ "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", "optional": true }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "license": "MIT" - }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -17970,6 +18200,7 @@ "version": "1.5.2", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "dev": true, "dependencies": { "call-bind": "^1.0.6", "define-properties": "^1.2.1", @@ -18081,71 +18312,6 @@ "node": ">=0.10" } }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "license": "Apache-2.0", - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/request/node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/request/node_modules/qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/request/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "license": "MIT", - "bin": { - "uuid": "bin/uuid" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -18396,6 +18562,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "dev": true, "dependencies": { "call-bind": "^1.0.7", "get-intrinsic": "^1.2.4", @@ -18427,6 +18594,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dev": true, "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -18860,6 +19028,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -19206,6 +19375,19 @@ "npm": ">= 3.0.0" } }, + "node_modules/socks-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", + "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/source-map": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", @@ -19555,31 +19737,6 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, - "node_modules/sshpk": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", - "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", - "license": "MIT", - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/ssri": { "version": "10.0.4", "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.4.tgz", @@ -19756,17 +19913,6 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, - "node_modules/string.fromcodepoint": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/string.fromcodepoint/-/string.fromcodepoint-0.2.1.tgz", - "integrity": "sha512-n69H31OnxSGSZyZbgBlvYIXlrMhJQ0dQAX1js1QDhpaUH6zmU3QYlj07bCwCNlPOu3oRXIubGPl2gDGnHsiCqg==" - }, - "node_modules/string.prototype.codepointat": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz", - "integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==", - "license": "MIT" - }, "node_modules/string.prototype.matchall": { "version": "4.0.11", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", @@ -19797,6 +19943,7 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -19814,6 +19961,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -19827,6 +19975,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -19944,110 +20093,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/svg-pathdata": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/svg-pathdata/-/svg-pathdata-5.0.5.tgz", - "integrity": "sha512-TAAvLNSE3fEhyl/Da19JWfMAdhSXTYeviXsLSoDT1UM76ADj5ndwAPX1FKQEgB/gFMPavOy6tOqfalXKUiXrow==", - "license": "MIT", - "engines": { - "node": ">=6.9.5" - } - }, - "node_modules/svg2ttf": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/svg2ttf/-/svg2ttf-5.2.0.tgz", - "integrity": "sha512-CzxPnSm2/CrMnJuKlXVllOx+q9wuarbIMi4Vf14eJoeESRqAOxVZiH0Ias71mhyXYGgz88A4T/E8fN/Y8eXoYA==", - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1", - "cubic2quad": "^1.0.0", - "lodash": "^4.17.10", - "microbuffer": "^1.0.0", - "svgpath": "^2.1.5", - "xmldom": "~0.5.0" - }, - "bin": { - "svg2ttf": "svg2ttf.js" - } - }, - "node_modules/svg2ttf/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "license": "Python-2.0" - }, - "node_modules/svgicons2svgfont": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/svgicons2svgfont/-/svgicons2svgfont-9.2.0.tgz", - "integrity": "sha512-mWeiuob7L2ZTcnAEP4JvSQ1pnIsGjV16ykQ0fCiiXqoUAQ/iNsDvBc601ojjfP89eCPtr3IVZ9mDxYpdxYO3xQ==", - "license": "MIT", - "dependencies": { - "array.prototype.flatmap": "1.2.4", - "commander": "^4.0.1", - "geometry-interfaces": "^1.1.4", - "glob": "^7.1.6", - "neatequal": "^1.0.0", - "readable-stream": "^3.4.0", - "sax": "^1.2.4", - "string.fromcodepoint": "^0.2.1", - "string.prototype.codepointat": "^0.2.1", - "svg-pathdata": "^5.0.2" - }, - "bin": { - "svgicons2svgfont": "bin/svgicons2svgfont.js" - }, - "engines": { - "node": ">=6.9.5" - } - }, - "node_modules/svgicons2svgfont/node_modules/array.prototype.flatmap": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz", - "integrity": "sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/svgicons2svgfont/node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/svgicons2svgfont/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/svgpath": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/svgpath/-/svgpath-2.6.0.tgz", @@ -20705,19 +20750,6 @@ "node": ">=6" } }, - "node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "license": "BSD-3-Clause", - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", @@ -20792,346 +20824,6 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==" }, - "node_modules/ttf2eot": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ttf2eot/-/ttf2eot-2.0.0.tgz", - "integrity": "sha512-U56aG2Ylw7psLOmakjemAzmpqVgeadwENg9oaDjaZG5NYX4WB6+7h74bNPcc+0BXsoU5A/XWiHabDXyzFOmsxQ==", - "license": "MIT", - "dependencies": { - "argparse": "^1.0.6", - "microbuffer": "^1.0.0" - }, - "bin": { - "ttf2eot": "ttf2eot.js" - } - }, - "node_modules/ttf2woff": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ttf2woff/-/ttf2woff-2.0.2.tgz", - "integrity": "sha512-X68badwBjAy/+itU49scLjXUL094up+rHuYk+YAOTTBYSUMOmLZ7VyhZJuqQESj1gnyLAC2/5V8Euv+mExmyPA==", - "license": "MIT", - "dependencies": { - "argparse": "^1.0.6", - "microbuffer": "^1.0.0", - "pako": "^1.0.0" - }, - "bin": { - "ttf2woff": "ttf2woff.js" - } - }, - "node_modules/ttf2woff/node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "license": "(MIT AND Zlib)" - }, - "node_modules/ttf2woff2": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ttf2woff2/-/ttf2woff2-3.0.0.tgz", - "integrity": "sha512-5/Web6B0lF/STNAQ0d5vAlRRquuWsNj8wOmKQ9ql9Bsgbx8MsLnNzaBG9vBcSE4s4Ry1QOr/MyUrDUIVgVPEfw==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "bindings": "^1.3.0", - "bufferstreams": "^2.0.1", - "nan": "^2.10.0", - "node-gyp": "^4.0.0" - }, - "bin": { - "ttf2woff2": "bin/ttf2woff2.js" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/ttf2woff2/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ttf2woff2/node_modules/aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "license": "ISC" - }, - "node_modules/ttf2woff2/node_modules/are-we-there-yet": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", - "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", - "deprecated": "This package is no longer supported.", - "license": "ISC", - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "node_modules/ttf2woff2/node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "license": "ISC" - }, - "node_modules/ttf2woff2/node_modules/fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "license": "ISC", - "dependencies": { - "minipass": "^2.6.0" - } - }, - "node_modules/ttf2woff2/node_modules/gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==", - "deprecated": "This package is no longer supported.", - "license": "ISC", - "dependencies": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "node_modules/ttf2woff2/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/ttf2woff2/node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", - "license": "MIT", - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ttf2woff2/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "license": "MIT" - }, - "node_modules/ttf2woff2/node_modules/minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "license": "ISC", - "dependencies": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "node_modules/ttf2woff2/node_modules/minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "license": "MIT", - "dependencies": { - "minipass": "^2.9.0" - } - }, - "node_modules/ttf2woff2/node_modules/node-gyp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-4.0.0.tgz", - "integrity": "sha512-2XiryJ8sICNo6ej8d0idXDEMKfVfFK7kekGCtJAuelGsYHQxhj13KTf95swTCN2dZ/4lTfZ84Fu31jqJEEgjWA==", - "license": "MIT", - "dependencies": { - "glob": "^7.0.3", - "graceful-fs": "^4.1.2", - "mkdirp": "^0.5.0", - "nopt": "2 || 3", - "npmlog": "0 || 1 || 2 || 3 || 4", - "osenv": "0", - "request": "^2.87.0", - "rimraf": "2", - "semver": "~5.3.0", - "tar": "^4.4.8", - "which": "1" - }, - "bin": { - "node-gyp": "bin/node-gyp.js" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/ttf2woff2/node_modules/nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", - "license": "ISC", - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - } - }, - "node_modules/ttf2woff2/node_modules/npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "deprecated": "This package is no longer supported.", - "license": "ISC", - "dependencies": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "node_modules/ttf2woff2/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/ttf2woff2/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/ttf2woff2/node_modules/semver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha512-mfmm3/H9+67MCVix1h+IXTpDwL6710LyHuk7+cWC9T1mE0qz4iHhh6r4hU2wrIT9iTsAAC2XQRvfblL028cpLw==", - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/ttf2woff2/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/ttf2woff2/node_modules/string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", - "license": "MIT", - "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ttf2woff2/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ttf2woff2/node_modules/tar": { - "version": "4.4.19", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", - "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", - "license": "ISC", - "dependencies": { - "chownr": "^1.1.4", - "fs-minipass": "^1.2.7", - "minipass": "^2.9.0", - "minizlib": "^1.3.3", - "mkdirp": "^0.5.5", - "safe-buffer": "^5.2.1", - "yallist": "^3.1.1" - }, - "engines": { - "node": ">=4.5" - } - }, - "node_modules/ttf2woff2/node_modules/tar/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/ttf2woff2/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, "node_modules/tuf-js": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-2.2.0.tgz", @@ -21258,24 +20950,6 @@ "node": ">=16 || 14 >=14.17" } }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "license": "Unlicense" - }, "node_modules/type": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", @@ -21326,6 +21000,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -21339,6 +21014,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -21357,6 +21033,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", @@ -21376,6 +21053,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "dev": true, "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -21490,6 +21168,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, "dependencies": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", @@ -21829,26 +21508,6 @@ "node": ">= 0.8" } }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "engines": [ - "node >=0.6.0" - ], - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/verror/node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "license": "MIT" - }, "node_modules/vite": { "version": "5.1.7", "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.7.tgz", @@ -22367,42 +22026,6 @@ "defaults": "^1.0.3" } }, - "node_modules/webfonts-generator-casaper": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/webfonts-generator-casaper/-/webfonts-generator-casaper-0.5.2.tgz", - "integrity": "sha512-beM/bZ/N+ajdldAwrILYKWnHNgMje9MwetYM52lJ15CLOGliyt82m3g39y2cZoi/Ca+Wqs8NKMhMrNOYYgX6Qg==", - "license": "Unlicense", - "dependencies": { - "handlebars": "^4.0.5", - "mkdirp": "^1.0.4", - "q": "^1.1.2", - "svg2ttf": "^5.0.0", - "svgicons2svgfont": "^9.1.1", - "ttf2eot": "^2.0.0", - "ttf2woff": "^2.0.1", - "ttf2woff2": "^3.0.0", - "underscore": "^1.7.0", - "url-join": "^4.0.1" - } - }, - "node_modules/webfonts-generator-casaper/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/webfonts-generator-casaper/node_modules/url-join": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", - "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", - "license": "MIT" - }, "node_modules/webpack": { "version": "5.90.3", "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.3.tgz", @@ -22840,6 +22463,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, "dependencies": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", @@ -22896,6 +22520,7 @@ "version": "1.1.15", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dev": true, "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", @@ -23040,15 +22665,6 @@ "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==", "dev": true }, - "node_modules/xmldom": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.5.0.tgz", - "integrity": "sha512-Foaj5FXVzgn7xFzsKeNIde9g6aFBxTPi37iwsno8QvApmtg7KYrr+OPyRHcJF7dud2a5nGRBXK3n0dL62Gf7PA==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -26603,6 +26219,11 @@ "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==", "dev": true }, + "@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==" + }, "@tsconfig/node10": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", @@ -27384,6 +27005,131 @@ "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.1.0.tgz", "integrity": "sha512-wO4Dk/rm8u7RNhOf95ZzcEmC9rYOncYgvq4z3duaJrCgjN8BxAnDVyndanfcJZ0O6XZzHz6Q0hTimxTg8Y9g/A==" }, + "@vusion/webfonts-generator": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@vusion/webfonts-generator/-/webfonts-generator-0.8.0.tgz", + "integrity": "sha512-1q17CF6umBEjlAtO37TzRw3aOCCAyFX+T4HPG70BmM6qx8s6H4/LQOa8eHFZq/oiMuMyd0FehKgUt/pqYlIMWA==", + "requires": { + "handlebars": "^4.0.11", + "mkdirp": "^1.0.4", + "q": "^1.1.2", + "svg2ttf": "^6.0.3", + "svgicons2svgfont": "^10.0.4", + "ttf2eot": "^3.0.0", + "ttf2woff": "^3.0.0", + "ttf2woff2": "^4.0.4", + "underscore": "^1.9.1", + "url-join": "^4.0.0" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "bufferstreams": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bufferstreams/-/bufferstreams-3.0.0.tgz", + "integrity": "sha512-Qg0ggJUWJq90vtg4lDsGN9CDWvzBMQxhiEkSOD/sJfYt6BLect3eV1/S6K7SCSKJ34n60rf6U5eUPmQENVE4UA==", + "requires": { + "readable-stream": "^3.4.0" + } + }, + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, + "svg-pathdata": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/svg-pathdata/-/svg-pathdata-6.0.3.tgz", + "integrity": "sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw==" + }, + "svg2ttf": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/svg2ttf/-/svg2ttf-6.0.3.tgz", + "integrity": "sha512-CgqMyZrbOPpc+WqH7aga4JWkDPso23EgypLsbQ6gN3uoPWwwiLjXvzgrwGADBExvCRJrWFzAeK1bSoSpE7ixSQ==", + "requires": { + "@xmldom/xmldom": "^0.7.2", + "argparse": "^2.0.1", + "cubic2quad": "^1.2.1", + "lodash": "^4.17.10", + "microbuffer": "^1.0.0", + "svgpath": "^2.1.5" + } + }, + "svgicons2svgfont": { + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/svgicons2svgfont/-/svgicons2svgfont-10.0.6.tgz", + "integrity": "sha512-fUgQEVg3XwTbOHvlXahHGqCet5Wvfo1bV4DCvbSRvjsOCPCRunYbG4dUJCPegps37BMph3eOrfoobhH5AWuC6A==", + "requires": { + "commander": "^7.2.0", + "geometry-interfaces": "^1.1.4", + "glob": "^7.1.6", + "neatequal": "^1.0.0", + "readable-stream": "^3.4.0", + "sax": "^1.2.4", + "svg-pathdata": "^6.0.0" + } + }, + "ttf2eot": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/ttf2eot/-/ttf2eot-3.1.0.tgz", + "integrity": "sha512-aHTbcYosNHVqb2Qtt9Xfta77ae/5y0VfdwNLUS6sGBeGr22cX2JDMo/i5h3uuOf+FAD3akYOr17+fYd5NK8aXw==", + "requires": { + "argparse": "^2.0.1" + } + }, + "ttf2woff": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ttf2woff/-/ttf2woff-3.0.0.tgz", + "integrity": "sha512-OvmFcj70PhmAsVQKfC15XoKH55cRWuaRzvr2fpTNhTNer6JBpG8n6vOhRrIgxMjcikyYt88xqYXMMVapJ4Rjvg==", + "requires": { + "argparse": "^2.0.1", + "pako": "^1.0.0" + } + }, + "ttf2woff2": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/ttf2woff2/-/ttf2woff2-4.0.5.tgz", + "integrity": "sha512-zpoU0NopfjoyVqkFeQ722SyKk/n607mm5OHxuDS/wCCSy82B8H3hHXrezftA2KMbKqfJIjie2lsJHdvPnBGbsw==", + "requires": { + "bindings": "^1.5.0", + "bufferstreams": "^3.0.0", + "nan": "^2.14.2", + "node-gyp": "^9.0.0" + } + }, + "url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" + } + } + }, "@w11k/ngx-componentdestroyed": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/@w11k/ngx-componentdestroyed/-/ngx-componentdestroyed-5.0.2.tgz", @@ -27543,6 +27289,11 @@ "html2canvas": "^1.4.1" } }, + "@xmldom/xmldom": { + "version": "0.7.13", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.13.tgz", + "integrity": "sha512-lm2GW5PkosIzccsaZIz7tp8cPADSIlIHWDFTR1N0SzfinhhYgeIQjFMz4rYzanCScr3DqQLeomUDArp6MWKm+g==" + }, "@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", @@ -27641,6 +27392,22 @@ } } }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "requires": { + "debug": "4" + } + }, + "agentkeepalive": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", + "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", + "requires": { + "humanize-ms": "^1.2.1" + } + }, "aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -28005,6 +27772,20 @@ } } }, + "aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + }, + "are-we-there-yet": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", + "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + } + }, "arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -28054,6 +27835,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, "requires": { "call-bind": "^1.0.5", "is-array-buffer": "^3.0.4" @@ -28194,6 +27976,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, "requires": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.5", @@ -28205,19 +27988,6 @@ "is-shared-array-buffer": "^1.0.2" } }, - "asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" - }, "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", @@ -28239,7 +28009,8 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true }, "atoa": { "version": "1.0.0", @@ -28278,20 +28049,11 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, "requires": { "possible-typed-array-names": "^1.0.0" } }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==" - }, - "aws4": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.0.tgz", - "integrity": "sha512-3AungXC4I8kKsS9PuS4JH2nc+0bVY/mjgrephHTIi8fpEeGsTHBUJeosp0Wc1myYMElmD0B3Oc4XL/HVJ4PV2g==" - }, "axe-core": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", @@ -28487,14 +28249,6 @@ "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "requires": { - "tweetnacl": "^0.14.3" - } - }, "big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", @@ -28655,43 +28409,6 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, - "bufferstreams": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/bufferstreams/-/bufferstreams-2.0.1.tgz", - "integrity": "sha512-ZswyIoBfFb3cVDsnZLLj2IDJ/0ppYdil/v2EGlZXvoefO689FokEmFEldhN5dV7R2QBxFneqTJOMIpfqhj+n0g==", - "requires": { - "readable-stream": "^2.3.6" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, "builtins": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.1.0.tgz", @@ -28710,6 +28427,60 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==" }, + "cacache": { + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-17.1.3.tgz", + "integrity": "sha512-jAdjGxmPxZh0IipMdR7fK/4sDSrHMLUV0+GvVUsjwyGNKHsh79kW/otg+GkbXwl6Uzvy9wsvHOX4nUoWldeZMg==", + "requires": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "glob": { + "version": "10.3.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.3.tgz", + "integrity": "sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw==", + "requires": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.0.3", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + } + }, + "lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==" + }, + "minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, "cache-base": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", @@ -28763,11 +28534,6 @@ "rsvp": "^4.8.4" } }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" - }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -28903,11 +28669,6 @@ "shallow-clone": "^3.0.0" } }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==" - }, "codemirror": { "version": "5.65.16", "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.16.tgz", @@ -28936,6 +28697,11 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" + }, "colorette": { "version": "2.0.20", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", @@ -28951,6 +28717,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -29487,18 +29254,11 @@ "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", "dev": true }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "requires": { - "assert-plus": "^1.0.0" - } - }, "data-view-buffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, "requires": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -29509,6 +29269,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, "requires": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -29519,6 +29280,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, "requires": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -29646,6 +29408,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, "requires": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -29670,7 +29433,8 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true }, "delegates": { "version": "1.0.0", @@ -29863,15 +29627,6 @@ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -30039,6 +29794,7 @@ "version": "1.23.3", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "dev": true, "requires": { "array-buffer-byte-length": "^1.0.1", "arraybuffer.prototype.slice": "^1.0.3", @@ -30138,6 +29894,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, "requires": { "es-errors": "^1.3.0" } @@ -30146,6 +29903,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, "requires": { "get-intrinsic": "^1.2.4", "has-tostringtag": "^1.0.2", @@ -30165,6 +29923,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, "requires": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -31062,7 +30821,8 @@ "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true }, "extend-shallow": { "version": "2.0.1", @@ -31109,11 +30869,6 @@ "to-regex": "^3.0.1" } }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==" - }, "eyes": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", @@ -31364,6 +31119,7 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, "requires": { "is-callable": "^1.1.3" } @@ -31399,11 +31155,6 @@ } } }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==" - }, "form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -31495,6 +31246,7 @@ "version": "1.1.6", "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -31505,7 +31257,23 @@ "functions-have-names": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==" + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true + }, + "gauge": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "requires": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + } }, "gensync": { "version": "1.0.0-beta.2", @@ -31590,6 +31358,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dev": true, "requires": { "call-bind": "^1.0.5", "es-errors": "^1.3.0", @@ -31602,14 +31371,6 @@ "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", "dev": true }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "requires": { - "assert-plus": "^1.0.0" - } - }, "gl-matrix": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.4.3.tgz", @@ -31671,6 +31432,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, "requires": { "define-properties": "^1.1.3" } @@ -31953,42 +31715,11 @@ "typeof-article": "^0.1.1" } }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==" - }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - } - } - }, "has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==" + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true }, "has-flag": { "version": "3.0.0", @@ -32017,6 +31748,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, "requires": { "has-symbols": "^1.0.3" } @@ -32270,6 +32002,16 @@ "requires-port": "^1.0.0" } }, + "http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "requires": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + } + }, "http-proxy-middleware": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", @@ -32345,14 +32087,13 @@ } } }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" + "agent-base": "6", + "debug": "4" } }, "human-signals": { @@ -32360,6 +32101,14 @@ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==" }, + "humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "requires": { + "ms": "^2.0.0" + } + }, "i18n-js": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/i18n-js/-/i18n-js-4.4.3.tgz", @@ -32543,6 +32292,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dev": true, "requires": { "es-errors": "^1.3.0", "hasown": "^2.0.0", @@ -32577,6 +32327,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dev": true, "requires": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.1" @@ -32600,6 +32351,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, "requires": { "has-bigints": "^1.0.1" } @@ -32616,6 +32368,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, "requires": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -32624,7 +32377,8 @@ "is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==" + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true }, "is-core-module": { "version": "2.13.1", @@ -32647,6 +32401,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dev": true, "requires": { "is-typed-array": "^1.1.13" } @@ -32655,6 +32410,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, "requires": { "has-tostringtag": "^1.0.0" } @@ -32744,7 +32500,8 @@ "is-negative-zero": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==" + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true }, "is-number": { "version": "4.0.0", @@ -32756,6 +32513,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, "requires": { "has-tostringtag": "^1.0.0" } @@ -32813,6 +32571,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, "requires": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -32837,6 +32596,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dev": true, "requires": { "call-bind": "^1.0.7" } @@ -32850,6 +32610,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, "requires": { "has-tostringtag": "^1.0.0" } @@ -32858,6 +32619,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, "requires": { "has-symbols": "^1.0.2" } @@ -32866,15 +32628,11 @@ "version": "1.1.13", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, "requires": { "which-typed-array": "^1.1.14" } }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" - }, "is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", @@ -32890,6 +32648,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, "requires": { "call-bind": "^1.0.2" } @@ -32926,7 +32685,8 @@ "isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true }, "isbinaryfile": { "version": "4.0.10", @@ -32955,11 +32715,6 @@ "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", "dev": true }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" - }, "istanbul-lib-coverage": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", @@ -33292,11 +33047,6 @@ "esprima": "^4.0.0" } }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" - }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -33318,11 +33068,6 @@ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.1.tgz", "integrity": "sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg==" }, - "json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" - }, "json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -33337,7 +33082,8 @@ "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true }, "json5": { "version": "2.2.3", @@ -33374,17 +33120,6 @@ "through": ">=2.2.7 <3" } }, - "jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - } - }, "jsx-ast-utils": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", @@ -33975,6 +33710,35 @@ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" }, + "make-fetch-happen": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", + "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", + "requires": { + "agentkeepalive": "^4.2.1", + "cacache": "^17.0.0", + "http-cache-semantics": "^4.1.1", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^10.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==" + } + } + }, "make-plural": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-7.3.0.tgz", @@ -34175,6 +33939,29 @@ "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==" }, + "minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "requires": { + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, "minipass-fetch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.3.tgz", @@ -34539,6 +34326,39 @@ "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==" }, + "node-gyp": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.0.tgz", + "integrity": "sha512-dMXsYP6gc9rRbejLXmTbVRYjAHw7ppswsKyMxuxJxxOHzluIO1rGp9TOQgjFJ+2MCqcOcQTOPB/8Xwhr+7s4Eg==", + "requires": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^11.0.3", + "nopt": "^6.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, "node-gyp-build": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", @@ -34562,6 +34382,14 @@ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" }, + "nopt": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", + "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", + "requires": { + "abbrev": "^1.0.0" + } + }, "normalize-package-data": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.0.tgz", @@ -34747,6 +34575,17 @@ "path-key": "^3.0.0" } }, + "npmlog": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", + "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "requires": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.3", + "set-blocking": "^2.0.0" + } + }, "nth-check": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", @@ -34755,11 +34594,6 @@ "boolbase": "^1.0.0" } }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==" - }, "nx": { "version": "18.2.4", "resolved": "https://registry.npmjs.org/nx/-/nx-18.2.4.tgz", @@ -34914,15 +34748,11 @@ } } }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true }, "object-copy": { "version": "0.1.0", @@ -34979,7 +34809,8 @@ "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true }, "object-visit": { "version": "1.0.1", @@ -34994,6 +34825,7 @@ "version": "4.1.5", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, "requires": { "call-bind": "^1.0.5", "define-properties": "^1.2.1", @@ -35202,25 +35034,11 @@ } } }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==" - }, "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==" }, - "osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -35492,11 +35310,6 @@ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" - }, "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -35611,7 +35424,8 @@ "possible-typed-array-names": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==" + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true }, "postcss": { "version": "8.4.31", @@ -35777,11 +35591,6 @@ "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", "optional": true }, - "psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" - }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -36045,6 +35854,7 @@ "version": "1.5.2", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "dev": true, "requires": { "call-bind": "^1.0.6", "define-properties": "^1.2.1", @@ -36127,55 +35937,6 @@ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==" }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==" - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - } - } - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -36351,6 +36112,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "dev": true, "requires": { "call-bind": "^1.0.7", "get-intrinsic": "^1.2.4", @@ -36376,6 +36138,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dev": true, "requires": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -36701,6 +36464,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, "requires": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -36967,6 +36731,16 @@ "smart-buffer": "^4.2.0" } }, + "socks-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", + "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", + "requires": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + } + }, "source-map": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", @@ -37239,22 +37013,6 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, - "sshpk": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", - "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, "ssri": { "version": "10.0.4", "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.4.tgz", @@ -37392,16 +37150,6 @@ } } }, - "string.fromcodepoint": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/string.fromcodepoint/-/string.fromcodepoint-0.2.1.tgz", - "integrity": "sha512-n69H31OnxSGSZyZbgBlvYIXlrMhJQ0dQAX1js1QDhpaUH6zmU3QYlj07bCwCNlPOu3oRXIubGPl2gDGnHsiCqg==" - }, - "string.prototype.codepointat": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz", - "integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==" - }, "string.prototype.matchall": { "version": "4.0.11", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", @@ -37426,6 +37174,7 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "dev": true, "requires": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -37437,6 +37186,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "dev": true, "requires": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -37447,6 +37197,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, "requires": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -37521,79 +37272,6 @@ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" }, - "svg-pathdata": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/svg-pathdata/-/svg-pathdata-5.0.5.tgz", - "integrity": "sha512-TAAvLNSE3fEhyl/Da19JWfMAdhSXTYeviXsLSoDT1UM76ADj5ndwAPX1FKQEgB/gFMPavOy6tOqfalXKUiXrow==" - }, - "svg2ttf": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/svg2ttf/-/svg2ttf-5.2.0.tgz", - "integrity": "sha512-CzxPnSm2/CrMnJuKlXVllOx+q9wuarbIMi4Vf14eJoeESRqAOxVZiH0Ias71mhyXYGgz88A4T/E8fN/Y8eXoYA==", - "requires": { - "argparse": "^2.0.1", - "cubic2quad": "^1.0.0", - "lodash": "^4.17.10", - "microbuffer": "^1.0.0", - "svgpath": "^2.1.5", - "xmldom": "~0.5.0" - }, - "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - } - } - }, - "svgicons2svgfont": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/svgicons2svgfont/-/svgicons2svgfont-9.2.0.tgz", - "integrity": "sha512-mWeiuob7L2ZTcnAEP4JvSQ1pnIsGjV16ykQ0fCiiXqoUAQ/iNsDvBc601ojjfP89eCPtr3IVZ9mDxYpdxYO3xQ==", - "requires": { - "array.prototype.flatmap": "1.2.4", - "commander": "^4.0.1", - "geometry-interfaces": "^1.1.4", - "glob": "^7.1.6", - "neatequal": "^1.0.0", - "readable-stream": "^3.4.0", - "sax": "^1.2.4", - "string.fromcodepoint": "^0.2.1", - "string.prototype.codepointat": "^0.2.1", - "svg-pathdata": "^5.0.2" - }, - "dependencies": { - "array.prototype.flatmap": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz", - "integrity": "sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q==", - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "function-bind": "^1.1.1" - } - }, - "commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==" - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, "svgpath": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/svgpath/-/svgpath-2.6.0.tgz", @@ -38112,15 +37790,6 @@ "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", "dev": true }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, "tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", @@ -38170,254 +37839,6 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==" }, - "ttf2eot": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ttf2eot/-/ttf2eot-2.0.0.tgz", - "integrity": "sha512-U56aG2Ylw7psLOmakjemAzmpqVgeadwENg9oaDjaZG5NYX4WB6+7h74bNPcc+0BXsoU5A/XWiHabDXyzFOmsxQ==", - "requires": { - "argparse": "^1.0.6", - "microbuffer": "^1.0.0" - } - }, - "ttf2woff": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ttf2woff/-/ttf2woff-2.0.2.tgz", - "integrity": "sha512-X68badwBjAy/+itU49scLjXUL094up+rHuYk+YAOTTBYSUMOmLZ7VyhZJuqQESj1gnyLAC2/5V8Euv+mExmyPA==", - "requires": { - "argparse": "^1.0.6", - "microbuffer": "^1.0.0", - "pako": "^1.0.0" - }, - "dependencies": { - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" - } - } - }, - "ttf2woff2": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ttf2woff2/-/ttf2woff2-3.0.0.tgz", - "integrity": "sha512-5/Web6B0lF/STNAQ0d5vAlRRquuWsNj8wOmKQ9ql9Bsgbx8MsLnNzaBG9vBcSE4s4Ry1QOr/MyUrDUIVgVPEfw==", - "requires": { - "bindings": "^1.3.0", - "bufferstreams": "^2.0.1", - "nan": "^2.10.0", - "node-gyp": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==" - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" - }, - "are-we-there-yet": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", - "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" - }, - "fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "requires": { - "minipass": "^2.6.0" - } - }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==", - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, - "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "requires": { - "minipass": "^2.9.0" - } - }, - "node-gyp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-4.0.0.tgz", - "integrity": "sha512-2XiryJ8sICNo6ej8d0idXDEMKfVfFK7kekGCtJAuelGsYHQxhj13KTf95swTCN2dZ/4lTfZ84Fu31jqJEEgjWA==", - "requires": { - "glob": "^7.0.3", - "graceful-fs": "^4.1.2", - "mkdirp": "^0.5.0", - "nopt": "2 || 3", - "npmlog": "0 || 1 || 2 || 3 || 4", - "osenv": "0", - "request": "^2.87.0", - "rimraf": "2", - "semver": "~5.3.0", - "tar": "^4.4.8", - "which": "1" - } - }, - "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", - "requires": { - "abbrev": "1" - } - }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "requires": { - "glob": "^7.1.3" - } - }, - "semver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha512-mfmm3/H9+67MCVix1h+IXTpDwL6710LyHuk7+cWC9T1mE0qz4iHhh6r4hU2wrIT9iTsAAC2XQRvfblL028cpLw==" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "tar": { - "version": "4.4.19", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", - "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", - "requires": { - "chownr": "^1.1.4", - "fs-minipass": "^1.2.7", - "minipass": "^2.9.0", - "minizlib": "^1.3.3", - "mkdirp": "^0.5.5", - "safe-buffer": "^5.2.1", - "yallist": "^3.1.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - } - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - } - } - }, "tuf-js": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-2.2.0.tgz", @@ -38513,19 +37934,6 @@ } } }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" - }, "type": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", @@ -38564,6 +37972,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, "requires": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -38574,6 +37983,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, "requires": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -38586,6 +37996,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, "requires": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", @@ -38599,6 +38010,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "dev": true, "requires": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -38674,6 +38086,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, "requires": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", @@ -38928,23 +38341,6 @@ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - }, - "dependencies": { - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" - } - } - }, "vite": { "version": "5.1.7", "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.7.tgz", @@ -39182,35 +38578,6 @@ "defaults": "^1.0.3" } }, - "webfonts-generator-casaper": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/webfonts-generator-casaper/-/webfonts-generator-casaper-0.5.2.tgz", - "integrity": "sha512-beM/bZ/N+ajdldAwrILYKWnHNgMje9MwetYM52lJ15CLOGliyt82m3g39y2cZoi/Ca+Wqs8NKMhMrNOYYgX6Qg==", - "requires": { - "handlebars": "^4.0.5", - "mkdirp": "^1.0.4", - "q": "^1.1.2", - "svg2ttf": "^5.0.0", - "svgicons2svgfont": "^9.1.1", - "ttf2eot": "^2.0.0", - "ttf2woff": "^2.0.1", - "ttf2woff2": "^3.0.0", - "underscore": "^1.7.0", - "url-join": "^4.0.1" - }, - "dependencies": { - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" - }, - "url-join": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", - "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" - } - } - }, "webpack": { "version": "5.90.3", "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.3.tgz", @@ -39495,6 +38862,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, "requires": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", @@ -39539,6 +38907,7 @@ "version": "1.1.15", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dev": true, "requires": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", @@ -39637,11 +39006,6 @@ "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==", "dev": true }, - "xmldom": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.5.0.tgz", - "integrity": "sha512-Foaj5FXVzgn7xFzsKeNIde9g6aFBxTPi37iwsno8QvApmtg7KYrr+OPyRHcJF7dud2a5nGRBXK3n0dL62Gf7PA==" - }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", From bb8634bac90b0f31077abeb9ca855110340910be Mon Sep 17 00:00:00 2001 From: as-op Date: Wed, 5 Jun 2024 15:24:32 +0200 Subject: [PATCH 162/176] use ProjectCustomField.find_by https://github.com/opf/openproject/pull/15702#discussion_r1627286353 --- app/models/work_package/exports/macros/attributes.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/work_package/exports/macros/attributes.rb b/app/models/work_package/exports/macros/attributes.rb index eb48c6be8632..a2867942c59c 100644 --- a/app/models/work_package/exports/macros/attributes.rb +++ b/app/models/work_package/exports/macros/attributes.rb @@ -129,7 +129,7 @@ def self.escape_tags(value) end def self.resolve_value_project(project, attribute) - cf = CustomField.find_by(name: attribute, type: "ProjectCustomField") + cf = ProjectCustomField.find_by(name: attribute) if cf.nil? ar_name = ::API::Utilities::PropertyNameConverter.to_ar_name(attribute.to_sym, context: project) else From 3664727f15ede418e2ac9d0206037e71d356a8b8 Mon Sep 17 00:00:00 2001 From: as-op Date: Wed, 5 Jun 2024 15:25:38 +0200 Subject: [PATCH 163/176] add markly comment https://github.com/opf/openproject/pull/15702#discussion_r1627296963 --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 9882d01a33d2..d6bac00979bb 100644 --- a/Gemfile +++ b/Gemfile @@ -157,7 +157,7 @@ gem "structured_warnings", "~> 0.4.0" # don't require by default, instead load on-demand when actually configured gem "airbrake", "~> 13.0.0", require: false -gem "markly", "~> 0.10" +gem "markly", "~> 0.10" # another markdown parser like commonmarker, but with AST support used in PDF export gem "md_to_pdf", git: "https://github.com/opf/md-to-pdf", ref: "8f14736a88ad0064d2a97be108fe7061ffbcee91" gem "prawn", "~> 2.4" gem "ttfunk", "~> 1.7.0" # remove after https://github.com/prawnpdf/prawn/issues/1346 resolved. From 558b80cba09a3e2374090b3747a831794b2bb561 Mon Sep 17 00:00:00 2001 From: as-op Date: Wed, 5 Jun 2024 15:25:53 +0200 Subject: [PATCH 164/176] fix typo --- app/models/work_package/pdf_export/work_package_list_to_pdf.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/work_package/pdf_export/work_package_list_to_pdf.rb b/app/models/work_package/pdf_export/work_package_list_to_pdf.rb index 7de6d091f45a..f933b5f6ee7d 100644 --- a/app/models/work_package/pdf_export/work_package_list_to_pdf.rb +++ b/app/models/work_package/pdf_export/work_package_list_to_pdf.rb @@ -73,7 +73,7 @@ def export! rescue Prawn::Errors::CannotFit error(I18n.t(:error_pdf_export_too_many_columns)) rescue StandardError => e - Rails.logger.error { "Failed to generated PDF export: #{e}." } + Rails.logger.error { "Failed to generate PDF export: #{e}." } error(I18n.t(:error_pdf_failed_to_export, error: e.message[0..300])) end From 0f1e67be14fa3cfe6e257d20d1e37798b403a3e0 Mon Sep 17 00:00:00 2001 From: as-op Date: Wed, 5 Jun 2024 15:36:34 +0200 Subject: [PATCH 165/176] fix bug and comment in attribute formatter project.public --- app/models/projects/exports/formatters/public.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/projects/exports/formatters/public.rb b/app/models/projects/exports/formatters/public.rb index 40a6e85d1f0f..deb4deb03011 100644 --- a/app/models/projects/exports/formatters/public.rb +++ b/app/models/projects/exports/formatters/public.rb @@ -33,9 +33,9 @@ def self.apply?(attribute, export_format) end ## - # Takes a project and returns the localized status code + # Takes a project and returns yes/no depending on the public attribute def format(project, **) - project.active ? I18n.t(:general_text_Yes) : I18n.t(:general_text_No) + project.public? ? I18n.t(:general_text_Yes) : I18n.t(:general_text_No) end end end From 08602866f2a55917312978d194ee06049dcd5f6c Mon Sep 17 00:00:00 2001 From: as-op Date: Wed, 5 Jun 2024 15:36:45 +0200 Subject: [PATCH 166/176] fix comment in attribute formatter project.active --- app/models/projects/exports/formatters/active.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/projects/exports/formatters/active.rb b/app/models/projects/exports/formatters/active.rb index 81980c07a751..93a78add3542 100644 --- a/app/models/projects/exports/formatters/active.rb +++ b/app/models/projects/exports/formatters/active.rb @@ -33,9 +33,9 @@ def self.apply?(attribute, export_format) end ## - # Takes a project and returns the localized status code + # Takes a project and returns yes/no depending on the active attribute def format(project, **) - project.active ? I18n.t(:general_text_Yes) : I18n.t(:general_text_No) + project.active? ? I18n.t(:general_text_Yes) : I18n.t(:general_text_No) end end end From 076b56073bcf06f99139e20870b54b0fa9aafdc8 Mon Sep 17 00:00:00 2001 From: as-op Date: Wed, 5 Jun 2024 15:45:08 +0200 Subject: [PATCH 167/176] simplify wp access check & find https://github.com/opf/openproject/pull/15702#discussion_r1627409100 --- app/models/work_package/exports/macros/attributes.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/models/work_package/exports/macros/attributes.rb b/app/models/work_package/exports/macros/attributes.rb index a2867942c59c..99e8631ef425 100644 --- a/app/models/work_package/exports/macros/attributes.rb +++ b/app/models/work_package/exports/macros/attributes.rb @@ -101,9 +101,8 @@ def self.resolve_work_package_match(id, type, attribute, user) return resolve_label_work_package(attribute) if type == "label" return msg_macro_error(I18n.t('export.macro.model_not_found', model: type)) unless type == "value" - work_package = WorkPackage.find_by(id:) - if work_package.nil? || - !user.allowed_in_work_package?(:view_work_packages, work_package) + work_package = WorkPackage.visible(user).find_by(id:) + if work_package.nil? return msg_macro_error(I18n.t('export.macro.resource_not_found', resource: "#{WorkPackage.name} #{id}")) end From f578226fba26a3ec70d1c6cb8a8377454da81cfc Mon Sep 17 00:00:00 2001 From: as-op Date: Wed, 5 Jun 2024 15:46:05 +0200 Subject: [PATCH 168/176] simplify project access check & find https://github.com/opf/openproject/pull/15702#discussion_r1627409660 --- app/models/work_package/exports/macros/attributes.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/models/work_package/exports/macros/attributes.rb b/app/models/work_package/exports/macros/attributes.rb index 99e8631ef425..90a8e9f892ab 100644 --- a/app/models/work_package/exports/macros/attributes.rb +++ b/app/models/work_package/exports/macros/attributes.rb @@ -113,9 +113,8 @@ def self.resolve_project_match(id, type, attribute, user) return resolve_label_project(attribute) if type == "label" return msg_macro_error(I18n.t("export.macro.model_not_found", model: type)) unless type == "value" - project = Project.find_by(id:) - if project.nil? || - !user.allowed_in_project?(:view_project, project) + project = Project.visible(user).find_by(id:) + if project.nil? return msg_macro_error(I18n.t("export.macro.resource_not_found", resource: "#{Project.name} #{id}")) end From 6ab7b50e97c33b171dcf20209a633fb393f4daff Mon Sep 17 00:00:00 2001 From: as-op Date: Wed, 5 Jun 2024 16:43:30 +0200 Subject: [PATCH 169/176] simplify & unify attribute value resolving https://github.com/opf/openproject/pull/15702#discussion_r1627436214 https://github.com/opf/openproject/pull/15702#discussion_r1627444854 --- .../work_package/exports/macros/attributes.rb | 48 +++++-------------- .../pdf_export/work_package_to_pdf_spec.rb | 11 +++-- 2 files changed, 19 insertions(+), 40 deletions(-) diff --git a/app/models/work_package/exports/macros/attributes.rb b/app/models/work_package/exports/macros/attributes.rb index 90a8e9f892ab..fa979b5e4d51 100644 --- a/app/models/work_package/exports/macros/attributes.rb +++ b/app/models/work_package/exports/macros/attributes.rb @@ -127,48 +127,26 @@ def self.escape_tags(value) end def self.resolve_value_project(project, attribute) - cf = ProjectCustomField.find_by(name: attribute) - if cf.nil? - ar_name = ::API::Utilities::PropertyNameConverter.to_ar_name(attribute.to_sym, context: project) - else - ar_name = "cf_#{cf.id}" - # currently we do not support embedding rich text fields: long text custom fields - return msg_macro_error_rich_text if cf.formattable? - - # Is the user allowed to see this custom field/"project attribute"? - if project.available_custom_fields.find { |pcf| pcf.id == cf.id }.nil? - return msg_macro_error(I18n.t("export.macro.resource_not_found", resource: attribute)) - end - end - - # currently we do not support embedding rich text field: e.g. projectValue:1234:description - if DISABLED_PROJECT_RICH_TEXT_FIELDS.include?(ar_name.to_sym) - return msg_macro_error_rich_text - - end - - format_attribute_value(ar_name, Project, project) + resolve_value(project, attribute, DISABLED_PROJECT_RICH_TEXT_FIELDS) end def self.resolve_value_work_package(work_package, attribute) - cf = CustomField.find_by(name: attribute, type: "WorkPackageCustomField") - if cf.nil? - ar_name = ::API::Utilities::PropertyNameConverter.to_ar_name(attribute.to_sym, context: work_package) - else - ar_name = "cf_#{cf.id}" - # currently we do not support embedding rich text fields: long text custom fields - return msg_macro_error_rich_text if cf.formattable? + resolve_value(work_package, attribute, DISABLED_WORK_PACKAGE_RICH_TEXT_FIELDS) + end - # TODO: Are there access restrictions on work_package custom fields? - end + def self.resolve_value(obj, attribute, disabled_rich_text_fields) + cf = obj.available_custom_fields.find { |pcf| pcf.name == attribute } - # currently we do not support embedding rich text field: workPackageValue:1234:description - if DISABLED_WORK_PACKAGE_RICH_TEXT_FIELDS.include?(ar_name.to_sym) - return msg_macro_error_rich_text + return msg_macro_error_rich_text if cf&.formattable? - end + ar_name = if cf.nil? + ::API::Utilities::PropertyNameConverter.to_ar_name(attribute.to_sym, context: obj) + else + "cf_#{cf.id}" + end + return msg_macro_error_rich_text if disabled_rich_text_fields.include?(ar_name.to_sym) - format_attribute_value(ar_name, WorkPackage, work_package) + format_attribute_value(ar_name, obj.class, obj) end def self.format_attribute_value(ar_name, model, obj) diff --git a/spec/models/work_packages/pdf_export/work_package_to_pdf_spec.rb b/spec/models/work_packages/pdf_export/work_package_to_pdf_spec.rb index 814f76bc9a18..9a703b1fb544 100644 --- a/spec/models/work_packages/pdf_export/work_package_to_pdf_spec.rb +++ b/spec/models/work_packages/pdf_export/work_package_to_pdf_spec.rb @@ -61,7 +61,8 @@ active: true, parent: parent_project, custom_field_values: { - project_custom_field_bool.id => true + project_custom_field_bool.id => true, + project_custom_field_long_text.id => "foo", }, work_package_custom_fields: [cf_long_text, cf_disabled_in_project, cf_global_bool], work_package_custom_field_ids: [cf_long_text.id, cf_global_bool.id]) # cf_disabled_in_project.id is disabled @@ -389,13 +390,13 @@ def get_column_value(column_name) "Custom field boolean", I18n.t(:general_text_Yes), "Custom field rich text", "[#{I18n.t('export.macro.rich_text_unsupported')}]", "Custom field hidden", - "[#{I18n.t('export.macro.error', message: - I18n.t('export.macro.resource_not_found', resource: "Secret string"))}]", - "No replacement of:", "projectValue:1:status", " ", "projectLabel:status", + "No replacement of:", "projectValue:1:status", "projectLabel:status", "projectValue:2:status projectLabel:status", "projectValue:3:status", "projectLabel:status", + "1", export_time_formatted, project.name, + "Project not found: ", "[#{I18n.t('export.macro.error', message: I18n.t('export.macro.resource_not_found', resource: "Project 1234567890"))}] ", @@ -403,7 +404,7 @@ def get_column_value(column_name) "[#{I18n.t('export.macro.error', message: I18n.t('export.macro.resource_not_found', resource: "Project #{forbidden_project.id}"))}]", - "1", export_time_formatted, project.name + "2", export_time_formatted, project.name, ].flatten expect(result.join(" ")).to eq(expected_result.join(" ")) end From 73aad7c16546d8e51049f63fdfc1efbb61af8917 Mon Sep 17 00:00:00 2001 From: as-op Date: Wed, 5 Jun 2024 16:48:49 +0200 Subject: [PATCH 170/176] remove already checked formatter.applicable? https://github.com/opf/openproject/pull/15702#discussion_r1627479843 --- app/models/work_package/pdf_export/markdown_field.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/models/work_package/pdf_export/markdown_field.rb b/app/models/work_package/pdf_export/markdown_field.rb index ddb7648c8b0f..b478d14278ab 100644 --- a/app/models/work_package/pdf_export/markdown_field.rb +++ b/app/models/work_package/pdf_export/markdown_field.rb @@ -72,8 +72,6 @@ def apply_macro_text(text, work_package, formatter) end def apply_macro_html(html, work_package, formatter) - return html unless formatter.applicable?(html) - doc = Nokogiri::HTML.fragment(html) apply_macro_html_node(doc, work_package, formatter) doc.to_html From 7356ddfcf380a865c7a192334e5512e9610f502a Mon Sep 17 00:00:00 2001 From: Christophe Bliard Date: Wed, 5 Jun 2024 16:55:02 +0200 Subject: [PATCH 171/176] [55467] Warn about potential data loss when changing progress modes https://community.openproject.org/wp/55467 --- .../work_packages_settings/show.html.erb | 17 ++++- .../show.html.erb | 3 +- config/locales/js-en.yml | 13 ++++ .../work-packages-settings.controller.ts | 69 +++++++++++++++++++ .../controllers/op-application.controller.ts | 2 +- 5 files changed, 99 insertions(+), 5 deletions(-) create mode 100644 frontend/src/stimulus/controllers/dynamic/admin/work-packages-settings.controller.ts diff --git a/app/views/admin/settings/work_packages_settings/show.html.erb b/app/views/admin/settings/work_packages_settings/show.html.erb index 0151e41e51fa..dd76fbf955a4 100644 --- a/app/views/admin/settings/work_packages_settings/show.html.erb +++ b/app/views/admin/settings/work_packages_settings/show.html.erb @@ -32,16 +32,29 @@ See COPYRIGHT and LICENSE files for more details. <%= toolbar title: t(:label_work_package_tracking) %> <%= styled_form_tag({ action: :update }, method: :patch) do %> -

    +
    <%= setting_check_box :cross_project_work_package_relations %>
    <%= setting_check_box :display_subprojects_work_packages %>
    <%= setting_check_box :work_package_startdate_is_adddate %>
    <%= setting_select :work_package_done_ratio, WorkPackage::DONE_RATIO_OPTIONS.collect { |i| [t("setting_work_package_done_ratio_#{i}"), i] }, - container_class: "-middle" %> + container_class: "-middle", + data: { admin__work_packages_settings_target: "progressCalculationModeSelect", + action: "change->admin--work-packages-settings#displayWarning" } %>
    <%= t("setting_work_package_done_ratio_explanation_html") %>
    +
    <%= setting_select(:work_package_list_default_highlighting_mode, Query::Highlighting::QUERY_HIGHLIGHTING_MODES.map do |mode| diff --git a/app/views/admin/settings/working_days_and_hours_settings/show.html.erb b/app/views/admin/settings/working_days_and_hours_settings/show.html.erb index 29bf4690feb8..26e2c8552c95 100644 --- a/app/views/admin/settings/working_days_and_hours_settings/show.html.erb +++ b/app/views/admin/settings/working_days_and_hours_settings/show.html.erb @@ -70,14 +70,13 @@ See COPYRIGHT and LICENSE files for more details.
    <%= t('settings.working_days.section_work_week') %> -
    +

    <%= t("working_days.warning") %>

    -

    <%= t("working_days.info") %>

    diff --git a/config/locales/js-en.yml b/config/locales/js-en.yml index a5cd566e1bd7..bc65a24cc3ac 100644 --- a/config/locales/js-en.yml +++ b/config/locales/js-en.yml @@ -303,6 +303,19 @@ en: Are you sure you want to continue? + + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make + % Complete a non-editable field whose value is derived from Work + and Remaining work. Existing values for % Complete are preserved. + If values for Work and Remaining work were not present, they + will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result + in all existing % Complete values to be lost and replaced with values + associated with each status. Existing values for Remaining work may + also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "on" diff --git a/frontend/src/stimulus/controllers/dynamic/admin/work-packages-settings.controller.ts b/frontend/src/stimulus/controllers/dynamic/admin/work-packages-settings.controller.ts new file mode 100644 index 000000000000..f805ff85473a --- /dev/null +++ b/frontend/src/stimulus/controllers/dynamic/admin/work-packages-settings.controller.ts @@ -0,0 +1,69 @@ +/* + * -- copyright + * OpenProject is an open source project management software. + * Copyright (C) 2023 the OpenProject GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 3. + * + * OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: + * Copyright (C) 2006-2013 Jean-Philippe Lang + * Copyright (C) 2010-2013 the ChiliProject Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * See COPYRIGHT and LICENSE files for more details. + * ++ + */ + +import { Controller } from '@hotwired/stimulus'; + +/* + * Helps keep daysPerWeek and daysPerMonth in-line with each other + */ +export default class WorkPackagesSettingsController extends Controller { + static targets = [ + 'progressCalculationModeSelect', + 'warningText', + 'warningToast', + ]; + + declare readonly progressCalculationModeSelectTarget:HTMLSelectElement; + declare readonly warningTextTarget:HTMLElement; + declare readonly warningToastTarget:HTMLElement; + private initialMode:string; + + connect() { + this.initialMode = this.progressCalculationModeSelectTarget.value; + } + + displayWarning() { + const warningMessageHtml = this.getWarningMessageHtml(); + if (warningMessageHtml) { + this.warningTextTarget.innerHTML = warningMessageHtml; + this.warningToastTarget.hidden = false; + } else { + this.warningToastTarget.hidden = true; + } + } + + getWarningMessageHtml():string { + const newMode = this.progressCalculationModeSelectTarget.value; + return I18n.t( + `js.admin.work_packages_settings.warning_progress_calculation_mode_change_from_${this.initialMode}_to_${newMode}_html`, + { defaultValue: '' }, + ); + } +} diff --git a/frontend/src/stimulus/controllers/op-application.controller.ts b/frontend/src/stimulus/controllers/op-application.controller.ts index 375065e3e901..e1234cc820e9 100644 --- a/frontend/src/stimulus/controllers/op-application.controller.ts +++ b/frontend/src/stimulus/controllers/op-application.controller.ts @@ -26,7 +26,7 @@ export class OpApplicationController extends ApplicationController { /** * Derive dynamic path from controller name. * - * Stimlus conventions allow subdirectories to be used by double dashes. + * Stimulus conventions allow subdirectories to be used by double dashes. * We convert these to slashes for the dynamic import. * * https://stimulus.hotwired.dev/handbook/installing#controller-filenames-map-to-identifiers From 53337f54c7857e7f1c222978925ead5188dc9c68 Mon Sep 17 00:00:00 2001 From: as-op Date: Wed, 5 Jun 2024 17:38:06 +0200 Subject: [PATCH 172/176] support referencing project by identifier https://github.com/opf/openproject/pull/15702#discussion_r1627668679 --- app/models/work_package/exports/macros/attributes.rb | 1 + app/models/work_package/pdf_export/markdown_field.rb | 6 ++++-- .../pdf_export/work_package_to_pdf_spec.rb | 12 ++++++++++-- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/app/models/work_package/exports/macros/attributes.rb b/app/models/work_package/exports/macros/attributes.rb index fa979b5e4d51..4885c9ad355d 100644 --- a/app/models/work_package/exports/macros/attributes.rb +++ b/app/models/work_package/exports/macros/attributes.rb @@ -114,6 +114,7 @@ def self.resolve_project_match(id, type, attribute, user) return msg_macro_error(I18n.t("export.macro.model_not_found", model: type)) unless type == "value" project = Project.visible(user).find_by(id:) + project = Project.visible(user).find_by(identifier: id) if project.nil? if project.nil? return msg_macro_error(I18n.t("export.macro.resource_not_found", resource: "#{Project.name} #{id}")) end diff --git a/app/models/work_package/pdf_export/markdown_field.rb b/app/models/work_package/pdf_export/markdown_field.rb index b478d14278ab..f5d45baa1dd5 100644 --- a/app/models/work_package/pdf_export/markdown_field.rb +++ b/app/models/work_package/pdf_export/markdown_field.rb @@ -54,9 +54,9 @@ def apply_macros(markdown, work_package, formatter) document = Markly.parse(markdown) document.walk do |node| if node.type == :html - node.string_content = apply_macro_html(node.string_content, work_package, formatter) + node.string_content = apply_macro_html(node.string_content, work_package, formatter) || node.string_content elsif node.type == :text - node.string_content = apply_macro_text(node.string_content, work_package, formatter) + node.string_content = apply_macro_text(node.string_content, work_package, formatter) || node.string_content end end document.to_markdown @@ -72,6 +72,8 @@ def apply_macro_text(text, work_package, formatter) end def apply_macro_html(html, work_package, formatter) + return html unless formatter.applicable?(html) + doc = Nokogiri::HTML.fragment(html) apply_macro_html_node(doc, work_package, formatter) doc.to_html diff --git a/spec/models/work_packages/pdf_export/work_package_to_pdf_spec.rb b/spec/models/work_packages/pdf_export/work_package_to_pdf_spec.rb index 9a703b1fb544..6078c2c63782 100644 --- a/spec/models/work_packages/pdf_export/work_package_to_pdf_spec.rb +++ b/spec/models/work_packages/pdf_export/work_package_to_pdf_spec.rb @@ -72,6 +72,7 @@ name: "Forbidden project", types: [type], id: 666, + identifier: "forbidden-project", public: false, status_code: "on_track", active: true, @@ -370,10 +371,15 @@ def get_column_value(column_name) projectLabel:status ``` + Project by identifier: + projectValue:"#{project.identifier}":active + Project not found: projectValue:1234567890:active Access denied: projectValue:#{forbidden_project.id}:active + Access denied by identifier: + projectValue:"#{forbidden_project.identifier}":active DESCRIPTION end it "contains resolved attributes and labels" do @@ -397,14 +403,16 @@ def get_column_value(column_name) "1", export_time_formatted, project.name, + "Project by identifier:", " ", I18n.t(:general_text_Yes), "Project not found: ", "[#{I18n.t('export.macro.error', message: I18n.t('export.macro.resource_not_found', resource: "Project 1234567890"))}] ", "Access denied: ", "[#{I18n.t('export.macro.error', message: - I18n.t('export.macro.resource_not_found', resource: "Project #{forbidden_project.id}"))}]", + I18n.t('export.macro.resource_not_found', resource: "Project #{forbidden_project.id}"))}] ", + "Access denied by identifier:", " ", "[Macro error, resource not found: Project", "forbidden-project]", - "2", export_time_formatted, project.name, + "2", export_time_formatted, project.name, ].flatten expect(result.join(" ")).to eq(expected_result.join(" ")) end From 33afc826224f336b3fe4a97f462e410957397b21 Mon Sep 17 00:00:00 2001 From: as-op Date: Wed, 5 Jun 2024 17:51:35 +0200 Subject: [PATCH 173/176] list more examples in comment --- .../work_package/exports/macros/attributes.rb | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/app/models/work_package/exports/macros/attributes.rb b/app/models/work_package/exports/macros/attributes.rb index 4885c9ad355d..8b50adfa503e 100644 --- a/app/models/work_package/exports/macros/attributes.rb +++ b/app/models/work_package/exports/macros/attributes.rb @@ -29,11 +29,21 @@ module WorkPackage::Exports module Macros # OpenProject attribute macros syntax # Examples: - # workPackageLabel:1234:subject # Outputs work package label attribute "Subject" + help text - # workPackageValue:1234:subject # Outputs the actual subject of #1234 + # workPackageLabel:subject # Outputs work package label attribute "Subject" + # workPackageLabel:1234:subject # Outputs work package label attribute "Subject" + + # workPackageValue:subject # Outputs the subject of the current work package + # workPackageValue:1234:subject # Outputs the subject of #1234 + # workPackageValue:"custom field name" # Outputs the custom field value of the current work package + # workPackageValue:1234:"custom field name" # Outputs the custom field value of #1234 # - # projectLabel:statusExplanation # Outputs current project label attribute "Status description" + help text - # projectValue:statusExplanation # Outputs current project value for "Status description" + # projectLabel:active # Outputs current project label attribute "active" + # projectLabel:1234:active # Outputs project label attribute "active" + # projectLabel:my-project-identifier:active # Outputs project label attribute "active" + + # projectValue:active # Outputs current project value for "active" + # projectValue:1234:active # Outputs project with id 1234 value for "active" + # projectValue:my-project-identifier:active # Outputs project with identifier my-project-identifier value for "active" class Attributes < OpenProject::TextFormatting::Matchers::RegexMatcher DISABLED_PROJECT_RICH_TEXT_FIELDS = %i[description status_explanation status_description].freeze DISABLED_WORK_PACKAGE_RICH_TEXT_FIELDS = %i[description].freeze From 55321b0c681d9f0c3957db3607f53210f3e4d9de Mon Sep 17 00:00:00 2001 From: Christophe Bliard Date: Wed, 5 Jun 2024 18:12:50 +0200 Subject: [PATCH 174/176] Remove test text --- app/views/admin/settings/work_packages_settings/show.html.erb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/views/admin/settings/work_packages_settings/show.html.erb b/app/views/admin/settings/work_packages_settings/show.html.erb index dd76fbf955a4..9c8031bba8e6 100644 --- a/app/views/admin/settings/work_packages_settings/show.html.erb +++ b/app/views/admin/settings/work_packages_settings/show.html.erb @@ -50,9 +50,7 @@ See COPYRIGHT and LICENSE files for more details. hidden data-admin--work-packages-settings-target="warningToast">
    -

    - Changing progress calculation mode from work-based is dangerous! Take this! -

    +

    From b773a3a168eb9805195474d2481850a8d43caf6d Mon Sep 17 00:00:00 2001 From: OpenProject Actions CI Date: Thu, 6 Jun 2024 03:08:54 +0000 Subject: [PATCH 175/176] update locales from crowdin [ci skip] --- config/locales/crowdin/af.yml | 12 ++++++ config/locales/crowdin/ar.yml | 12 ++++++ config/locales/crowdin/az.yml | 12 ++++++ config/locales/crowdin/be.yml | 12 ++++++ config/locales/crowdin/bg.yml | 12 ++++++ config/locales/crowdin/ca.yml | 12 ++++++ config/locales/crowdin/ckb-IR.yml | 12 ++++++ config/locales/crowdin/cs.yml | 12 ++++++ config/locales/crowdin/da.yml | 12 ++++++ config/locales/crowdin/de.yml | 12 ++++++ config/locales/crowdin/el.yml | 12 ++++++ config/locales/crowdin/eo.yml | 12 ++++++ config/locales/crowdin/es.yml | 12 ++++++ config/locales/crowdin/et.yml | 12 ++++++ config/locales/crowdin/eu.yml | 12 ++++++ config/locales/crowdin/fa.yml | 12 ++++++ config/locales/crowdin/fi.yml | 12 ++++++ config/locales/crowdin/fil.yml | 12 ++++++ config/locales/crowdin/fr.yml | 12 ++++++ config/locales/crowdin/he.yml | 12 ++++++ config/locales/crowdin/hi.yml | 12 ++++++ config/locales/crowdin/hr.yml | 12 ++++++ config/locales/crowdin/hu.yml | 12 ++++++ config/locales/crowdin/id.yml | 12 ++++++ config/locales/crowdin/it.yml | 12 ++++++ config/locales/crowdin/ja.yml | 12 ++++++ config/locales/crowdin/js-af.yml | 5 +++ config/locales/crowdin/js-ar.yml | 5 +++ config/locales/crowdin/js-az.yml | 5 +++ config/locales/crowdin/js-be.yml | 5 +++ config/locales/crowdin/js-bg.yml | 5 +++ config/locales/crowdin/js-ca.yml | 5 +++ config/locales/crowdin/js-ckb-IR.yml | 5 +++ config/locales/crowdin/js-cs.yml | 5 +++ config/locales/crowdin/js-da.yml | 5 +++ config/locales/crowdin/js-de.yml | 5 +++ config/locales/crowdin/js-el.yml | 5 +++ config/locales/crowdin/js-eo.yml | 5 +++ config/locales/crowdin/js-es.yml | 5 +++ config/locales/crowdin/js-et.yml | 5 +++ config/locales/crowdin/js-eu.yml | 5 +++ config/locales/crowdin/js-fa.yml | 5 +++ config/locales/crowdin/js-fi.yml | 5 +++ config/locales/crowdin/js-fil.yml | 5 +++ config/locales/crowdin/js-fr.yml | 5 +++ config/locales/crowdin/js-he.yml | 5 +++ config/locales/crowdin/js-hi.yml | 5 +++ config/locales/crowdin/js-hr.yml | 5 +++ config/locales/crowdin/js-hu.yml | 5 +++ config/locales/crowdin/js-id.yml | 5 +++ config/locales/crowdin/js-it.yml | 5 +++ config/locales/crowdin/js-ja.yml | 5 +++ config/locales/crowdin/js-ka.yml | 5 +++ config/locales/crowdin/js-kk.yml | 5 +++ config/locales/crowdin/js-ko.yml | 5 +++ config/locales/crowdin/js-lt.yml | 5 +++ config/locales/crowdin/js-lv.yml | 5 +++ config/locales/crowdin/js-mn.yml | 5 +++ config/locales/crowdin/js-ms.yml | 35 +++++++++------- config/locales/crowdin/js-ne.yml | 5 +++ config/locales/crowdin/js-nl.yml | 5 +++ config/locales/crowdin/js-no.yml | 5 +++ config/locales/crowdin/js-pl.yml | 5 +++ config/locales/crowdin/js-pt-BR.yml | 5 +++ config/locales/crowdin/js-pt-PT.yml | 5 +++ config/locales/crowdin/js-ro.yml | 5 +++ config/locales/crowdin/js-ru.yml | 5 +++ config/locales/crowdin/js-rw.yml | 5 +++ config/locales/crowdin/js-si.yml | 5 +++ config/locales/crowdin/js-sk.yml | 5 +++ config/locales/crowdin/js-sl.yml | 5 +++ config/locales/crowdin/js-sr.yml | 5 +++ config/locales/crowdin/js-sv.yml | 5 +++ config/locales/crowdin/js-th.yml | 5 +++ config/locales/crowdin/js-tr.yml | 5 +++ config/locales/crowdin/js-uk.yml | 5 +++ config/locales/crowdin/js-uz.yml | 5 +++ config/locales/crowdin/js-vi.yml | 5 +++ config/locales/crowdin/js-zh-CN.yml | 5 +++ config/locales/crowdin/js-zh-TW.yml | 5 +++ config/locales/crowdin/ka.yml | 12 ++++++ config/locales/crowdin/kk.yml | 12 ++++++ config/locales/crowdin/ko.yml | 12 ++++++ config/locales/crowdin/lt.yml | 12 ++++++ config/locales/crowdin/lv.yml | 12 ++++++ config/locales/crowdin/mn.yml | 12 ++++++ config/locales/crowdin/ms.yml | 42 ++++++++++++------- config/locales/crowdin/ne.yml | 12 ++++++ config/locales/crowdin/nl.yml | 12 ++++++ config/locales/crowdin/no.yml | 12 ++++++ config/locales/crowdin/pl.yml | 12 ++++++ config/locales/crowdin/pt-BR.yml | 12 ++++++ config/locales/crowdin/pt-PT.yml | 12 ++++++ config/locales/crowdin/ro.yml | 12 ++++++ config/locales/crowdin/ru.yml | 16 ++++++- config/locales/crowdin/rw.yml | 12 ++++++ config/locales/crowdin/si.yml | 12 ++++++ config/locales/crowdin/sk.yml | 12 ++++++ config/locales/crowdin/sl.yml | 12 ++++++ config/locales/crowdin/sr.yml | 12 ++++++ config/locales/crowdin/sv.yml | 12 ++++++ config/locales/crowdin/th.yml | 12 ++++++ config/locales/crowdin/tr.yml | 12 ++++++ config/locales/crowdin/uk.yml | 12 ++++++ config/locales/crowdin/uz.yml | 12 ++++++ config/locales/crowdin/vi.yml | 12 ++++++ config/locales/crowdin/zh-CN.yml | 19 +++++++-- config/locales/crowdin/zh-TW.yml | 12 ++++++ .../bim/config/locales/crowdin/id.seeders.yml | 8 ++-- modules/bim/config/locales/crowdin/id.yml | 32 +++++++------- .../config/locales/crowdin/af.yml | 12 ++++++ .../config/locales/crowdin/ar.yml | 12 ++++++ .../config/locales/crowdin/az.yml | 12 ++++++ .../config/locales/crowdin/be.yml | 12 ++++++ .../config/locales/crowdin/bg.yml | 12 ++++++ .../config/locales/crowdin/ca.yml | 12 ++++++ .../config/locales/crowdin/ckb-IR.yml | 12 ++++++ .../config/locales/crowdin/cs.yml | 12 ++++++ .../config/locales/crowdin/da.yml | 12 ++++++ .../config/locales/crowdin/de.yml | 12 ++++++ .../config/locales/crowdin/el.yml | 12 ++++++ .../config/locales/crowdin/eo.yml | 12 ++++++ .../config/locales/crowdin/es.yml | 12 ++++++ .../config/locales/crowdin/et.yml | 12 ++++++ .../config/locales/crowdin/eu.yml | 12 ++++++ .../config/locales/crowdin/fa.yml | 12 ++++++ .../config/locales/crowdin/fi.yml | 12 ++++++ .../config/locales/crowdin/fil.yml | 12 ++++++ .../config/locales/crowdin/fr.yml | 12 ++++++ .../config/locales/crowdin/he.yml | 12 ++++++ .../config/locales/crowdin/hi.yml | 12 ++++++ .../config/locales/crowdin/hr.yml | 12 ++++++ .../config/locales/crowdin/hu.yml | 12 ++++++ .../config/locales/crowdin/id.yml | 12 ++++++ .../config/locales/crowdin/it.yml | 12 ++++++ .../config/locales/crowdin/ja.yml | 12 ++++++ .../config/locales/crowdin/ka.yml | 12 ++++++ .../config/locales/crowdin/kk.yml | 12 ++++++ .../config/locales/crowdin/ko.yml | 12 ++++++ .../config/locales/crowdin/lt.yml | 12 ++++++ .../config/locales/crowdin/lv.yml | 12 ++++++ .../config/locales/crowdin/mn.yml | 12 ++++++ .../config/locales/crowdin/ms.yml | 12 ++++++ .../config/locales/crowdin/ne.yml | 12 ++++++ .../config/locales/crowdin/nl.yml | 12 ++++++ .../config/locales/crowdin/no.yml | 12 ++++++ .../config/locales/crowdin/pl.yml | 12 ++++++ .../config/locales/crowdin/pt-BR.yml | 12 ++++++ .../config/locales/crowdin/pt-PT.yml | 12 ++++++ .../config/locales/crowdin/ro.yml | 12 ++++++ .../config/locales/crowdin/ru.yml | 12 ++++++ .../config/locales/crowdin/rw.yml | 12 ++++++ .../config/locales/crowdin/si.yml | 12 ++++++ .../config/locales/crowdin/sk.yml | 12 ++++++ .../config/locales/crowdin/sl.yml | 12 ++++++ .../config/locales/crowdin/sr.yml | 12 ++++++ .../config/locales/crowdin/sv.yml | 12 ++++++ .../config/locales/crowdin/th.yml | 12 ++++++ .../config/locales/crowdin/tr.yml | 12 ++++++ .../config/locales/crowdin/uk.yml | 12 ++++++ .../config/locales/crowdin/uz.yml | 12 ++++++ .../config/locales/crowdin/vi.yml | 12 ++++++ .../config/locales/crowdin/zh-CN.yml | 12 ++++++ .../config/locales/crowdin/zh-TW.yml | 12 ++++++ .../grids/config/locales/crowdin/js-ru.yml | 6 +-- modules/meeting/config/locales/crowdin/ru.yml | 2 +- .../meeting/config/locales/crowdin/zh-CN.yml | 2 +- 167 files changed, 1627 insertions(+), 60 deletions(-) diff --git a/config/locales/crowdin/af.yml b/config/locales/crowdin/af.yml index 56c7e97d96c2..4430e652b1ed 100644 --- a/config/locales/crowdin/af.yml +++ b/config/locales/crowdin/af.yml @@ -300,6 +300,12 @@ af: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: There are currently no types available. form: @@ -1610,6 +1616,12 @@ af: pdf_gantt: "PDF Gantt" image: omitted: "Image not exported." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/ar.yml b/config/locales/crowdin/ar.yml index 6c6814a9096e..5364ffea99ef 100644 --- a/config/locales/crowdin/ar.yml +++ b/config/locales/crowdin/ar.yml @@ -300,6 +300,12 @@ ar: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: لا يوجد حالياً أي أنواع متاحة. form: @@ -1742,6 +1748,12 @@ ar: pdf_gantt: "PDF Gantt" image: omitted: "Image not exported." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/az.yml b/config/locales/crowdin/az.yml index 00ec786d618e..59a7c4513c26 100644 --- a/config/locales/crowdin/az.yml +++ b/config/locales/crowdin/az.yml @@ -300,6 +300,12 @@ az: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: There are currently no types available. form: @@ -1610,6 +1616,12 @@ az: pdf_gantt: "PDF Gantt" image: omitted: "Image not exported." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/be.yml b/config/locales/crowdin/be.yml index 834af1a43be8..3dd437f3e326 100644 --- a/config/locales/crowdin/be.yml +++ b/config/locales/crowdin/be.yml @@ -300,6 +300,12 @@ be: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: There are currently no types available. form: @@ -1676,6 +1682,12 @@ be: pdf_gantt: "PDF Gantt" image: omitted: "Image not exported." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/bg.yml b/config/locales/crowdin/bg.yml index 2ec28fa73139..2f34ed109ddc 100644 --- a/config/locales/crowdin/bg.yml +++ b/config/locales/crowdin/bg.yml @@ -300,6 +300,12 @@ bg: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: В момента има няма типове на разположение. form: @@ -1610,6 +1616,12 @@ bg: pdf_gantt: "PDF Gantt" image: omitted: "Image not exported." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/ca.yml b/config/locales/crowdin/ca.yml index 515a8392841a..c1f5e59cf3c3 100644 --- a/config/locales/crowdin/ca.yml +++ b/config/locales/crowdin/ca.yml @@ -297,6 +297,12 @@ ca: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: Actualment no hi ha cap classe disponible. form: @@ -1606,6 +1612,12 @@ ca: pdf_gantt: "PDF Gantt" image: omitted: "Imatge no exportada." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/ckb-IR.yml b/config/locales/crowdin/ckb-IR.yml index 9783c45b9de4..18fd56d616ba 100644 --- a/config/locales/crowdin/ckb-IR.yml +++ b/config/locales/crowdin/ckb-IR.yml @@ -300,6 +300,12 @@ ckb-IR: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: There are currently no types available. form: @@ -1610,6 +1616,12 @@ ckb-IR: pdf_gantt: "PDF Gantt" image: omitted: "Image not exported." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/cs.yml b/config/locales/crowdin/cs.yml index c51c8696874e..86bc449dc686 100644 --- a/config/locales/crowdin/cs.yml +++ b/config/locales/crowdin/cs.yml @@ -300,6 +300,12 @@ cs: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: V současné době nejsou k dispozici žádné typy. form: @@ -1676,6 +1682,12 @@ cs: pdf_gantt: "PDF Gantt" image: omitted: "Obrázek nebyl exportován." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/da.yml b/config/locales/crowdin/da.yml index 1591e225ad36..681cd6ef54bc 100644 --- a/config/locales/crowdin/da.yml +++ b/config/locales/crowdin/da.yml @@ -298,6 +298,12 @@ da: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: Der er i øjeblikket ingen tilgængelige typer. form: @@ -1608,6 +1614,12 @@ da: pdf_gantt: "PDF Gantt" image: omitted: "Image not exported." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/de.yml b/config/locales/crowdin/de.yml index 2262f5325dd3..414aa2761dac 100644 --- a/config/locales/crowdin/de.yml +++ b/config/locales/crowdin/de.yml @@ -297,6 +297,12 @@ de: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: Derzeit stehen keine Typen zur Verfügung. form: @@ -1605,6 +1611,12 @@ de: pdf_gantt: "PDF Gantt" image: omitted: "Bild nicht exportiert." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/el.yml b/config/locales/crowdin/el.yml index f110cb99d005..6044e7949c54 100644 --- a/config/locales/crowdin/el.yml +++ b/config/locales/crowdin/el.yml @@ -296,6 +296,12 @@ el: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: Προς το παρόν δεν υπάρχουν διαθέσιμοι τύποι. form: @@ -1606,6 +1612,12 @@ el: pdf_gantt: "PDF Gantt" image: omitted: "Η εικόνα δεν εξήχθη." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/eo.yml b/config/locales/crowdin/eo.yml index 8cacb55ff887..a889bf65cac6 100644 --- a/config/locales/crowdin/eo.yml +++ b/config/locales/crowdin/eo.yml @@ -300,6 +300,12 @@ eo: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: There are currently no types available. form: @@ -1610,6 +1616,12 @@ eo: pdf_gantt: "PDF Gantt" image: omitted: "Bildo ne eksportita." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/es.yml b/config/locales/crowdin/es.yml index 152d6eb01df5..ceeb050ec753 100644 --- a/config/locales/crowdin/es.yml +++ b/config/locales/crowdin/es.yml @@ -297,6 +297,12 @@ es: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: Actualmente no hay tipos disponibles. form: @@ -1607,6 +1613,12 @@ es: pdf_gantt: "PDF Gantt" image: omitted: "Imagen no exportada." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/et.yml b/config/locales/crowdin/et.yml index 218b9a9ad47b..27264a2abd63 100644 --- a/config/locales/crowdin/et.yml +++ b/config/locales/crowdin/et.yml @@ -300,6 +300,12 @@ et: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: There are currently no types available. form: @@ -1610,6 +1616,12 @@ et: pdf_gantt: "PDF Gantt" image: omitted: "Image not exported." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/eu.yml b/config/locales/crowdin/eu.yml index 5834b70abd83..5b13cbd6a71e 100644 --- a/config/locales/crowdin/eu.yml +++ b/config/locales/crowdin/eu.yml @@ -300,6 +300,12 @@ eu: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: There are currently no types available. form: @@ -1610,6 +1616,12 @@ eu: pdf_gantt: "PDF Gantt" image: omitted: "Image not exported." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/fa.yml b/config/locales/crowdin/fa.yml index b974534ed50f..53eea8f5f584 100644 --- a/config/locales/crowdin/fa.yml +++ b/config/locales/crowdin/fa.yml @@ -300,6 +300,12 @@ fa: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: There are currently no types available. form: @@ -1610,6 +1616,12 @@ fa: pdf_gantt: "PDF Gantt" image: omitted: "Image not exported." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/fi.yml b/config/locales/crowdin/fi.yml index f6a81986f13d..3be7f249e580 100644 --- a/config/locales/crowdin/fi.yml +++ b/config/locales/crowdin/fi.yml @@ -300,6 +300,12 @@ fi: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: Tällä hetkellä tyyppejä ei ole saatavilla. form: @@ -1610,6 +1616,12 @@ fi: pdf_gantt: "PDF Gantt" image: omitted: "Image not exported." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/fil.yml b/config/locales/crowdin/fil.yml index 5fc508ce112f..bc68eb9eb44e 100644 --- a/config/locales/crowdin/fil.yml +++ b/config/locales/crowdin/fil.yml @@ -300,6 +300,12 @@ fil: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: Sa kasalukuyan ay walang mga uri na available. form: @@ -1610,6 +1616,12 @@ fil: pdf_gantt: "PDF Gantt" image: omitted: "Image not exported." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/fr.yml b/config/locales/crowdin/fr.yml index 2372d3248256..9eceeabf752f 100644 --- a/config/locales/crowdin/fr.yml +++ b/config/locales/crowdin/fr.yml @@ -300,6 +300,12 @@ fr: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: Il n'y a actuellement aucun type disponible. form: @@ -1610,6 +1616,12 @@ fr: pdf_gantt: "PDF Gantt" image: omitted: "Image non exportée." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: j diff --git a/config/locales/crowdin/he.yml b/config/locales/crowdin/he.yml index 33bb962cf831..d9c7f8d99e56 100644 --- a/config/locales/crowdin/he.yml +++ b/config/locales/crowdin/he.yml @@ -300,6 +300,12 @@ he: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: There are currently no types available. form: @@ -1676,6 +1682,12 @@ he: pdf_gantt: "PDF Gantt" image: omitted: "Image not exported." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/hi.yml b/config/locales/crowdin/hi.yml index fe1dd29095c9..9aff67140875 100644 --- a/config/locales/crowdin/hi.yml +++ b/config/locales/crowdin/hi.yml @@ -300,6 +300,12 @@ hi: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: There are currently no types available. form: @@ -1608,6 +1614,12 @@ hi: pdf_gantt: "PDF Gantt" image: omitted: "Image not exported." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/hr.yml b/config/locales/crowdin/hr.yml index 431560bee2ef..02f4cef1fd22 100644 --- a/config/locales/crowdin/hr.yml +++ b/config/locales/crowdin/hr.yml @@ -300,6 +300,12 @@ hr: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: Trenutno nema dostupnih tipova. form: @@ -1643,6 +1649,12 @@ hr: pdf_gantt: "PDF Gantt" image: omitted: "Image not exported." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/hu.yml b/config/locales/crowdin/hu.yml index 9bc6c74f86b3..f3fe3fc6d141 100644 --- a/config/locales/crowdin/hu.yml +++ b/config/locales/crowdin/hu.yml @@ -299,6 +299,12 @@ hu: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: Jelenleg nincs elérhető típus. form: @@ -1607,6 +1613,12 @@ hu: pdf_gantt: "PDF Gantt" image: omitted: "Kép nem került exportálásra." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: óra days: nap diff --git a/config/locales/crowdin/id.yml b/config/locales/crowdin/id.yml index d088021d52ed..498130de3d37 100644 --- a/config/locales/crowdin/id.yml +++ b/config/locales/crowdin/id.yml @@ -294,6 +294,12 @@ id: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: There are currently no types available. form: @@ -1570,6 +1576,12 @@ id: pdf_gantt: "PDF Gantt" image: omitted: "Gambar tidak diekspor." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: j days: h diff --git a/config/locales/crowdin/it.yml b/config/locales/crowdin/it.yml index 1505cf26ed4b..458b23cdf021 100644 --- a/config/locales/crowdin/it.yml +++ b/config/locales/crowdin/it.yml @@ -297,6 +297,12 @@ it: is_required_blank_slate: heading: Richiesto in tutti i progetti description: Questo attributo di progetto è attivato in tutti i progetti, poiché l'opzione "Richiesto in tutti i progetti" è selezionata. Non può essere disattivato per i singoli progetti. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: Al momento non sono disponibili tipi. form: @@ -1607,6 +1613,12 @@ it: pdf_gantt: "Gantt in PDF" image: omitted: "Immagine non esportata." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: o days: g diff --git a/config/locales/crowdin/ja.yml b/config/locales/crowdin/ja.yml index 89e912cc08ae..7da60486d7b5 100644 --- a/config/locales/crowdin/ja.yml +++ b/config/locales/crowdin/ja.yml @@ -298,6 +298,12 @@ ja: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: 現在、有効な種類はありません。 form: @@ -1573,6 +1579,12 @@ ja: pdf_gantt: "PDF Gantt" image: omitted: "画像はエクスポートされませんでした。" + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/js-af.yml b/config/locales/crowdin/js-af.yml index 9658d6acfc83..06d0484df2aa 100644 --- a/config/locales/crowdin/js-af.yml +++ b/config/locales/crowdin/js-af.yml @@ -274,6 +274,11 @@ af: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "on" diff --git a/config/locales/crowdin/js-ar.yml b/config/locales/crowdin/js-ar.yml index 2ad7f5630274..fa96ca430ccf 100644 --- a/config/locales/crowdin/js-ar.yml +++ b/config/locales/crowdin/js-ar.yml @@ -274,6 +274,11 @@ ar: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "في" diff --git a/config/locales/crowdin/js-az.yml b/config/locales/crowdin/js-az.yml index 21d40ec39cf3..cad353152936 100644 --- a/config/locales/crowdin/js-az.yml +++ b/config/locales/crowdin/js-az.yml @@ -274,6 +274,11 @@ az: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "on" diff --git a/config/locales/crowdin/js-be.yml b/config/locales/crowdin/js-be.yml index 4f7f5d4f4024..740a1bfff54e 100644 --- a/config/locales/crowdin/js-be.yml +++ b/config/locales/crowdin/js-be.yml @@ -274,6 +274,11 @@ be: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "on" diff --git a/config/locales/crowdin/js-bg.yml b/config/locales/crowdin/js-bg.yml index 0bbfae1f147a..cbd513bf16bd 100644 --- a/config/locales/crowdin/js-bg.yml +++ b/config/locales/crowdin/js-bg.yml @@ -274,6 +274,11 @@ bg: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "на" diff --git a/config/locales/crowdin/js-ca.yml b/config/locales/crowdin/js-ca.yml index 90f8dce119e6..08fe1aa5995b 100644 --- a/config/locales/crowdin/js-ca.yml +++ b/config/locales/crowdin/js-ca.yml @@ -274,6 +274,11 @@ ca: warning: > Els canvis poden tardar un temps a ser aplicats. Et notificarem un cop s'hagin actualitzat tots els paquets de treball rellevants. Estàs segur que vols continuar? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "en" diff --git a/config/locales/crowdin/js-ckb-IR.yml b/config/locales/crowdin/js-ckb-IR.yml index 1e83eaf45e08..8fe2f55b203c 100644 --- a/config/locales/crowdin/js-ckb-IR.yml +++ b/config/locales/crowdin/js-ckb-IR.yml @@ -274,6 +274,11 @@ ckb-IR: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "on" diff --git a/config/locales/crowdin/js-cs.yml b/config/locales/crowdin/js-cs.yml index cd56de58cc31..b67c8300404b 100644 --- a/config/locales/crowdin/js-cs.yml +++ b/config/locales/crowdin/js-cs.yml @@ -273,6 +273,11 @@ cs: change_description: "Změna, těch dnů v týdnu, které jsou považovány za pracovní dny, může ovlivnit datum zahájení a datum ukončení všech pracovních balíčků ve všech projektech \n v této instanci." warning: > + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "zapnuto" diff --git a/config/locales/crowdin/js-da.yml b/config/locales/crowdin/js-da.yml index a68b6180c7d0..b8c97debaff0 100644 --- a/config/locales/crowdin/js-da.yml +++ b/config/locales/crowdin/js-da.yml @@ -273,6 +273,11 @@ da: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "på" diff --git a/config/locales/crowdin/js-de.yml b/config/locales/crowdin/js-de.yml index 4ac4661bcc4c..06f59d1c38a0 100644 --- a/config/locales/crowdin/js-de.yml +++ b/config/locales/crowdin/js-de.yml @@ -273,6 +273,11 @@ de: warning: > Es kann einige Zeit dauern, bis die Änderungen wirksam werden. Sie werden benachrichtigt, wenn alle relevanten Arbeitspakete aktualisiert worden sind. Sind Sie sicher, dass Sie fortfahren möchten? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "am" diff --git a/config/locales/crowdin/js-el.yml b/config/locales/crowdin/js-el.yml index 4683d2244f6f..fadaa36f67b4 100644 --- a/config/locales/crowdin/js-el.yml +++ b/config/locales/crowdin/js-el.yml @@ -273,6 +273,11 @@ el: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "σε" diff --git a/config/locales/crowdin/js-eo.yml b/config/locales/crowdin/js-eo.yml index 0cf7866dc02b..75d8afe65a00 100644 --- a/config/locales/crowdin/js-eo.yml +++ b/config/locales/crowdin/js-eo.yml @@ -274,6 +274,11 @@ eo: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "je" diff --git a/config/locales/crowdin/js-es.yml b/config/locales/crowdin/js-es.yml index ddfe1842b65c..631c1f63927c 100644 --- a/config/locales/crowdin/js-es.yml +++ b/config/locales/crowdin/js-es.yml @@ -274,6 +274,11 @@ es: warning: > Los cambios pueden tardar algún tiempo en surtir efecto. Se le notificará cuando todos los paquetes de trabajo relevantes hayan sido actualizados. ¿Está seguro de que desea continuar? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "en" diff --git a/config/locales/crowdin/js-et.yml b/config/locales/crowdin/js-et.yml index 926d8a622677..b37cf89f73c9 100644 --- a/config/locales/crowdin/js-et.yml +++ b/config/locales/crowdin/js-et.yml @@ -274,6 +274,11 @@ et: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "on" diff --git a/config/locales/crowdin/js-eu.yml b/config/locales/crowdin/js-eu.yml index facaca6d41d7..cb5eb01c8734 100644 --- a/config/locales/crowdin/js-eu.yml +++ b/config/locales/crowdin/js-eu.yml @@ -274,6 +274,11 @@ eu: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "on" diff --git a/config/locales/crowdin/js-fa.yml b/config/locales/crowdin/js-fa.yml index 6cfc2216dc10..efbfd32f297e 100644 --- a/config/locales/crowdin/js-fa.yml +++ b/config/locales/crowdin/js-fa.yml @@ -274,6 +274,11 @@ fa: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "برخط" diff --git a/config/locales/crowdin/js-fi.yml b/config/locales/crowdin/js-fi.yml index 1414c66ec279..ce230f101dd5 100644 --- a/config/locales/crowdin/js-fi.yml +++ b/config/locales/crowdin/js-fi.yml @@ -274,6 +274,11 @@ fi: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "päälle" diff --git a/config/locales/crowdin/js-fil.yml b/config/locales/crowdin/js-fil.yml index 088eda3dd3a2..16e8933fad45 100644 --- a/config/locales/crowdin/js-fil.yml +++ b/config/locales/crowdin/js-fil.yml @@ -274,6 +274,11 @@ fil: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "sa" diff --git a/config/locales/crowdin/js-fr.yml b/config/locales/crowdin/js-fr.yml index 5a442381926f..b8333debc36e 100644 --- a/config/locales/crowdin/js-fr.yml +++ b/config/locales/crowdin/js-fr.yml @@ -274,6 +274,11 @@ fr: warning: > Les modifications pourraient prendre un certain temps pour être appliquées. Vous serez averti(e) lorsque tous les lots de travaux pertinents auront été mis à jour. Voulez-vous continuer ? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "le" diff --git a/config/locales/crowdin/js-he.yml b/config/locales/crowdin/js-he.yml index 14b8993eef32..8c679ec6fe2d 100644 --- a/config/locales/crowdin/js-he.yml +++ b/config/locales/crowdin/js-he.yml @@ -274,6 +274,11 @@ he: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "פועל" diff --git a/config/locales/crowdin/js-hi.yml b/config/locales/crowdin/js-hi.yml index 488a8c91b901..726e7ef078a4 100644 --- a/config/locales/crowdin/js-hi.yml +++ b/config/locales/crowdin/js-hi.yml @@ -274,6 +274,11 @@ hi: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "पर" diff --git a/config/locales/crowdin/js-hr.yml b/config/locales/crowdin/js-hr.yml index 49f01998cca4..c2a6f1cf4db2 100644 --- a/config/locales/crowdin/js-hr.yml +++ b/config/locales/crowdin/js-hr.yml @@ -274,6 +274,11 @@ hr: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "na" diff --git a/config/locales/crowdin/js-hu.yml b/config/locales/crowdin/js-hu.yml index e235cee0bd55..5250ed74383d 100644 --- a/config/locales/crowdin/js-hu.yml +++ b/config/locales/crowdin/js-hu.yml @@ -274,6 +274,11 @@ hu: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "be" diff --git a/config/locales/crowdin/js-id.yml b/config/locales/crowdin/js-id.yml index 883e53cc26b1..7d81b5a34434 100644 --- a/config/locales/crowdin/js-id.yml +++ b/config/locales/crowdin/js-id.yml @@ -274,6 +274,11 @@ id: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "pada" diff --git a/config/locales/crowdin/js-it.yml b/config/locales/crowdin/js-it.yml index b2aaa57fb2ef..0ba584eaf4a8 100644 --- a/config/locales/crowdin/js-it.yml +++ b/config/locales/crowdin/js-it.yml @@ -274,6 +274,11 @@ it: warning: > L'applicazione delle modifiche potrebbe richiedere del tempo. Riceverai una notifica quando tutti i pacchetti di lavoro pertinenti saranno aggiornati. Vuoi davvero continuare? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "il" diff --git a/config/locales/crowdin/js-ja.yml b/config/locales/crowdin/js-ja.yml index 2e2d72183ed6..83ab1924dfd3 100644 --- a/config/locales/crowdin/js-ja.yml +++ b/config/locales/crowdin/js-ja.yml @@ -275,6 +275,11 @@ ja: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "オン" diff --git a/config/locales/crowdin/js-ka.yml b/config/locales/crowdin/js-ka.yml index 5b3db1472fa7..cdeeb4533666 100644 --- a/config/locales/crowdin/js-ka.yml +++ b/config/locales/crowdin/js-ka.yml @@ -274,6 +274,11 @@ ka: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "დრო" diff --git a/config/locales/crowdin/js-kk.yml b/config/locales/crowdin/js-kk.yml index 87d0840e44ee..4f5ea4b84d79 100644 --- a/config/locales/crowdin/js-kk.yml +++ b/config/locales/crowdin/js-kk.yml @@ -274,6 +274,11 @@ kk: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "on" diff --git a/config/locales/crowdin/js-ko.yml b/config/locales/crowdin/js-ko.yml index d4f0540fad4c..9a2f670ed8c4 100644 --- a/config/locales/crowdin/js-ko.yml +++ b/config/locales/crowdin/js-ko.yml @@ -274,6 +274,11 @@ ko: warning: > 변경 사항이 적용되는 데 시간이 걸릴 수 있습니다. 모든 관련 작업 패키지가 업데이트되면 알림이 전송됩니다. 계속하시겠습니까? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "에" diff --git a/config/locales/crowdin/js-lt.yml b/config/locales/crowdin/js-lt.yml index 2d0c87d3bb76..209637feef8e 100644 --- a/config/locales/crowdin/js-lt.yml +++ b/config/locales/crowdin/js-lt.yml @@ -274,6 +274,11 @@ lt: warning: > Pakeitimų įsigaliojimas gali užtrukti. Jums bus pranešta, kai visi susiję darbo paketai bus atnaujinti. Ar tikrai norite tęsti? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "įjungta" diff --git a/config/locales/crowdin/js-lv.yml b/config/locales/crowdin/js-lv.yml index cf4f38c711dd..e69ab5f81739 100644 --- a/config/locales/crowdin/js-lv.yml +++ b/config/locales/crowdin/js-lv.yml @@ -274,6 +274,11 @@ lv: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: " " diff --git a/config/locales/crowdin/js-mn.yml b/config/locales/crowdin/js-mn.yml index 47577b14bd22..23c9f97d706b 100644 --- a/config/locales/crowdin/js-mn.yml +++ b/config/locales/crowdin/js-mn.yml @@ -274,6 +274,11 @@ mn: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "on" diff --git a/config/locales/crowdin/js-ms.yml b/config/locales/crowdin/js-ms.yml index bd8ba74bea5f..7563f36c8cdc 100644 --- a/config/locales/crowdin/js-ms.yml +++ b/config/locales/crowdin/js-ms.yml @@ -22,7 +22,7 @@ ms: js: ajax: - hide: "Sorokkan" + hide: "Sembunyikan" loading: "Memuatkan..." updating: "Mengemas kini..." attachments: @@ -146,7 +146,7 @@ ms: manual: "Tukar ke sumber Markdown" wysiwyg: "Tukar ke editor WYSIWYG" macro: - error: "Tidak dapat kembangkan macro: %{message}" + error: "Tidak dapat kembangkan makro: %{message}" attribute_reference: macro_help_tooltip: "Bahagian teks ini sedang dihasilkan secara dinamik oleh makro." not_found: "Sumber yang diminta tidak dapat ditemui" @@ -168,7 +168,7 @@ ms: macros: "Makro-makro" chose_macro: "Pilih makro" toc: "Jadual kandungan" - toolbar_help: "Klik untuk memilih widget dan tunjuk toolbar. Klik dua kali untuk edit widget" + toolbar_help: "Klik untuk memilih widget dan paparkan toolbar. Klik dua kali untuk edit widget" wiki_page_include: button: "Sertakan kandungan halaman wiki lain" text: "[Placeholder] Termasuk halaman wiki" @@ -205,7 +205,7 @@ ms: trial: confirmation: "Pengesahan alamat e-mel " confirmation_info: > - Kami telah menghantar satu e-mel kepada anda pada %{date} kepada %{email}. Sila semak peti masuk anda dan klik pautan pengesahan yang disediakan untuk memulakan percubaan 14 hari anda. + Kami telah menghantar e-mel kepada anda pada %{date} di %{email}. Sila semak peti masuk anda dan klik pautan pengesahan yang disediakan untuk memulakan percubaan 14 hari anda. form: general_consent: > Saya bersetuju dengan syarat-syarat perkhidmatan dan polisi privasi. @@ -247,7 +247,7 @@ ms: premium_features: "Tambahan Enterprise" premium_features_text: "Board Agile, tema tersuai dan logo, graf, aliran kerja yang cerdas dengan tindakan tersuai, carian teks penuh untuk lampiran pakej kerja dan pelbagai pilihan ruang tersuai." professional_support: "Sokongan profesional" - professional_support_text: "Dapatkan sokongan yang boleh dipercayai, sentuhan tinggi daripada jurutera sokongan kanan dengan pengetahuan pakar tentang menjalankan OpenProject dalam persekitaran perniagaan yang kritikal." + professional_support_text: "Dapatkan sokongan yang boleh dipercayai, sokongan peribadi yang berkualiti tinggi daripada jurutera sokongan berpengalaman dengan pengetahuan pakar tentang menjalankan OpenProject dalam persekitaran perniagaan yang kritikal." button_start_trial: "Mulakan percubaan percuma" button_upgrade: "Naik taraf sekarang" button_contact_us: "Hubungi kami untuk demo" @@ -267,13 +267,18 @@ ms: new_date: "(baharu)" add_non_working_day: "Hari tidak bekerja" already_added_error: "Hari tidak bekerja untuk tarikh ini sudah ada. Hanya boleh mempunyai satu hari tidak bekerja dicipta untuk setiap tarikh yang unik." - change_button: "Simpan dan jadual semula" + change_button: "Simpan dan jadualkan semula" change_title: "Tukar hari bekerja" removed_title: "Anda akan mengeluarkan hari berikut dari senarai hari tidak bekerja:" change_description: "Mengubah hari dalam seminggu yang dianggap hari bekerja atau hari tidak bekerja akan mempengaruhi hari mula dan selesai semua pakej kerja dalam semua projek dalam kejadian ini." warning: > Perubahan mungkin mengambil sedikit masa untuk berkesan. Anda akan dimaklumkan apabila semua pakej kerja yang berkaitan telah dikemas kini. Adakah anda pasti anda ingin teruskan? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "pada" @@ -365,9 +370,9 @@ ms: new_features_html: > Keluaran tersebut mengandungi pelbagai fitur baharu dan penambahbaikan:
    • eksport PDF paparan Gantt, cth. untuk mencetak (tambahan Enterprise)
    • Projek kegemaran
    • Bahagian dalam Mesyuarat
    • Paparkan mesyuarat di Halaman Saya dan halaman gambaran keseluruhan projek
    • Kemungkinan untuk sorokkan lampiran dalam tab Fail
    • Ruang tersuai jenis Pautan (URL)
    ical_sharing_modal: - title: "Langgan ke kalendar" + title: "Langgan kalendar" inital_setup_error_message: "Ralat berlaku ketika sedang mengambil data." - description: "Anda boleh menggunakan URL (iCalendar) untuk melanggan ke kalendar ini dalam pelanggan luaran dan lihat maklumat pakej kerja terkini dari situ." + description: "Anda boleh menggunakan URL (iCalendar) untuk melanggan kalendar ini dalam pelanggan luaran dan lihat maklumat pakej kerja terkini dari situ." warning: "Sila jangan kongsi URL ini dengan pengguna lain. Sesiapa sahaja yang mempunyai pautan ini akan boleh melihat butiran pakej kerja tanpa akaun atau kata laluan." token_name_label: "Dimanakah anda akan menggunakan ini?" token_name_placeholder: 'Taip nama, cth. "Telefon"' @@ -451,7 +456,7 @@ ms: label_invalid: "Tidak sah" label_import: "Import" label_latest_activity: "Aktiviti terkini" - label_last_updated_on: "Dikemas kini terakhir pada" + label_last_updated_on: "Kemas kini terakhir pada" label_learn_more_link: "Ketahui lebih lanjut" label_less_or_equal: "<=" label_less_than_ago: "kurang dari beberapa hari yang lalu" @@ -562,8 +567,8 @@ ms: label_rejected_files: "Fail-fail tersebut tidak dapat dimuat naik:" label_rejected_files_reason: "Fail-fail tersebut tidak boleh dimuat naik kerana saiz mereka adalah lebih besar daripada %{maximumFilesize}" label_wait: "Sila tunggu untuk konfigurasi..." - label_upload_counter: "%{done} dari %{count} fail selesai" - label_validation_error: "Pakej kerja tidak dapat disimpan kerana ralat berikut:" + label_upload_counter: "%{done} daripada %{count} fail selesai" + label_validation_error: "Pakej kerja tidak dapat disimpan disebabkan ralat berikut:" label_version_plural: "Versi-versi" label_view_has_changed: "Paparan ini mempunyai perubahan yang tidak disimpan. Klik untuk simpan mereka." help_texts: @@ -574,12 +579,12 @@ ms: next: "Seterusnya" got_it: "Faham" steps: - help_menu: "Menu Bantuan (?) menyediakan sumber bantuan tambahan. Di sini anda akan menjumpai panduan pengguna, video panduan membantu dan lebih lagi.
    Nikmati kerja anda di OpenProject!" - members: "Jemput ahli baru untuk sertai projek anda." - quick_add_button: "Klik pada ikon tambah (+) dalam navigasi pengepala untuk cipta projek baru atau untuk jemput rakan sekerja." + help_menu: "Menu Bantuan (?) menyediakan sumber bantuan tambahan. Di sini anda akan menjumpai panduan pengguna, video panduan dan lebih lagi.
    Nikmati kerja anda di OpenProject!" + members: "Jemput ahli baharu untuk sertai projek anda." + quick_add_button: "Klik ikon tambah (+) dalam navigasi pengepala untuk cipta projek baharu atau untuk jemput rakan sekerja." sidebar_arrow: "Guna anak panah kembali di sudut kiri atas untuk kembali ke menu utama projek." welcome: "Ambil lawatan pengenalan 3 minit untuk belajar fitur-fitur penting dengan banyak.
    Kami sarankan melengkapi langkah-langkah tersebut sehingga ke akhirnya. Anda boleh mula semula lawatan bila-bila masa." - wiki: "Dalam wiki anda boleh mendokumentasikan dan kongsi pengetahuan bersama dengan pasukan anda." + wiki: "Dalam wiki anda boleh mendokumentasikan dan kongsi pengetahuan bersama pasukan anda." backlogs: overview: "Kendalikan kerja anda dalam paparan tunggakan." sprints: "Di kanan anda mempunyai tunggakan produk dan tunggakan bug, di kiri anda mempunyai pecutan yang berkenaan. Di sini anda boleh mencipta epik, cerita pengguna, dan bug, utamakan dengan menarik & melepaskan dan tambah mereka ke pecutan." diff --git a/config/locales/crowdin/js-ne.yml b/config/locales/crowdin/js-ne.yml index 97fb75ef4026..00ce390e2704 100644 --- a/config/locales/crowdin/js-ne.yml +++ b/config/locales/crowdin/js-ne.yml @@ -274,6 +274,11 @@ ne: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "on" diff --git a/config/locales/crowdin/js-nl.yml b/config/locales/crowdin/js-nl.yml index 76ba03afa77c..20f8a2529eda 100644 --- a/config/locales/crowdin/js-nl.yml +++ b/config/locales/crowdin/js-nl.yml @@ -274,6 +274,11 @@ nl: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "op" diff --git a/config/locales/crowdin/js-no.yml b/config/locales/crowdin/js-no.yml index f560f80dd630..40b6ee3607c5 100644 --- a/config/locales/crowdin/js-no.yml +++ b/config/locales/crowdin/js-no.yml @@ -274,6 +274,11 @@ warning: > Endringene kan ta noe tid på å bli effektivisert. Du vil bli varslet når alle relevante arbeidspakker har blitt oppdatert. Er du sikker på at du vil fortsette? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "på" diff --git a/config/locales/crowdin/js-pl.yml b/config/locales/crowdin/js-pl.yml index cf8ce18985b7..3dae16f6d1e3 100644 --- a/config/locales/crowdin/js-pl.yml +++ b/config/locales/crowdin/js-pl.yml @@ -274,6 +274,11 @@ pl: warning: > Zmiany mogą wejść w życie po pewnym czasie. Gdy wszystkie odpowiednie pakiety robocze zostaną zaktualizowane, otrzymasz powiadomienie. Czy na pewno chcesz kontynuować? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "wł" diff --git a/config/locales/crowdin/js-pt-BR.yml b/config/locales/crowdin/js-pt-BR.yml index 3655ce93fbc4..e760427cd047 100644 --- a/config/locales/crowdin/js-pt-BR.yml +++ b/config/locales/crowdin/js-pt-BR.yml @@ -273,6 +273,11 @@ pt-BR: warning: > As alterações podem demorar algum tempo para entrar em vigor. Receberá uma notificação quando todos os pacotes de trabalho relevantes forem atualizados. Tem a certeza de que deseja continuar? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "ligado" diff --git a/config/locales/crowdin/js-pt-PT.yml b/config/locales/crowdin/js-pt-PT.yml index d4c4510599e7..35a2d3aa77d3 100644 --- a/config/locales/crowdin/js-pt-PT.yml +++ b/config/locales/crowdin/js-pt-PT.yml @@ -274,6 +274,11 @@ pt-PT: warning: > As alterações podem demorar algum tempo a entrar em vigor. Receberá uma notificação quando todos os pacotes de trabalho relevantes forem atualizados. Tem a certeza de que quer continuar? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "on" diff --git a/config/locales/crowdin/js-ro.yml b/config/locales/crowdin/js-ro.yml index 4cb892d2d43d..937aa3b60453 100644 --- a/config/locales/crowdin/js-ro.yml +++ b/config/locales/crowdin/js-ro.yml @@ -273,6 +273,11 @@ ro: warning: > Modificările ar putea dura ceva timp pentru a produce efecte. Vei fi notificat când toate pachetele de lucru relevante au fost actualizate. Ești sigur că vrei să continui? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "pe" diff --git a/config/locales/crowdin/js-ru.yml b/config/locales/crowdin/js-ru.yml index 7c78db83986d..225deb25d762 100644 --- a/config/locales/crowdin/js-ru.yml +++ b/config/locales/crowdin/js-ru.yml @@ -273,6 +273,11 @@ ru: warning: > Для вступления изменений в силу может потребоваться некоторое время. Вы будете уведомлены, когда все соответствующие пакеты работ будут обновлены. Хотите продолжить? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "вкл" diff --git a/config/locales/crowdin/js-rw.yml b/config/locales/crowdin/js-rw.yml index de70f87987a5..d82d03e07d61 100644 --- a/config/locales/crowdin/js-rw.yml +++ b/config/locales/crowdin/js-rw.yml @@ -274,6 +274,11 @@ rw: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "on" diff --git a/config/locales/crowdin/js-si.yml b/config/locales/crowdin/js-si.yml index 0be8ec876f69..95f1e050c165 100644 --- a/config/locales/crowdin/js-si.yml +++ b/config/locales/crowdin/js-si.yml @@ -274,6 +274,11 @@ si: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "මත" diff --git a/config/locales/crowdin/js-sk.yml b/config/locales/crowdin/js-sk.yml index b57add8da9c4..fc048453d3e8 100644 --- a/config/locales/crowdin/js-sk.yml +++ b/config/locales/crowdin/js-sk.yml @@ -274,6 +274,11 @@ sk: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "dňa" diff --git a/config/locales/crowdin/js-sl.yml b/config/locales/crowdin/js-sl.yml index 4dfc4e6c2010..48ec63af3779 100644 --- a/config/locales/crowdin/js-sl.yml +++ b/config/locales/crowdin/js-sl.yml @@ -273,6 +273,11 @@ sl: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "vključeno" diff --git a/config/locales/crowdin/js-sr.yml b/config/locales/crowdin/js-sr.yml index 87dfae798587..c00dd6c7b2a0 100644 --- a/config/locales/crowdin/js-sr.yml +++ b/config/locales/crowdin/js-sr.yml @@ -274,6 +274,11 @@ sr: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "on" diff --git a/config/locales/crowdin/js-sv.yml b/config/locales/crowdin/js-sv.yml index ea2dee1eaaa9..67d3cbd57ea7 100644 --- a/config/locales/crowdin/js-sv.yml +++ b/config/locales/crowdin/js-sv.yml @@ -273,6 +273,11 @@ sv: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "på" diff --git a/config/locales/crowdin/js-th.yml b/config/locales/crowdin/js-th.yml index 4493f3e50d33..d48c8db3abab 100644 --- a/config/locales/crowdin/js-th.yml +++ b/config/locales/crowdin/js-th.yml @@ -274,6 +274,11 @@ th: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "on" diff --git a/config/locales/crowdin/js-tr.yml b/config/locales/crowdin/js-tr.yml index d11d44979782..9c4b64897a38 100644 --- a/config/locales/crowdin/js-tr.yml +++ b/config/locales/crowdin/js-tr.yml @@ -273,6 +273,11 @@ tr: change_description: "Haftanın hangi günlerinin iş günü olarak kabul edileceğini değiştirmek, bu durumda tüm projelerdeki tüm iş paketlerinin başlangıç ve bitiş günlerini etkileyebilir." warning: > Değişikliklerin geçerlilik kazanması biraz zaman alabilir. İlgili tüm iş paketleri güncellendiğinde bilgilendirileceksiniz. Devam etmek istediğine emin misin? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "açık" diff --git a/config/locales/crowdin/js-uk.yml b/config/locales/crowdin/js-uk.yml index 50c42ec7fed7..596357093a93 100644 --- a/config/locales/crowdin/js-uk.yml +++ b/config/locales/crowdin/js-uk.yml @@ -274,6 +274,11 @@ uk: warning: > Застосування змін може тривати деякий час. Ви отримаєте сповіщення, коли всі відповідні пакети робіт буде оновлено. Продовжити? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "на" diff --git a/config/locales/crowdin/js-uz.yml b/config/locales/crowdin/js-uz.yml index dce517e42c4e..63ca003fa244 100644 --- a/config/locales/crowdin/js-uz.yml +++ b/config/locales/crowdin/js-uz.yml @@ -274,6 +274,11 @@ uz: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "on" diff --git a/config/locales/crowdin/js-vi.yml b/config/locales/crowdin/js-vi.yml index 6949645064f8..e876c63f7e01 100644 --- a/config/locales/crowdin/js-vi.yml +++ b/config/locales/crowdin/js-vi.yml @@ -273,6 +273,11 @@ vi: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "lúc" diff --git a/config/locales/crowdin/js-zh-CN.yml b/config/locales/crowdin/js-zh-CN.yml index a9e97fc4706e..3b0b304bef78 100644 --- a/config/locales/crowdin/js-zh-CN.yml +++ b/config/locales/crowdin/js-zh-CN.yml @@ -273,6 +273,11 @@ zh-CN: change_description: "更改一周中哪些天被视为工作日或非工作日可能会影响此实例中所有项目中所有工作包的开始和结束日期。" warning: > 更改可能需要一些时间才能生效。当更新完所有相关工作包时,您将收到通知。 + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "于" diff --git a/config/locales/crowdin/js-zh-TW.yml b/config/locales/crowdin/js-zh-TW.yml index d5be49e99a88..1cd8ec4a7c23 100644 --- a/config/locales/crowdin/js-zh-TW.yml +++ b/config/locales/crowdin/js-zh-TW.yml @@ -273,6 +273,11 @@ zh-TW: warning: > The changes might take some time to take effect. You will be notified when all relevant work packages have been updated. Are you sure you want to continue? + work_packages_settings: + warning_progress_calculation_mode_change_from_status_to_field_html: >- + Changing progress calculation mode from status-based to work-based will make % Complete a non-editable field whose value is derived from Work and Remaining work. Existing values for % Complete are preserved. If values for Work and Remaining work were not present, they will be required in order to change % Complete. + warning_progress_calculation_mode_change_from_field_to_status_html: >- + Changing progress calculation mode from work-based to status-based will result in all existing % Complete values to be lost and replaced with values associated with each status. Existing values for Remaining work may also be recalculated to reflect this change. This action is not reversible. custom_actions: date: specific: "開啟" diff --git a/config/locales/crowdin/ka.yml b/config/locales/crowdin/ka.yml index 0d98d5b23051..e50eac593044 100644 --- a/config/locales/crowdin/ka.yml +++ b/config/locales/crowdin/ka.yml @@ -300,6 +300,12 @@ ka: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: There are currently no types available. form: @@ -1610,6 +1616,12 @@ ka: pdf_gantt: "PDF Gantt" image: omitted: "Image not exported." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: სთ days: დ diff --git a/config/locales/crowdin/kk.yml b/config/locales/crowdin/kk.yml index e7bbb4ae4416..4b35fd9f7503 100644 --- a/config/locales/crowdin/kk.yml +++ b/config/locales/crowdin/kk.yml @@ -300,6 +300,12 @@ kk: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: There are currently no types available. form: @@ -1610,6 +1616,12 @@ kk: pdf_gantt: "PDF Gantt" image: omitted: "Image not exported." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/ko.yml b/config/locales/crowdin/ko.yml index c6c2bc0d0756..481d7836ac00 100644 --- a/config/locales/crowdin/ko.yml +++ b/config/locales/crowdin/ko.yml @@ -300,6 +300,12 @@ ko: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: 사용 가능한 타입이 없습니다. form: @@ -1576,6 +1582,12 @@ ko: pdf_gantt: "PDF Gantt" image: omitted: "이미지를 내보내지 못했습니다." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: 시간 days: 일 diff --git a/config/locales/crowdin/lt.yml b/config/locales/crowdin/lt.yml index 6c4acc0d6a30..f0100301db00 100644 --- a/config/locales/crowdin/lt.yml +++ b/config/locales/crowdin/lt.yml @@ -297,6 +297,12 @@ lt: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: Nėra prieinamų tipų. form: @@ -1673,6 +1679,12 @@ lt: pdf_gantt: "PDF Gantt" image: omitted: "Paveiksliukas neeksportuotas." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/lv.yml b/config/locales/crowdin/lv.yml index f3112f929518..3809b9d7ed44 100644 --- a/config/locales/crowdin/lv.yml +++ b/config/locales/crowdin/lv.yml @@ -300,6 +300,12 @@ lv: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: Pašlaik nav pieejams neviens veids. form: @@ -1643,6 +1649,12 @@ lv: pdf_gantt: "PDF Gantt" image: omitted: "Image not exported." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/mn.yml b/config/locales/crowdin/mn.yml index f4b2637f43df..0a18aed74724 100644 --- a/config/locales/crowdin/mn.yml +++ b/config/locales/crowdin/mn.yml @@ -300,6 +300,12 @@ mn: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: There are currently no types available. form: @@ -1610,6 +1616,12 @@ mn: pdf_gantt: "PDF Gantt" image: omitted: "Image not exported." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/ms.yml b/config/locales/crowdin/ms.yml index 4d630ae9fa2c..6c8dbf133d7e 100644 --- a/config/locales/crowdin/ms.yml +++ b/config/locales/crowdin/ms.yml @@ -299,6 +299,12 @@ ms: is_required_blank_slate: heading: Diperlukan dalam semua projek description: Atribut projek ini telah diaktifkan dalam semua projek sejak pilihan "Diperlukan dalam semua projek" telah ditandakan. Ia tidak boleh dinyahaktifkan untuk projek individu. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: Tiada jenis yang tersedia buat masa ini. form: @@ -1575,6 +1581,12 @@ ms: pdf_gantt: "Gantt PDF" image: omitted: "Imej tidak dieksport." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: j days: h @@ -3412,7 +3424,7 @@ ms: missing_content_type: "tidak ditentukan" missing_property: "Ciri-ciri yang hilang '%{property}'." missing_request_body: "Tiada badan permintaan." - missing_or_malformed_parameter: "Parameter pertanyaan '%{parameter}' tidak ditemui atau cacat." + missing_or_malformed_parameter: "Parameter pertanyaan '%{parameter}' tidak ditemui atau tidak betul." multipart_body_error: "Badan permintaan tidak mempunyai bahagian multipart seperti yang dijangka." multiple_errors: "Beberapa kekangan ruang telah dilanggar." unable_to_create_attachment: "Lampiran tidak boleh dicipta" @@ -3436,31 +3448,31 @@ ms: doorkeeper: pre_authorization: status: "Pra-kebenaran" - auth_url: "Auth URL" + auth_url: "URL Auth" access_token_url: "Akses token URL" errors: messages: #Common error messages invalid_request: - unknown: "Permintaan tersebut tidak mengandungi parameter yang diperlukan, termasuk nilai parameter yang tidak disokong, atau sebaliknya telah cacat." + unknown: "Permintaan tersebut tidak mengandungi parameter yang diperlukan, termasuk nilai parameter yang tidak disokong, atau sebaliknya tidak betul." missing_param: "Parameter yang diperlukan hilang: %{value}." request_not_authorized: "Permintaan perlu dibenarkan. Parameter yang diperlukan untuk membenarkan permintaan tiada atau tidak sah." invalid_redirect_uri: "Pengubah hala URI yang diminta tidak betul atau tidak sepadan dengan pengubah hala URI pelanggan." unauthorized_client: "Pelanggan tersebut tidak dibenarkan untuk melaksanakan permintaan ini menggunakan kaedah ini." access_denied: "Pemilik sumber atau server kebenaran menafikan permintaan ini." - invalid_scope: "Skop yang diminta adalah tidak sah, tidak diketahui, atau salah bentuk." + invalid_scope: "Skop yang diminta adalah tidak sah, tidak diketahui, atau tidak betul." invalid_code_challenge_method: "Kaedah kod cabaran mesti biasa atau S256." server_error: "Server kebenaran mengalami keadaan yang tidak dijangka yang menghalangnya daripada memenuhi permintaan." temporarily_unavailable: "Server kebenaran pada masa ini tidak dapat mengendalikan permintaan kerana beban berlebihan sementara atau penyelenggaraan server." #Configuration error messages credential_flow_not_configured: "Aliran Kelayakan Kata Laluan Pemilik Sumber telah gagal disebabkan oleh Doorkeeper.configure.resource_owner_authenticator tidak dikonfigurasikan." resource_owner_authenticator_not_configured: "Carian Pemilik Sumber gagal kerana Doorkeeper.configure.resource_owner_authenticator tidak dikonfigurasikan." - admin_authenticator_not_configured: "Akses ke panel admin dilarang kerana Doorkeeper.configure.admin_authenticator tidak dikonfigurasi." + admin_authenticator_not_configured: "Akses ke panel pentadbir dilarang kerana Doorkeeper.configure.admin_authenticator tidak dikonfigurasi." #Access grant errors unsupported_response_type: "Server kebenaran tidak menyokong jenis tindak balas ini." unsupported_response_mode: "Server kebenaran tidak menyokong mod tindak balas ini." #Access token errors - invalid_client: "Pengesahan pelanggan gagal kerana pelanggan yang tidak diketahui, tiada pengesahan pelanggan yang disertakan, atau kaedah pengesahan yang tidak disokong." + invalid_client: "Pengesahan pelanggan gagal kerana pelanggan yang tidak diketahui, tiada pengesahan pelanggan yang disertakan, atau kaedah pengesahan tidak disokong." invalid_grant: "Pemberian kebenaran yang diberikan adalah tidak sah, luput, dibatalkan, tidak sepadan dengan pengubah hala URI yang digunakan dalam permintaan kebenaran, atau dikeluarkan kepada pelanggan lain." unsupported_grant_type: "Jenis pemberian kebenaran tidak disokong oleh server pengesahan." invalid_token: @@ -3486,9 +3498,9 @@ ms: instructions: name: "Nama aplikasi anda. Ini akan dipaparkan ke pengguna lain selepas kebenaran." redirect_uri_html: > - URL yang dibenarkan membenarkan pengguna boleh diubah hala. Satu entri setiap baris.
    Jika anda mendaftar aplikasi desktop, guna URL berikut. - confidential: "Semak jika aplikasi akan digunakan dimana rahsia pelanggan boleh dikekalkan sulit. Mobile apps asal dan Single Page Apps dianggap sebagai tidak sulit." - scopes: "Tandakan skop yang anda mahu aplikasi untuk berikan akses. Jika tiada skop ditandakan, api_v3 akan diandaikan." + URL yang dibenarkan membenarkan pengguna boleh diubah hala. Satu entri setiap baris.
    Jika anda mendaftar aplikasi desktop, gunakan URL berikut. + confidential: "Semak jika aplikasi akan digunakan dimana rahsia pelanggan boleh dikekalkan sulit. Aplikasi mudah alih asal dan Single Page Apps dianggap sebagai tidak sulit." + scopes: "Tandakan skop yang anda mahu untuk berikan akses ke aplikasi tersebut. Jika tiada skop ditandakan, api_v3 akan diandaikan." client_credential_user_id: "ID pengguna pilihan untuk menyamar apabila pelanggan menggunakan aplikasi ini. Tinggalkan kosong untuk benarkan akses awam sahaja." register_intro: "Jika anda sedang membangunkan aplikasi pelanggan API OAuth untuk OpenProject, anda boleh mendaftarkannya menggunakan borang ini untuk semua pengguna menggunakannya." default_scopes: "" @@ -3521,7 +3533,7 @@ ms: client_credentials_impersonation_html: > Secara default, OpenProject menyediakan kebenaran OAuth 2.0 melalui %{authorization_code_flow_link}. Anda boleh memilih untuk mengaktifkan %{client_credentials_flow_link}, tetapi anda mesti menyediakan pengguna yang akan mewakili permintaan. authorization_error: "Sebuah ralat kebenaran telah berlaku." - revoke_my_application_confirmation: "Adakah anda benar-benar mahu keluarkan aplikasi ini? Ini akan menarik balik %{token_count} aktif darinya." + revoke_my_application_confirmation: "Adakah anda benar-benar mahu memadam aplikasi ini? Ini akan menarik balik %{token_count} yang aktif darinya." my_registered_applications: "Aplikasi OAuth berdaftar" oauth_client: urn_connection_status: @@ -3531,11 +3543,11 @@ ms: labels: label_oauth_integration: "Integrasi OAuth2" label_redirect_uri: "Ubah hala URI" - label_request_token: "Permintaan token" + label_request_token: "Token permintaan" label_refresh_token: "Token muat semula" errors: oauth_authorization_code_grant_had_errors: "Pemberian pengesahan OAuth2 tidak berjaya" - oauth_reported: "Pembekal OAuth2 melaporkan" + oauth_reported: "Penyedia OAuth2 melaporkan" oauth_returned_error: "OAuth2 telah kembalikan sebuah ralat" oauth_returned_json_error: "OAuth2 telah kembalikan ralat JSON" oauth_returned_http_error: "OAuth2 telah kembalikan ralat rangkaian" @@ -3547,13 +3559,13 @@ ms: Ralat dalaman: Memanggil refresh_token tanpa token yang sedia ada sebelum ini. refresh_token_updated_failed: "Ralat semasa kemas kini OAuthClientToken" oauth_client_not_found_explanation: > - Ralat muncul selepas anda mengemas kini client_id dan client_secret di Openproject, tetapi belum mengemas kini ruangan 'URI Kembali' dalam pembekal OAuth2. + Ralat muncul selepas anda mengemas kini client_id dan client_secret di Openproject, tetapi belum mengemas kini ruangan 'URI Kembali' dalam penyedia OAuth2. oauth_code_not_present: "'Kod' OAuth2 tidak ditemui dalam titik terakhir 'panggilan balik' (redirect_url)." oauth_code_not_present_explanation: > Ralat ini muncul jika anda telah memilih response_type yang salah dalam pembekal OAuth2. Response_type perlu 'kod' atau serupa. oauth_state_not_present: "'Kondisi' OAuth2 tidak ditemui dalam titik terakhir 'panggilan balik' (ubah hala_url)." oauth_state_not_present_explanation: > - 'Kondisi' digunakan untuk menunjukkan ke OpenProject tempat untuk meneruskan selepas kebenaran OAuth2 berjaya. Ketiadaan 'Kondisi' adalah ralat dalaman yang mungkin muncul semasa penyediaan. Sila hubungi pentadbir sistem anda. + 'Kondisi' digunakan untuk menunjukkan ke OpenProject tempat untuk meneruskan selepas kebenaran OAuth2 berjaya. Ketiadaan 'kondisi' adalah ralat dalaman yang mungkin muncul semasa penyediaan. Sila hubungi pentadbir sistem anda. rack_oauth2: client_secret_invalid: "Rahsia pelanggan adalah tidak sah (rahsia_pelanggan_tidak sah)" invalid_request: > @@ -3567,7 +3579,7 @@ ms: http: request: failed_authorization: "Permintaan dari pihak server gagal mengesahkan dirinya sendiri." - missing_authorization: "Permintaan dari pihak server gagal disebabkan maklumat pengesahan yang hilang." + missing_authorization: "Permintaan dari pihak server gagal disebabkan maklumat pengesahan yang hilang." response: unexpected: "Tindak balas yang tidak dijangka diterima." you: anda diff --git a/config/locales/crowdin/ne.yml b/config/locales/crowdin/ne.yml index 17210a739714..135c98c3403c 100644 --- a/config/locales/crowdin/ne.yml +++ b/config/locales/crowdin/ne.yml @@ -300,6 +300,12 @@ ne: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: There are currently no types available. form: @@ -1610,6 +1616,12 @@ ne: pdf_gantt: "PDF Gantt" image: omitted: "छवि निर्यात गरिएको छैन।" + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/nl.yml b/config/locales/crowdin/nl.yml index d872d443a45a..3e7ca5fe74d8 100644 --- a/config/locales/crowdin/nl.yml +++ b/config/locales/crowdin/nl.yml @@ -297,6 +297,12 @@ nl: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: Er zijn momenteel geen types beschikbaar. form: @@ -1607,6 +1613,12 @@ nl: pdf_gantt: "PDF Gantt" image: omitted: "Afbeelding niet geëxporteerd." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: u days: d diff --git a/config/locales/crowdin/no.yml b/config/locales/crowdin/no.yml index 1747eab6485c..954c37419e75 100644 --- a/config/locales/crowdin/no.yml +++ b/config/locales/crowdin/no.yml @@ -300,6 +300,12 @@ is_required_blank_slate: heading: Påkrevd i alle prosjekter description: Prosjektattributten er aktivert i alle prosjekter fordi "Påkrevd i alle prosjekter"-alternativet er valgt. Attributten kan ikke deaktiveres for hvert enkelt prosjekt. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: Det finnes ingen tilgjengelige typer. form: @@ -1609,6 +1615,12 @@ pdf_gantt: "PDF Gantt" image: omitted: "Bilde ikke eksportert." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: t days: d diff --git a/config/locales/crowdin/pl.yml b/config/locales/crowdin/pl.yml index 3617c79bd8c6..407c45647dcc 100644 --- a/config/locales/crowdin/pl.yml +++ b/config/locales/crowdin/pl.yml @@ -297,6 +297,12 @@ pl: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: Nie ma dostępnych typów. form: @@ -1673,6 +1679,12 @@ pl: pdf_gantt: "Wykres Gantta w formacie PDF" image: omitted: "Nie wyeksportowano obrazu" + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/pt-BR.yml b/config/locales/crowdin/pt-BR.yml index 5711acec8f8b..ba6299a3d5b5 100644 --- a/config/locales/crowdin/pt-BR.yml +++ b/config/locales/crowdin/pt-BR.yml @@ -299,6 +299,12 @@ pt-BR: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: Atualmente, não há tipos disponíveis. form: @@ -1609,6 +1615,12 @@ pt-BR: pdf_gantt: "Gantt em PDF" image: omitted: "Imagem não exportada." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/pt-PT.yml b/config/locales/crowdin/pt-PT.yml index d5e93a5d898c..0efbaeeee1de 100644 --- a/config/locales/crowdin/pt-PT.yml +++ b/config/locales/crowdin/pt-PT.yml @@ -298,6 +298,12 @@ pt-PT: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: Atualmente, não existem tipos disponíveis. form: @@ -1608,6 +1614,12 @@ pt-PT: pdf_gantt: "PDF Gantt" image: omitted: "Imagem não exportada." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/ro.yml b/config/locales/crowdin/ro.yml index 11a7bc6d561d..7d14d0d6dcf2 100644 --- a/config/locales/crowdin/ro.yml +++ b/config/locales/crowdin/ro.yml @@ -300,6 +300,12 @@ ro: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: În acest moment nu există tipuri disponibile. form: @@ -1643,6 +1649,12 @@ ro: pdf_gantt: "PDF Gantt" image: omitted: "Imaginea nu a fost exportată." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/ru.yml b/config/locales/crowdin/ru.yml index f7544cc11d87..a47c7380a783 100644 --- a/config/locales/crowdin/ru.yml +++ b/config/locales/crowdin/ru.yml @@ -299,6 +299,12 @@ ru: is_required_blank_slate: heading: Требуется во всех проектах description: Этот атрибут проекта активирован во всех проектах, поскольку установлен флажок «Требуется во всех проектах». Его нельзя отключить для отдельных проектов. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: На данный момент доступных типов нет. form: @@ -1675,6 +1681,12 @@ ru: pdf_gantt: "Диаграмма Гантта в PDF" image: omitted: "Изображение не экспортировано." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: ч days: д @@ -3007,7 +3019,7 @@ ru: setting_date_format: "Дата" setting_days_per_month: "Количество дней в месяце" setting_days_per_month_explanation: >- - This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + Это определяет, что считается "месяцем" при более естественном отображении продолжительности (например, если месяц 20 дней, то 60 дней будет 3 месяца). setting_default_language: "Язык по умолчанию" setting_default_projects_modules: "По умолчанию доступные в новых проектах модули" setting_default_projects_public: "По умолчанию новые проекты видимы всем" @@ -3025,7 +3037,7 @@ ru: setting_host_name: "Имя компьютера в сети" setting_hours_per_day: "Количество часов в день" setting_hours_per_day_explanation: >- - Это определяет, что считается «днем» при более естественном отображении продолжительности (например, если день 8 часов, то 32 часа будет 4 дня). + Это определяет, что считается "днем" при более естественном отображении продолжительности (например, если день 8 часов, то 32 часа будет 4 дня). setting_days_per_week: "Количество дней в неделю" setting_days_per_week_explanation: >- Это определяет, что считается "неделей" при более естественном отображении продолжительности (например, если в неделю 5 дней, то 15 дней будет 3 недели). diff --git a/config/locales/crowdin/rw.yml b/config/locales/crowdin/rw.yml index 7866289d0f30..0b0fe0718418 100644 --- a/config/locales/crowdin/rw.yml +++ b/config/locales/crowdin/rw.yml @@ -300,6 +300,12 @@ rw: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: There are currently no types available. form: @@ -1610,6 +1616,12 @@ rw: pdf_gantt: "PDF Gantt" image: omitted: "Image not exported." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/si.yml b/config/locales/crowdin/si.yml index 272c8d93b0e8..171a4a3a8b3b 100644 --- a/config/locales/crowdin/si.yml +++ b/config/locales/crowdin/si.yml @@ -300,6 +300,12 @@ si: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: දැනට වර්ග නොමැත. form: @@ -1610,6 +1616,12 @@ si: pdf_gantt: "PDF Gantt" image: omitted: "රූපය අපනයනය කර නැත." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/sk.yml b/config/locales/crowdin/sk.yml index 818349ba0959..cbc306c99bd1 100644 --- a/config/locales/crowdin/sk.yml +++ b/config/locales/crowdin/sk.yml @@ -300,6 +300,12 @@ sk: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: Momentálne nie sú k dispozícii žiadne typy. form: @@ -1676,6 +1682,12 @@ sk: pdf_gantt: "PDF Gantt" image: omitted: "Image not exported." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/sl.yml b/config/locales/crowdin/sl.yml index 7cf6b7383d28..11630979b0c7 100644 --- a/config/locales/crowdin/sl.yml +++ b/config/locales/crowdin/sl.yml @@ -299,6 +299,12 @@ sl: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: Trenutno ni na voljo nobenih vrst. form: @@ -1673,6 +1679,12 @@ sl: pdf_gantt: "PDF Gantt" image: omitted: "Slika ni izvožena." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/sr.yml b/config/locales/crowdin/sr.yml index ae81c2b7a9b2..8630a3e6567b 100644 --- a/config/locales/crowdin/sr.yml +++ b/config/locales/crowdin/sr.yml @@ -300,6 +300,12 @@ sr: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: There are currently no types available. form: @@ -1643,6 +1649,12 @@ sr: pdf_gantt: "PDF Gantt" image: omitted: "Image not exported." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/sv.yml b/config/locales/crowdin/sv.yml index 640df9856c36..357930892064 100644 --- a/config/locales/crowdin/sv.yml +++ b/config/locales/crowdin/sv.yml @@ -300,6 +300,12 @@ sv: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: Det finns för närvarande inga typer tillgängliga. form: @@ -1609,6 +1615,12 @@ sv: pdf_gantt: "PDF Gantt" image: omitted: "Image not exported." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/th.yml b/config/locales/crowdin/th.yml index 6ce8bc99536f..ed492f465c9a 100644 --- a/config/locales/crowdin/th.yml +++ b/config/locales/crowdin/th.yml @@ -300,6 +300,12 @@ th: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: There are currently no types available. form: @@ -1577,6 +1583,12 @@ th: pdf_gantt: "PDF Gantt" image: omitted: "Image not exported." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/tr.yml b/config/locales/crowdin/tr.yml index 796c03fe7fb8..f84e684d5afa 100644 --- a/config/locales/crowdin/tr.yml +++ b/config/locales/crowdin/tr.yml @@ -300,6 +300,12 @@ tr: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: Şu anda hiçbir tip mevcut değil. form: @@ -1609,6 +1615,12 @@ tr: pdf_gantt: "PDF Gantt" image: omitted: "Görüntü dışa aktarılmadı." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/uk.yml b/config/locales/crowdin/uk.yml index a2b6f250b8d8..cbd580431a6b 100644 --- a/config/locales/crowdin/uk.yml +++ b/config/locales/crowdin/uk.yml @@ -295,6 +295,12 @@ uk: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: Наразі немає доступних типів. form: @@ -1671,6 +1677,12 @@ uk: pdf_gantt: "Діаграма Ґанта (PDF)" image: omitted: "Зображення не експортовано." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: г days: д diff --git a/config/locales/crowdin/uz.yml b/config/locales/crowdin/uz.yml index 34818eeee254..6d8f0a386eaa 100644 --- a/config/locales/crowdin/uz.yml +++ b/config/locales/crowdin/uz.yml @@ -300,6 +300,12 @@ uz: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: There are currently no types available. form: @@ -1610,6 +1616,12 @@ uz: pdf_gantt: "PDF Gantt" image: omitted: "Image not exported." + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/vi.yml b/config/locales/crowdin/vi.yml index 64c3f56e1352..564d0b0fa406 100644 --- a/config/locales/crowdin/vi.yml +++ b/config/locales/crowdin/vi.yml @@ -302,6 +302,12 @@ vi: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: Không có phân loại. form: @@ -1579,6 +1585,12 @@ vi: pdf_gantt: "PDF Gantt" image: omitted: "Hình ảnh không được xuất" + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: h days: d diff --git a/config/locales/crowdin/zh-CN.yml b/config/locales/crowdin/zh-CN.yml index 1a722a4df817..8c5a95a36f1c 100644 --- a/config/locales/crowdin/zh-CN.yml +++ b/config/locales/crowdin/zh-CN.yml @@ -297,6 +297,12 @@ zh-CN: is_required_blank_slate: heading: 所有项目中需要 description: 此项目属性已在所有项目中激活,因为选中了“所有项目中需要”的选项。它在单个项目中不能被停用。 + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: 目前有可用的类型。 form: @@ -440,7 +446,8 @@ zh-CN:
    :继承值(例如,来自子级或关系的值)仍然适用。 status_excluded_from_totals_text: |- - 选中此选项可将具有此状态的工作包在层级结构中从“总工时”,“剩余工作”,以及“完成百分比”中排除。 + 选中此选项可将具有此状态的工作包排除在层次结构中的 "工时"、" + 剩余工时 "和 "完成百分比 "总数之外。 status_color_text: | 单击可以分配或更改此状态的颜色。 颜色显示在状态按钮中,可用于突出显示表中的工作包。 @@ -1572,6 +1579,12 @@ zh-CN: pdf_gantt: "PDF 甘特图" image: omitted: "图像未导出。" + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: 时 days: 天 @@ -2895,7 +2908,7 @@ zh-CN: setting_date_format: "日期" setting_days_per_month: "每月天数" setting_days_per_month_explanation: >- - This will define what is considered a "month" when displaying duration in a more natural way (for example, if a month is 20 days, 60 days would be 3 months. + 这将以更自然的方式在显示持续时间时定义什么是 "一个月"(例如,如果一个月是20天,60天就是3个月)。 setting_default_language: "默认语言" setting_default_projects_modules: "新项目的默认启用模块" setting_default_projects_public: "新项目默认公开" @@ -2911,7 +2924,7 @@ zh-CN: setting_feeds_limit: "Feed 内容限制" setting_file_max_size_displayed: "内联显示的文本文件的最大大小" setting_host_name: "主机名" - setting_hours_per_day: "每日小时数" + setting_hours_per_day: "每天小时数" setting_hours_per_day_explanation: >- 这将以更自然的方式在显示持续时间时定义什么是 "一天"(例如,如果一天是8小时,32小时就是4天)。 setting_days_per_week: "每周天数" diff --git a/config/locales/crowdin/zh-TW.yml b/config/locales/crowdin/zh-TW.yml index 0735b7fac8ef..8017d73682db 100644 --- a/config/locales/crowdin/zh-TW.yml +++ b/config/locales/crowdin/zh-TW.yml @@ -299,6 +299,12 @@ zh-TW: is_required_blank_slate: heading: Required in all projects description: This project attribute is activated in all projects since the "Required in all projects" option is checked. It cannot be deactivated for individual projects. + new_project_mapping_form: + add_projects: Add projects + include_sub_projects: Include sub-projects + project_mapping_filter: + label: Search project + placeholder: Filter by text types: no_results_title_text: 目前沒有可用的類型 form: @@ -1576,6 +1582,12 @@ zh-TW: pdf_gantt: "PDF Gantt" image: omitted: "影像沒有匯出。" + macro: + error: "Macro error, %{message}" + attribute_not_found: "attribute not found: %{attribute}" + model_not_found: "invalid attribute model: %{model}" + resource_not_found: "resource not found: %{resource}" + rich_text_unsupported: "Rich text embedding currently not supported in export" units: hours: 小時 days: 日 diff --git a/modules/bim/config/locales/crowdin/id.seeders.yml b/modules/bim/config/locales/crowdin/id.seeders.yml index 8c3340ee9f67..d454cd8579e0 100644 --- a/modules/bim/config/locales/crowdin/id.seeders.yml +++ b/modules/bim/config/locales/crowdin/id.seeders.yml @@ -13,7 +13,7 @@ id: item_2: name: High item_3: - name: Critical + name: Kritik statuses: item_0: name: Baru @@ -42,7 +42,7 @@ id: item_4: name: Remark item_5: - name: Request + name: Permintaan item_6: name: Clash global_queries: @@ -694,7 +694,7 @@ id: item_5: name: Tahapan pencapaian item_6: - name: Tasks + name: Tugas item_7: name: Rencana tim boards: @@ -704,7 +704,7 @@ id: widgets: item_0: options: - name: Welcome + name: Selamat datang item_1: options: name: Getting started diff --git a/modules/bim/config/locales/crowdin/id.yml b/modules/bim/config/locales/crowdin/id.yml index b09848242bdc..77bc93dfeabe 100644 --- a/modules/bim/config/locales/crowdin/id.yml +++ b/modules/bim/config/locales/crowdin/id.yml @@ -107,30 +107,30 @@ id: uuid_already_taken: "Tidak dapat mengimpor masalah BCF ini karena sudah ada masalah lain dengan GUID yang sama. Mungkinkah masalah BCF ini sudah diimpor ke proyek lain?" ifc_models: label_ifc_models: 'Model IFC' - label_new_ifc_model: 'New IFC model' - label_show_defaults: 'Show defaults' - label_default_ifc_models: 'Default IFC models' - label_edit_defaults: 'Edit defaults' + label_new_ifc_model: 'Model IFC baru' + label_show_defaults: 'Tampilkan bawaan' + label_default_ifc_models: 'Model bawaan IFC' + label_edit_defaults: 'Edit pengaturan bawaan' no_defaults_warning: - title: 'No IFC model was set as default for this project.' - check_1: 'Check that you have uploaded at least one IFC model.' + title: 'Tidak ada model IFC yang ditetapkan sebagai bawaan dalam projek ini.' + check_1: 'Pastikan anda telah mengunggah setidaknya satu model IFC.' check_2: 'Check that at least one IFC model is set to "Default".' - no_results: "No IFC models have been uploaded in this project." + no_results: "Tidak ada model IFC yang diunggah dalam proyek ini." conversion_status: - label: 'Processing?' - pending: 'Pending' - processing: 'Processing' - completed: 'Completed' + label: 'Memproses?' + pending: 'Menunggu' + processing: 'Memproses' + completed: 'Selesai' error: 'Eror' processing_notice: - processing_default: 'The following default IFC models are still being processed and are thus not available, yet:' + processing_default: 'Model IFC bawaan berikut ini masih diproses dan belum tersedia sekarang:' flash_messages: - upload_successful: 'Upload succeeded. It will now get processed and will be ready to use in a couple of minutes.' + upload_successful: 'Pengunggahan sukses. File akan diproses dan akan siap digunakan dalam beberapa menit.' conversion: - missing_commands: "The following IFC converter commands are missing on this system: %{names}" + missing_commands: "Perintah IFC converter berikut ini tidak ditemukan dalam perangkat ini: %{names}\n" project_module_ifc_models: "Model IFC" - permission_view_ifc_models: "View IFC models" - permission_manage_ifc_models: "Import and manage IFC models" + permission_view_ifc_models: "Lihat model IFC" + permission_manage_ifc_models: "Import dan sesuaikan model IFC" extraction: available: ifc_convert: "IFC conversion pipeline available" diff --git a/modules/github_integration/config/locales/crowdin/af.yml b/modules/github_integration/config/locales/crowdin/af.yml index bf078ba5074f..a50b60d7fd63 100644 --- a/modules/github_integration/config/locales/crowdin/af.yml +++ b/modules/github_integration/config/locales/crowdin/af.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ af: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Show GitHub content" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/ar.yml b/modules/github_integration/config/locales/crowdin/ar.yml index b2cf04719abd..898406d566ac 100644 --- a/modules/github_integration/config/locales/crowdin/ar.yml +++ b/modules/github_integration/config/locales/crowdin/ar.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ ar: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "عرض محتوى GitHub" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/az.yml b/modules/github_integration/config/locales/crowdin/az.yml index 39d4f01f4312..14c738320d54 100644 --- a/modules/github_integration/config/locales/crowdin/az.yml +++ b/modules/github_integration/config/locales/crowdin/az.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ az: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Show GitHub content" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/be.yml b/modules/github_integration/config/locales/crowdin/be.yml index ecca59cddb7d..0ed3f730b28f 100644 --- a/modules/github_integration/config/locales/crowdin/be.yml +++ b/modules/github_integration/config/locales/crowdin/be.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ be: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Show GitHub content" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/bg.yml b/modules/github_integration/config/locales/crowdin/bg.yml index 2951ef2ed5c1..ef87dda6866b 100644 --- a/modules/github_integration/config/locales/crowdin/bg.yml +++ b/modules/github_integration/config/locales/crowdin/bg.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ bg: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Show GitHub content" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/ca.yml b/modules/github_integration/config/locales/crowdin/ca.yml index 281de70a9e8c..f9295b89a765 100644 --- a/modules/github_integration/config/locales/crowdin/ca.yml +++ b/modules/github_integration/config/locales/crowdin/ca.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ ca: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Mostra el contingut de GitHub" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/ckb-IR.yml b/modules/github_integration/config/locales/crowdin/ckb-IR.yml index a196a2b20966..e49f8f07b4c1 100644 --- a/modules/github_integration/config/locales/crowdin/ckb-IR.yml +++ b/modules/github_integration/config/locales/crowdin/ckb-IR.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ ckb-IR: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Show GitHub content" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/cs.yml b/modules/github_integration/config/locales/crowdin/cs.yml index 29da6e2a4b86..2701b1a04370 100644 --- a/modules/github_integration/config/locales/crowdin/cs.yml +++ b/modules/github_integration/config/locales/crowdin/cs.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ cs: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub integrace" description: "Integruje OpenProject a GitHub pro lepší workflow" project_module_github: "GitHub" permission_show_github_content: "Zobrazit GitHub obsah" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/da.yml b/modules/github_integration/config/locales/crowdin/da.yml index 63535f8c8bff..eb951a74bf1d 100644 --- a/modules/github_integration/config/locales/crowdin/da.yml +++ b/modules/github_integration/config/locales/crowdin/da.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ da: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Vis GitHub indhold" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/de.yml b/modules/github_integration/config/locales/crowdin/de.yml index 90e23bd57458..27c5349f54fc 100644 --- a/modules/github_integration/config/locales/crowdin/de.yml +++ b/modules/github_integration/config/locales/crowdin/de.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ de: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub-Integration" description: "Integriert OpenProject und GitHub für einen besseren Arbeitsablauf" project_module_github: "GitHub" permission_show_github_content: "Zeige weiteren Inhalt" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/el.yml b/modules/github_integration/config/locales/crowdin/el.yml index d0ff03cb836e..5dbd8258fc84 100644 --- a/modules/github_integration/config/locales/crowdin/el.yml +++ b/modules/github_integration/config/locales/crowdin/el.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ el: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Εμφάνιση περιεχομένου GitHub" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/eo.yml b/modules/github_integration/config/locales/crowdin/eo.yml index 2a3c878fcb6e..30283f1c7ffb 100644 --- a/modules/github_integration/config/locales/crowdin/eo.yml +++ b/modules/github_integration/config/locales/crowdin/eo.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ eo: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Show GitHub content" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/es.yml b/modules/github_integration/config/locales/crowdin/es.yml index 054612a72417..7e0cf3cbeba5 100644 --- a/modules/github_integration/config/locales/crowdin/es.yml +++ b/modules/github_integration/config/locales/crowdin/es.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ es: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "Integración de OpenProject y GitHub" description: "Integra OpenProject y GitHub para un mejor flujo de trabajo" project_module_github: "GitHub" permission_show_github_content: "Mostrar contenido de GitHub" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/et.yml b/modules/github_integration/config/locales/crowdin/et.yml index 2f044d80b514..07a614243bce 100644 --- a/modules/github_integration/config/locales/crowdin/et.yml +++ b/modules/github_integration/config/locales/crowdin/et.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ et: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Show GitHub content" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/eu.yml b/modules/github_integration/config/locales/crowdin/eu.yml index a6fc297c2037..2d925faa3b64 100644 --- a/modules/github_integration/config/locales/crowdin/eu.yml +++ b/modules/github_integration/config/locales/crowdin/eu.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ eu: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Show GitHub content" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/fa.yml b/modules/github_integration/config/locales/crowdin/fa.yml index 23756ff7fe35..4bfebe337745 100644 --- a/modules/github_integration/config/locales/crowdin/fa.yml +++ b/modules/github_integration/config/locales/crowdin/fa.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ fa: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Show GitHub content" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/fi.yml b/modules/github_integration/config/locales/crowdin/fi.yml index 45427fba8763..d8b69535e9f2 100644 --- a/modules/github_integration/config/locales/crowdin/fi.yml +++ b/modules/github_integration/config/locales/crowdin/fi.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ fi: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Show GitHub content" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/fil.yml b/modules/github_integration/config/locales/crowdin/fil.yml index 53862d954cbe..d2460144746d 100644 --- a/modules/github_integration/config/locales/crowdin/fil.yml +++ b/modules/github_integration/config/locales/crowdin/fil.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ fil: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Show GitHub content" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/fr.yml b/modules/github_integration/config/locales/crowdin/fr.yml index e7756809697a..b8391722e13f 100644 --- a/modules/github_integration/config/locales/crowdin/fr.yml +++ b/modules/github_integration/config/locales/crowdin/fr.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ fr: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "Intégration de GitHub et OpenProject" description: "Permet une intégration étroite entre OpenProject et GitHub pour un meilleur flux de travail" project_module_github: "GitHub" permission_show_github_content: "Afficher le contenu GitHub" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/he.yml b/modules/github_integration/config/locales/crowdin/he.yml index b2dc75766e5f..57965b9f3a7f 100644 --- a/modules/github_integration/config/locales/crowdin/he.yml +++ b/modules/github_integration/config/locales/crowdin/he.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ he: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Show GitHub content" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/hi.yml b/modules/github_integration/config/locales/crowdin/hi.yml index c2c206940e38..9a54ed36ce3d 100644 --- a/modules/github_integration/config/locales/crowdin/hi.yml +++ b/modules/github_integration/config/locales/crowdin/hi.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ hi: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Show GitHub content" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/hr.yml b/modules/github_integration/config/locales/crowdin/hr.yml index 34ec7803ff4a..9fb9e050f445 100644 --- a/modules/github_integration/config/locales/crowdin/hr.yml +++ b/modules/github_integration/config/locales/crowdin/hr.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ hr: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Show GitHub content" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/hu.yml b/modules/github_integration/config/locales/crowdin/hu.yml index e25a58801b7b..95f163b045af 100644 --- a/modules/github_integration/config/locales/crowdin/hu.yml +++ b/modules/github_integration/config/locales/crowdin/hu.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ hu: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "GitHub tartalom mutatása" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/id.yml b/modules/github_integration/config/locales/crowdin/id.yml index f7e8c79d0ac2..3c2130025b73 100644 --- a/modules/github_integration/config/locales/crowdin/id.yml +++ b/modules/github_integration/config/locales/crowdin/id.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ id: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Tampilkan konten GitHub" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/it.yml b/modules/github_integration/config/locales/crowdin/it.yml index d2b0ecda8dec..e1dcd0ff21ef 100644 --- a/modules/github_integration/config/locales/crowdin/it.yml +++ b/modules/github_integration/config/locales/crowdin/it.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ it: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "Integrazione OpenProject GitHub" description: "Integra OpenProject e GitHub per un migliore flusso di lavoro" project_module_github: "GitHub" permission_show_github_content: "Mostra il contenuto di GitHub" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/ja.yml b/modules/github_integration/config/locales/crowdin/ja.yml index ba104b1a6e78..26401ac03dcc 100644 --- a/modules/github_integration/config/locales/crowdin/ja.yml +++ b/modules/github_integration/config/locales/crowdin/ja.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ ja: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "GitHub コンテンツを表示する" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/ka.yml b/modules/github_integration/config/locales/crowdin/ka.yml index 853ae6c0e2e7..e82e553a0c95 100644 --- a/modules/github_integration/config/locales/crowdin/ka.yml +++ b/modules/github_integration/config/locales/crowdin/ka.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ ka: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Show GitHub content" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/kk.yml b/modules/github_integration/config/locales/crowdin/kk.yml index e0826ee9b562..1709043c43ed 100644 --- a/modules/github_integration/config/locales/crowdin/kk.yml +++ b/modules/github_integration/config/locales/crowdin/kk.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ kk: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Show GitHub content" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/ko.yml b/modules/github_integration/config/locales/crowdin/ko.yml index 2bad6ba92add..1ff41a30cb75 100644 --- a/modules/github_integration/config/locales/crowdin/ko.yml +++ b/modules/github_integration/config/locales/crowdin/ko.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ ko: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub 통합" description: "개선된 워크플로를 위해 OpenProject와 GitHub를 통합합니다" project_module_github: "GitHub" permission_show_github_content: "GitHub 콘텐츠 표시" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/lt.yml b/modules/github_integration/config/locales/crowdin/lt.yml index 712dcedd15d5..d785406d8b54 100644 --- a/modules/github_integration/config/locales/crowdin/lt.yml +++ b/modules/github_integration/config/locales/crowdin/lt.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ lt: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub integracija" description: "Integruoja OpenProject ir GitHub geresniems procesams" project_module_github: "GitHub" permission_show_github_content: "Parodyti GitHub turinį" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/lv.yml b/modules/github_integration/config/locales/crowdin/lv.yml index 2dce3eb5dae2..285956e3e20a 100644 --- a/modules/github_integration/config/locales/crowdin/lv.yml +++ b/modules/github_integration/config/locales/crowdin/lv.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ lv: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Show GitHub content" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/mn.yml b/modules/github_integration/config/locales/crowdin/mn.yml index 6750905a8175..499560dd9975 100644 --- a/modules/github_integration/config/locales/crowdin/mn.yml +++ b/modules/github_integration/config/locales/crowdin/mn.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ mn: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Show GitHub content" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/ms.yml b/modules/github_integration/config/locales/crowdin/ms.yml index 4d24deee6a10..5194c5899f6a 100644 --- a/modules/github_integration/config/locales/crowdin/ms.yml +++ b/modules/github_integration/config/locales/crowdin/ms.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ ms: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "Integrasi GitHub OpenProject" description: "Mengintegrasikan OpenProject dan GitHub untuk aliran kerja yang lebih baik" project_module_github: "GitHub" permission_show_github_content: "Paparkan kandungan GitHub" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/ne.yml b/modules/github_integration/config/locales/crowdin/ne.yml index 8933e430608a..703c0bb0a1e8 100644 --- a/modules/github_integration/config/locales/crowdin/ne.yml +++ b/modules/github_integration/config/locales/crowdin/ne.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ ne: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Show GitHub content" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/nl.yml b/modules/github_integration/config/locales/crowdin/nl.yml index 7f46d226eed6..ee4ec41dd907 100644 --- a/modules/github_integration/config/locales/crowdin/nl.yml +++ b/modules/github_integration/config/locales/crowdin/nl.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ nl: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Toon GitHub inhoud" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/no.yml b/modules/github_integration/config/locales/crowdin/no.yml index ee9779d1b1df..f24b4677792a 100644 --- a/modules/github_integration/config/locales/crowdin/no.yml +++ b/modules/github_integration/config/locales/crowdin/no.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ "no": + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub integrasjon" description: "Integrerer OpenProject og GitHub for en bedre arbeidsflyt" project_module_github: "GitHub" permission_show_github_content: "Vis GitHub innhold" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/pl.yml b/modules/github_integration/config/locales/crowdin/pl.yml index 366ff3450d18..ebd3fe849c7d 100644 --- a/modules/github_integration/config/locales/crowdin/pl.yml +++ b/modules/github_integration/config/locales/crowdin/pl.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ pl: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "Integracja OpenProject z GitHub" description: "Integruje OpenProject i GitHub dla lepszego przepływu pracy" project_module_github: "GitHub" permission_show_github_content: "Pokaż treść GitHub" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/pt-BR.yml b/modules/github_integration/config/locales/crowdin/pt-BR.yml index a623297c3791..6537addd962d 100644 --- a/modules/github_integration/config/locales/crowdin/pt-BR.yml +++ b/modules/github_integration/config/locales/crowdin/pt-BR.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ pt-BR: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "Integração do OpenProject GitHub" description: "Integra o OpenProject e o GitHub para um melhor fluxo de trabalho" project_module_github: "GitHub" permission_show_github_content: "Exibir conteúdo GitHub" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/pt-PT.yml b/modules/github_integration/config/locales/crowdin/pt-PT.yml index 319a17c6e6a0..f2c6faa6be1d 100644 --- a/modules/github_integration/config/locales/crowdin/pt-PT.yml +++ b/modules/github_integration/config/locales/crowdin/pt-PT.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ pt-PT: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "Integração do OpenProject GitHub" description: "Integra o OpenProject e o GitHub para um melhor fluxo de trabalho" project_module_github: "GitHub" permission_show_github_content: "Mostrar conteúdo GitHub" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/ro.yml b/modules/github_integration/config/locales/crowdin/ro.yml index 322fb50887f2..f60b02ab23c0 100644 --- a/modules/github_integration/config/locales/crowdin/ro.yml +++ b/modules/github_integration/config/locales/crowdin/ro.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ ro: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Afișați conținutul GitHub" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/ru.yml b/modules/github_integration/config/locales/crowdin/ru.yml index 222a47827d9c..003a9741bdfd 100644 --- a/modules/github_integration/config/locales/crowdin/ru.yml +++ b/modules/github_integration/config/locales/crowdin/ru.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ ru: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "Интеграция с OpenProject GitHub" description: "Интегрирует OpenProject и GitHub для лучшего рабочего процесса" project_module_github: "GitHub" permission_show_github_content: "Показать контент GitHub" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/rw.yml b/modules/github_integration/config/locales/crowdin/rw.yml index a42bca3db70d..8a5009d3e822 100644 --- a/modules/github_integration/config/locales/crowdin/rw.yml +++ b/modules/github_integration/config/locales/crowdin/rw.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ rw: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Show GitHub content" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/si.yml b/modules/github_integration/config/locales/crowdin/si.yml index f06ef5264ae2..5dd3bd30f9e5 100644 --- a/modules/github_integration/config/locales/crowdin/si.yml +++ b/modules/github_integration/config/locales/crowdin/si.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ si: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Show GitHub content" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/sk.yml b/modules/github_integration/config/locales/crowdin/sk.yml index 833ddae134c3..5ad998b0ac80 100644 --- a/modules/github_integration/config/locales/crowdin/sk.yml +++ b/modules/github_integration/config/locales/crowdin/sk.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ sk: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Show GitHub content" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/sl.yml b/modules/github_integration/config/locales/crowdin/sl.yml index 483112f142f5..dc3bd69181cb 100644 --- a/modules/github_integration/config/locales/crowdin/sl.yml +++ b/modules/github_integration/config/locales/crowdin/sl.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ sl: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Pokaži GitHub vsebino" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/sr.yml b/modules/github_integration/config/locales/crowdin/sr.yml index 3cf9eed05324..d6ba7ce2ebb3 100644 --- a/modules/github_integration/config/locales/crowdin/sr.yml +++ b/modules/github_integration/config/locales/crowdin/sr.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ sr: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Show GitHub content" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/sv.yml b/modules/github_integration/config/locales/crowdin/sv.yml index 95999c5cf523..ba84910b2e73 100644 --- a/modules/github_integration/config/locales/crowdin/sv.yml +++ b/modules/github_integration/config/locales/crowdin/sv.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ sv: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Show GitHub content" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/th.yml b/modules/github_integration/config/locales/crowdin/th.yml index fb54c5c421b4..3cd44effbc8a 100644 --- a/modules/github_integration/config/locales/crowdin/th.yml +++ b/modules/github_integration/config/locales/crowdin/th.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ th: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "แสดงเนื้อหา GitHub " + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/tr.yml b/modules/github_integration/config/locales/crowdin/tr.yml index 55573af1443c..b07857734afb 100644 --- a/modules/github_integration/config/locales/crowdin/tr.yml +++ b/modules/github_integration/config/locales/crowdin/tr.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ tr: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Entegrasyonu" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Github içeriğini göster" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/uk.yml b/modules/github_integration/config/locales/crowdin/uk.yml index 75c9840641e9..c7524bb03581 100644 --- a/modules/github_integration/config/locales/crowdin/uk.yml +++ b/modules/github_integration/config/locales/crowdin/uk.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ uk: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "Інтеграція OpenProject GitHub" description: "Інтегрує OpenProject і GitHub для покращення робочого процесу" project_module_github: "GitHub" permission_show_github_content: "Показати контент GitHub" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/uz.yml b/modules/github_integration/config/locales/crowdin/uz.yml index a56b43bc7f59..afc55646cf9e 100644 --- a/modules/github_integration/config/locales/crowdin/uz.yml +++ b/modules/github_integration/config/locales/crowdin/uz.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ uz: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Show GitHub content" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/vi.yml b/modules/github_integration/config/locales/crowdin/vi.yml index 0127650d8340..9e14e2e70dab 100644 --- a/modules/github_integration/config/locales/crowdin/vi.yml +++ b/modules/github_integration/config/locales/crowdin/vi.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ vi: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub Integration" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "Hiển thị nội dung GitHub" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/zh-CN.yml b/modules/github_integration/config/locales/crowdin/zh-CN.yml index a37088622f53..80299b66e3e1 100644 --- a/modules/github_integration/config/locales/crowdin/zh-CN.yml +++ b/modules/github_integration/config/locales/crowdin/zh-CN.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ zh-CN: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub 集成" description: "将 OpenProject 和 GitHub 进行集成,以实现更好的工作流程。" project_module_github: "GitHub" permission_show_github_content: "显示 GitHub 内容" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/github_integration/config/locales/crowdin/zh-TW.yml b/modules/github_integration/config/locales/crowdin/zh-TW.yml index 15c4247585b6..138bb92750de 100644 --- a/modules/github_integration/config/locales/crowdin/zh-TW.yml +++ b/modules/github_integration/config/locales/crowdin/zh-TW.yml @@ -20,8 +20,20 @@ #See COPYRIGHT and LICENSE files for more details. #++ zh-TW: + button_add_deploy_target: Add deploy target + label_deploy_target: Deploy target + label_deploy_target_new: New deploy target + label_deploy_target_plural: Deploy targets + label_github_integration: GitHub Integration + notice_deploy_target_created: Deploy target created + notice_deploy_target_destroyed: Deploy target deleted plugin_openproject_github_integration: name: "OpenProject GitHub 整合" description: "Integrates OpenProject and GitHub for a better workflow" project_module_github: "GitHub" permission_show_github_content: "顯示 GitHub 內容" + permission_introspection: Read running OpenProject core version and build SHA + text_deploy_target_type_info: > + So far we only support OpenProject itself. + text_deploy_target_api_key_info: > + An OpenProject [API key](docs_url) belonging to a user who has the global introspection permission. diff --git a/modules/grids/config/locales/crowdin/js-ru.yml b/modules/grids/config/locales/crowdin/js-ru.yml index 909eae575f99..15bd64c296e3 100644 --- a/modules/grids/config/locales/crowdin/js-ru.yml +++ b/modules/grids/config/locales/crowdin/js-ru.yml @@ -32,13 +32,13 @@ ru: no_results: 'Для проектов не определены настраиваемые поля.' project_status: title: 'Статус проекта' - not_started: 'Не начато' + not_started: 'Не начат' on_track: 'По плану' off_track: 'Приостановлен' at_risk: 'Под угрозой' not_set: 'Не задано' - finished: 'Завершено' - discontinued: 'Прекращено' + finished: 'Завершен' + discontinued: 'Прекращен' subprojects: title: 'Подпроекты' no_results: 'Подпроектов нет.' diff --git a/modules/meeting/config/locales/crowdin/ru.yml b/modules/meeting/config/locales/crowdin/ru.yml index 7daf66122b3f..ff24f27e5724 100644 --- a/modules/meeting/config/locales/crowdin/ru.yml +++ b/modules/meeting/config/locales/crowdin/ru.yml @@ -60,7 +60,7 @@ ru: meeting_agenda_item: "Пункт повестки" meeting_agenda: "Повестка дня" meeting_minutes: "Протокол(-ы)" - meeting_section: "Section" + meeting_section: "Раздел" activity: filter: meeting: "Совещания" diff --git a/modules/meeting/config/locales/crowdin/zh-CN.yml b/modules/meeting/config/locales/crowdin/zh-CN.yml index 358f5f80bffa..378a137df41d 100644 --- a/modules/meeting/config/locales/crowdin/zh-CN.yml +++ b/modules/meeting/config/locales/crowdin/zh-CN.yml @@ -57,7 +57,7 @@ zh-CN: meeting_agenda_item: "议程项目" meeting_agenda: "议程" meeting_minutes: "会议记录" - meeting_section: "Section" + meeting_section: "节" activity: filter: meeting: "会议" From cc8addffc220975454480befd28ed8a7d2f03912 Mon Sep 17 00:00:00 2001 From: OpenProject Actions CI Date: Thu, 6 Jun 2024 03:11:04 +0000 Subject: [PATCH 176/176] update locales from crowdin [ci skip] --- config/locales/crowdin/js-ms.yml | 30 ++++++++--------- config/locales/crowdin/ms.yml | 30 ++++++++--------- .../bim/config/locales/crowdin/id.seeders.yml | 8 ++--- modules/bim/config/locales/crowdin/id.yml | 32 +++++++++---------- .../grids/config/locales/crowdin/js-ru.yml | 6 ++-- 5 files changed, 53 insertions(+), 53 deletions(-) diff --git a/config/locales/crowdin/js-ms.yml b/config/locales/crowdin/js-ms.yml index 0f5be795c643..b3f7d3c3d7fa 100644 --- a/config/locales/crowdin/js-ms.yml +++ b/config/locales/crowdin/js-ms.yml @@ -22,7 +22,7 @@ ms: js: ajax: - hide: "Sorokkan" + hide: "Sembunyikan" loading: "Memuatkan..." updating: "Mengemas kini..." attachments: @@ -146,7 +146,7 @@ ms: manual: "Tukar ke sumber Markdown" wysiwyg: "Tukar ke editor WYSIWYG" macro: - error: "Tidak dapat kembangkan macro: %{message}" + error: "Tidak dapat kembangkan makro: %{message}" attribute_reference: macro_help_tooltip: "Bahagian teks ini sedang dihasilkan secara dinamik oleh makro." not_found: "Sumber yang diminta tidak dapat ditemui" @@ -168,7 +168,7 @@ ms: macros: "Makro-makro" chose_macro: "Pilih makro" toc: "Jadual kandungan" - toolbar_help: "Klik untuk memilih widget dan tunjuk toolbar. Klik dua kali untuk edit widget" + toolbar_help: "Klik untuk memilih widget dan paparkan toolbar. Klik dua kali untuk edit widget" wiki_page_include: button: "Sertakan kandungan halaman wiki lain" text: "[Placeholder] Termasuk halaman wiki" @@ -205,7 +205,7 @@ ms: trial: confirmation: "Pengesahan alamat e-mel " confirmation_info: > - Kami telah menghantar satu e-mel kepada anda pada %{date} kepada %{email}. Sila semak peti masuk anda dan klik pautan pengesahan yang disediakan untuk memulakan percubaan 14 hari anda. + Kami telah menghantar e-mel kepada anda pada %{date} di %{email}. Sila semak peti masuk anda dan klik pautan pengesahan yang disediakan untuk memulakan percubaan 14 hari anda. form: general_consent: > Saya bersetuju dengan syarat-syarat perkhidmatan dan polisi privasi. @@ -247,7 +247,7 @@ ms: premium_features: "Tambahan Enterprise" premium_features_text: "Board Agile, tema tersuai dan logo, graf, aliran kerja yang cerdas dengan tindakan tersuai, carian teks penuh untuk lampiran pakej kerja dan pelbagai pilihan ruang tersuai." professional_support: "Sokongan profesional" - professional_support_text: "Dapatkan sokongan yang boleh dipercayai, sentuhan tinggi daripada jurutera sokongan kanan dengan pengetahuan pakar tentang menjalankan OpenProject dalam persekitaran perniagaan yang kritikal." + professional_support_text: "Dapatkan sokongan yang boleh dipercayai, sokongan peribadi yang berkualiti tinggi daripada jurutera sokongan berpengalaman dengan pengetahuan pakar tentang menjalankan OpenProject dalam persekitaran perniagaan yang kritikal." button_start_trial: "Mulakan percubaan percuma" button_upgrade: "Naik taraf sekarang" button_contact_us: "Hubungi kami untuk demo" @@ -267,7 +267,7 @@ ms: new_date: "(baharu)" add_non_working_day: "Hari tidak bekerja" already_added_error: "Hari tidak bekerja untuk tarikh ini sudah ada. Hanya boleh mempunyai satu hari tidak bekerja dicipta untuk setiap tarikh yang unik." - change_button: "Simpan dan jadual semula" + change_button: "Simpan dan jadualkan semula" change_title: "Tukar hari bekerja" removed_title: "Anda akan mengeluarkan hari berikut dari senarai hari tidak bekerja:" change_description: "Mengubah hari dalam seminggu yang dianggap hari bekerja atau hari tidak bekerja akan mempengaruhi hari mula dan selesai semua pakej kerja dalam semua projek dalam kejadian ini." @@ -365,9 +365,9 @@ ms: new_features_html: > Keluaran tersebut mengandungi pelbagai fitur baharu dan penambahbaikan:
    • eksport PDF paparan Gantt, cth. untuk mencetak (tambahan Enterprise)
    • Projek kegemaran
    • Bahagian dalam Mesyuarat
    • Paparkan mesyuarat di Halaman Saya dan halaman gambaran keseluruhan projek
    • Kemungkinan untuk sorokkan lampiran dalam tab Fail
    • Ruang tersuai jenis Pautan (URL)
    ical_sharing_modal: - title: "Langgan ke kalendar" + title: "Langgan kalendar" inital_setup_error_message: "Ralat berlaku ketika sedang mengambil data." - description: "Anda boleh menggunakan URL (iCalendar) untuk melanggan ke kalendar ini dalam pelanggan luaran dan lihat maklumat pakej kerja terkini dari situ." + description: "Anda boleh menggunakan URL (iCalendar) untuk melanggan kalendar ini dalam pelanggan luaran dan lihat maklumat pakej kerja terkini dari situ." warning: "Sila jangan kongsi URL ini dengan pengguna lain. Sesiapa sahaja yang mempunyai pautan ini akan boleh melihat butiran pakej kerja tanpa akaun atau kata laluan." token_name_label: "Dimanakah anda akan menggunakan ini?" token_name_placeholder: 'Taip nama, cth. "Telefon"' @@ -451,7 +451,7 @@ ms: label_invalid: "Tidak sah" label_import: "Import" label_latest_activity: "Aktiviti terkini" - label_last_updated_on: "Dikemas kini terakhir pada" + label_last_updated_on: "Kemas kini terakhir pada" label_learn_more_link: "Ketahui lebih lanjut" label_less_or_equal: "<=" label_less_than_ago: "kurang dari beberapa hari yang lalu" @@ -562,8 +562,8 @@ ms: label_rejected_files: "Fail-fail tersebut tidak dapat dimuat naik:" label_rejected_files_reason: "Fail-fail tersebut tidak boleh dimuat naik kerana saiz mereka adalah lebih besar daripada %{maximumFilesize}" label_wait: "Sila tunggu untuk konfigurasi..." - label_upload_counter: "%{done} dari %{count} fail selesai" - label_validation_error: "Pakej kerja tidak dapat disimpan kerana ralat berikut:" + label_upload_counter: "%{done} daripada %{count} fail selesai" + label_validation_error: "Pakej kerja tidak dapat disimpan disebabkan ralat berikut:" label_version_plural: "Versi-versi" label_view_has_changed: "Paparan ini mempunyai perubahan yang tidak disimpan. Klik untuk simpan mereka." help_texts: @@ -574,12 +574,12 @@ ms: next: "Seterusnya" got_it: "Faham" steps: - help_menu: "Menu Bantuan (?) menyediakan sumber bantuan tambahan. Di sini anda akan menjumpai panduan pengguna, video panduan membantu dan lebih lagi.
    Nikmati kerja anda di OpenProject!" - members: "Jemput ahli baru untuk sertai projek anda." - quick_add_button: "Klik pada ikon tambah (+) dalam navigasi pengepala untuk cipta projek baru atau untuk jemput rakan sekerja." + help_menu: "Menu Bantuan (?) menyediakan sumber bantuan tambahan. Di sini anda akan menjumpai panduan pengguna, video panduan dan lebih lagi.
    Nikmati kerja anda di OpenProject!" + members: "Jemput ahli baharu untuk sertai projek anda." + quick_add_button: "Klik ikon tambah (+) dalam navigasi pengepala untuk cipta projek baharu atau untuk jemput rakan sekerja." sidebar_arrow: "Guna anak panah kembali di sudut kiri atas untuk kembali ke menu utama projek." welcome: "Ambil lawatan pengenalan 3 minit untuk belajar fitur-fitur penting dengan banyak.
    Kami sarankan melengkapi langkah-langkah tersebut sehingga ke akhirnya. Anda boleh mula semula lawatan bila-bila masa." - wiki: "Dalam wiki anda boleh mendokumentasikan dan kongsi pengetahuan bersama dengan pasukan anda." + wiki: "Dalam wiki anda boleh mendokumentasikan dan kongsi pengetahuan bersama pasukan anda." backlogs: overview: "Kendalikan kerja anda dalam paparan tunggakan." sprints: "Di kanan anda mempunyai tunggakan produk dan tunggakan bug, di kiri anda mempunyai pecutan yang berkenaan. Di sini anda boleh mencipta epik, cerita pengguna, dan bug, utamakan dengan menarik & melepaskan dan tambah mereka ke pecutan." diff --git a/config/locales/crowdin/ms.yml b/config/locales/crowdin/ms.yml index f27ee892a5a3..7c7b7850c74e 100644 --- a/config/locales/crowdin/ms.yml +++ b/config/locales/crowdin/ms.yml @@ -3381,7 +3381,7 @@ ms: missing_content_type: "tidak ditentukan" missing_property: "Ciri-ciri yang hilang '%{property}'." missing_request_body: "Tiada badan permintaan." - missing_or_malformed_parameter: "Parameter pertanyaan '%{parameter}' tidak ditemui atau cacat." + missing_or_malformed_parameter: "Parameter pertanyaan '%{parameter}' tidak ditemui atau tidak betul." multipart_body_error: "Badan permintaan tidak mempunyai bahagian multipart seperti yang dijangka." multiple_errors: "Beberapa kekangan ruang telah dilanggar." unable_to_create_attachment: "Lampiran tidak boleh dicipta" @@ -3405,31 +3405,31 @@ ms: doorkeeper: pre_authorization: status: "Pra-kebenaran" - auth_url: "Auth URL" + auth_url: "URL Auth" access_token_url: "Akses token URL" errors: messages: #Common error messages invalid_request: - unknown: "Permintaan tersebut tidak mengandungi parameter yang diperlukan, termasuk nilai parameter yang tidak disokong, atau sebaliknya telah cacat." + unknown: "Permintaan tersebut tidak mengandungi parameter yang diperlukan, termasuk nilai parameter yang tidak disokong, atau sebaliknya tidak betul." missing_param: "Parameter yang diperlukan hilang: %{value}." request_not_authorized: "Permintaan perlu dibenarkan. Parameter yang diperlukan untuk membenarkan permintaan tiada atau tidak sah." invalid_redirect_uri: "Pengubah hala URI yang diminta tidak betul atau tidak sepadan dengan pengubah hala URI pelanggan." unauthorized_client: "Pelanggan tersebut tidak dibenarkan untuk melaksanakan permintaan ini menggunakan kaedah ini." access_denied: "Pemilik sumber atau server kebenaran menafikan permintaan ini." - invalid_scope: "Skop yang diminta adalah tidak sah, tidak diketahui, atau salah bentuk." + invalid_scope: "Skop yang diminta adalah tidak sah, tidak diketahui, atau tidak betul." invalid_code_challenge_method: "Kaedah kod cabaran mesti biasa atau S256." server_error: "Server kebenaran mengalami keadaan yang tidak dijangka yang menghalangnya daripada memenuhi permintaan." temporarily_unavailable: "Server kebenaran pada masa ini tidak dapat mengendalikan permintaan kerana beban berlebihan sementara atau penyelenggaraan server." #Configuration error messages credential_flow_not_configured: "Aliran Kelayakan Kata Laluan Pemilik Sumber telah gagal disebabkan oleh Doorkeeper.configure.resource_owner_authenticator tidak dikonfigurasikan." resource_owner_authenticator_not_configured: "Carian Pemilik Sumber gagal kerana Doorkeeper.configure.resource_owner_authenticator tidak dikonfigurasikan." - admin_authenticator_not_configured: "Akses ke panel admin dilarang kerana Doorkeeper.configure.admin_authenticator tidak dikonfigurasi." + admin_authenticator_not_configured: "Akses ke panel pentadbir dilarang kerana Doorkeeper.configure.admin_authenticator tidak dikonfigurasi." #Access grant errors unsupported_response_type: "Server kebenaran tidak menyokong jenis tindak balas ini." unsupported_response_mode: "Server kebenaran tidak menyokong mod tindak balas ini." #Access token errors - invalid_client: "Pengesahan pelanggan gagal kerana pelanggan yang tidak diketahui, tiada pengesahan pelanggan yang disertakan, atau kaedah pengesahan yang tidak disokong." + invalid_client: "Pengesahan pelanggan gagal kerana pelanggan yang tidak diketahui, tiada pengesahan pelanggan yang disertakan, atau kaedah pengesahan tidak disokong." invalid_grant: "Pemberian kebenaran yang diberikan adalah tidak sah, luput, dibatalkan, tidak sepadan dengan pengubah hala URI yang digunakan dalam permintaan kebenaran, atau dikeluarkan kepada pelanggan lain." unsupported_grant_type: "Jenis pemberian kebenaran tidak disokong oleh server pengesahan." invalid_token: @@ -3455,9 +3455,9 @@ ms: instructions: name: "Nama aplikasi anda. Ini akan dipaparkan ke pengguna lain selepas kebenaran." redirect_uri_html: > - URL yang dibenarkan membenarkan pengguna boleh diubah hala. Satu entri setiap baris.
    Jika anda mendaftar aplikasi desktop, guna URL berikut. - confidential: "Semak jika aplikasi akan digunakan dimana rahsia pelanggan boleh dikekalkan sulit. Mobile apps asal dan Single Page Apps dianggap sebagai tidak sulit." - scopes: "Tandakan skop yang anda mahu aplikasi untuk berikan akses. Jika tiada skop ditandakan, api_v3 akan diandaikan." + URL yang dibenarkan membenarkan pengguna boleh diubah hala. Satu entri setiap baris.
    Jika anda mendaftar aplikasi desktop, gunakan URL berikut. + confidential: "Semak jika aplikasi akan digunakan dimana rahsia pelanggan boleh dikekalkan sulit. Aplikasi mudah alih asal dan Single Page Apps dianggap sebagai tidak sulit." + scopes: "Tandakan skop yang anda mahu untuk berikan akses ke aplikasi tersebut. Jika tiada skop ditandakan, api_v3 akan diandaikan." client_credential_user_id: "ID pengguna pilihan untuk menyamar apabila pelanggan menggunakan aplikasi ini. Tinggalkan kosong untuk benarkan akses awam sahaja." register_intro: "Jika anda sedang membangunkan aplikasi pelanggan API OAuth untuk OpenProject, anda boleh mendaftarkannya menggunakan borang ini untuk semua pengguna menggunakannya." default_scopes: "" @@ -3490,7 +3490,7 @@ ms: client_credentials_impersonation_html: > Secara default, OpenProject menyediakan kebenaran OAuth 2.0 melalui %{authorization_code_flow_link}. Anda boleh memilih untuk mengaktifkan %{client_credentials_flow_link}, tetapi anda mesti menyediakan pengguna yang akan mewakili permintaan. authorization_error: "Sebuah ralat kebenaran telah berlaku." - revoke_my_application_confirmation: "Adakah anda benar-benar mahu keluarkan aplikasi ini? Ini akan menarik balik %{token_count} aktif darinya." + revoke_my_application_confirmation: "Adakah anda benar-benar mahu memadam aplikasi ini? Ini akan menarik balik %{token_count} yang aktif darinya." my_registered_applications: "Aplikasi OAuth berdaftar" oauth_client: urn_connection_status: @@ -3500,11 +3500,11 @@ ms: labels: label_oauth_integration: "Integrasi OAuth2" label_redirect_uri: "Ubah hala URI" - label_request_token: "Permintaan token" + label_request_token: "Token permintaan" label_refresh_token: "Token muat semula" errors: oauth_authorization_code_grant_had_errors: "Pemberian pengesahan OAuth2 tidak berjaya" - oauth_reported: "Pembekal OAuth2 melaporkan" + oauth_reported: "Penyedia OAuth2 melaporkan" oauth_returned_error: "OAuth2 telah kembalikan sebuah ralat" oauth_returned_json_error: "OAuth2 telah kembalikan ralat JSON" oauth_returned_http_error: "OAuth2 telah kembalikan ralat rangkaian" @@ -3516,13 +3516,13 @@ ms: Ralat dalaman: Memanggil refresh_token tanpa token yang sedia ada sebelum ini. refresh_token_updated_failed: "Ralat semasa kemas kini OAuthClientToken" oauth_client_not_found_explanation: > - Ralat muncul selepas anda mengemas kini client_id dan client_secret di Openproject, tetapi belum mengemas kini ruangan 'URI Kembali' dalam pembekal OAuth2. + Ralat muncul selepas anda mengemas kini client_id dan client_secret di Openproject, tetapi belum mengemas kini ruangan 'URI Kembali' dalam penyedia OAuth2. oauth_code_not_present: "'Kod' OAuth2 tidak ditemui dalam titik terakhir 'panggilan balik' (redirect_url)." oauth_code_not_present_explanation: > Ralat ini muncul jika anda telah memilih response_type yang salah dalam pembekal OAuth2. Response_type perlu 'kod' atau serupa. oauth_state_not_present: "'Kondisi' OAuth2 tidak ditemui dalam titik terakhir 'panggilan balik' (ubah hala_url)." oauth_state_not_present_explanation: > - 'Kondisi' digunakan untuk menunjukkan ke OpenProject tempat untuk meneruskan selepas kebenaran OAuth2 berjaya. Ketiadaan 'Kondisi' adalah ralat dalaman yang mungkin muncul semasa penyediaan. Sila hubungi pentadbir sistem anda. + 'Kondisi' digunakan untuk menunjukkan ke OpenProject tempat untuk meneruskan selepas kebenaran OAuth2 berjaya. Ketiadaan 'kondisi' adalah ralat dalaman yang mungkin muncul semasa penyediaan. Sila hubungi pentadbir sistem anda. rack_oauth2: client_secret_invalid: "Rahsia pelanggan adalah tidak sah (rahsia_pelanggan_tidak sah)" invalid_request: > @@ -3536,7 +3536,7 @@ ms: http: request: failed_authorization: "Permintaan dari pihak server gagal mengesahkan dirinya sendiri." - missing_authorization: "Permintaan dari pihak server gagal disebabkan maklumat pengesahan yang hilang." + missing_authorization: "Permintaan dari pihak server gagal disebabkan maklumat pengesahan yang hilang." response: unexpected: "Tindak balas yang tidak dijangka diterima." you: anda diff --git a/modules/bim/config/locales/crowdin/id.seeders.yml b/modules/bim/config/locales/crowdin/id.seeders.yml index 8c3340ee9f67..d454cd8579e0 100644 --- a/modules/bim/config/locales/crowdin/id.seeders.yml +++ b/modules/bim/config/locales/crowdin/id.seeders.yml @@ -13,7 +13,7 @@ id: item_2: name: High item_3: - name: Critical + name: Kritik statuses: item_0: name: Baru @@ -42,7 +42,7 @@ id: item_4: name: Remark item_5: - name: Request + name: Permintaan item_6: name: Clash global_queries: @@ -694,7 +694,7 @@ id: item_5: name: Tahapan pencapaian item_6: - name: Tasks + name: Tugas item_7: name: Rencana tim boards: @@ -704,7 +704,7 @@ id: widgets: item_0: options: - name: Welcome + name: Selamat datang item_1: options: name: Getting started diff --git a/modules/bim/config/locales/crowdin/id.yml b/modules/bim/config/locales/crowdin/id.yml index b09848242bdc..77bc93dfeabe 100644 --- a/modules/bim/config/locales/crowdin/id.yml +++ b/modules/bim/config/locales/crowdin/id.yml @@ -107,30 +107,30 @@ id: uuid_already_taken: "Tidak dapat mengimpor masalah BCF ini karena sudah ada masalah lain dengan GUID yang sama. Mungkinkah masalah BCF ini sudah diimpor ke proyek lain?" ifc_models: label_ifc_models: 'Model IFC' - label_new_ifc_model: 'New IFC model' - label_show_defaults: 'Show defaults' - label_default_ifc_models: 'Default IFC models' - label_edit_defaults: 'Edit defaults' + label_new_ifc_model: 'Model IFC baru' + label_show_defaults: 'Tampilkan bawaan' + label_default_ifc_models: 'Model bawaan IFC' + label_edit_defaults: 'Edit pengaturan bawaan' no_defaults_warning: - title: 'No IFC model was set as default for this project.' - check_1: 'Check that you have uploaded at least one IFC model.' + title: 'Tidak ada model IFC yang ditetapkan sebagai bawaan dalam projek ini.' + check_1: 'Pastikan anda telah mengunggah setidaknya satu model IFC.' check_2: 'Check that at least one IFC model is set to "Default".' - no_results: "No IFC models have been uploaded in this project." + no_results: "Tidak ada model IFC yang diunggah dalam proyek ini." conversion_status: - label: 'Processing?' - pending: 'Pending' - processing: 'Processing' - completed: 'Completed' + label: 'Memproses?' + pending: 'Menunggu' + processing: 'Memproses' + completed: 'Selesai' error: 'Eror' processing_notice: - processing_default: 'The following default IFC models are still being processed and are thus not available, yet:' + processing_default: 'Model IFC bawaan berikut ini masih diproses dan belum tersedia sekarang:' flash_messages: - upload_successful: 'Upload succeeded. It will now get processed and will be ready to use in a couple of minutes.' + upload_successful: 'Pengunggahan sukses. File akan diproses dan akan siap digunakan dalam beberapa menit.' conversion: - missing_commands: "The following IFC converter commands are missing on this system: %{names}" + missing_commands: "Perintah IFC converter berikut ini tidak ditemukan dalam perangkat ini: %{names}\n" project_module_ifc_models: "Model IFC" - permission_view_ifc_models: "View IFC models" - permission_manage_ifc_models: "Import and manage IFC models" + permission_view_ifc_models: "Lihat model IFC" + permission_manage_ifc_models: "Import dan sesuaikan model IFC" extraction: available: ifc_convert: "IFC conversion pipeline available" diff --git a/modules/grids/config/locales/crowdin/js-ru.yml b/modules/grids/config/locales/crowdin/js-ru.yml index 909eae575f99..15bd64c296e3 100644 --- a/modules/grids/config/locales/crowdin/js-ru.yml +++ b/modules/grids/config/locales/crowdin/js-ru.yml @@ -32,13 +32,13 @@ ru: no_results: 'Для проектов не определены настраиваемые поля.' project_status: title: 'Статус проекта' - not_started: 'Не начато' + not_started: 'Не начат' on_track: 'По плану' off_track: 'Приостановлен' at_risk: 'Под угрозой' not_set: 'Не задано' - finished: 'Завершено' - discontinued: 'Прекращено' + finished: 'Завершен' + discontinued: 'Прекращен' subprojects: title: 'Подпроекты' no_results: 'Подпроектов нет.'