graphql 2.4.13 → 2.5.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graphql/analysis/query_complexity.rb +87 -7
  3. data/lib/graphql/backtrace/table.rb +37 -14
  4. data/lib/graphql/current.rb +1 -1
  5. data/lib/graphql/dashboard/detailed_traces.rb +47 -0
  6. data/lib/graphql/dashboard/installable.rb +22 -0
  7. data/lib/graphql/dashboard/limiters.rb +93 -0
  8. data/lib/graphql/dashboard/operation_store.rb +199 -0
  9. data/lib/graphql/dashboard/statics/charts.min.css +1 -0
  10. data/lib/graphql/dashboard/statics/dashboard.css +27 -0
  11. data/lib/graphql/dashboard/statics/dashboard.js +74 -9
  12. data/lib/graphql/dashboard/subscriptions.rb +96 -0
  13. data/lib/graphql/dashboard/views/graphql/dashboard/detailed_traces/traces/index.html.erb +45 -0
  14. data/lib/graphql/dashboard/views/graphql/dashboard/limiters/limiters/show.html.erb +62 -0
  15. data/lib/graphql/dashboard/views/graphql/dashboard/not_installed.html.erb +18 -0
  16. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/_form.html.erb +23 -0
  17. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/edit.html.erb +21 -0
  18. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/index.html.erb +69 -0
  19. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/new.html.erb +7 -0
  20. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/index_entries/index.html.erb +39 -0
  21. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/index_entries/show.html.erb +32 -0
  22. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/operations/index.html.erb +81 -0
  23. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/operations/show.html.erb +71 -0
  24. data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/subscriptions/show.html.erb +41 -0
  25. data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/topics/index.html.erb +55 -0
  26. data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/topics/show.html.erb +40 -0
  27. data/lib/graphql/dashboard/views/layouts/graphql/dashboard/application.html.erb +49 -1
  28. data/lib/graphql/dashboard.rb +45 -29
  29. data/lib/graphql/dataloader/active_record_association_source.rb +28 -8
  30. data/lib/graphql/dataloader/active_record_source.rb +26 -5
  31. data/lib/graphql/dataloader/null_dataloader.rb +7 -0
  32. data/lib/graphql/dataloader/source.rb +16 -4
  33. data/lib/graphql/dig.rb +2 -1
  34. data/lib/graphql/execution/interpreter/resolve.rb +3 -3
  35. data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +34 -1
  36. data/lib/graphql/execution/interpreter/runtime.rb +163 -59
  37. data/lib/graphql/execution/interpreter.rb +5 -13
  38. data/lib/graphql/execution/multiplex.rb +6 -1
  39. data/lib/graphql/invalid_null_error.rb +15 -2
  40. data/lib/graphql/language/lexer.rb +9 -2
  41. data/lib/graphql/language/nodes.rb +5 -1
  42. data/lib/graphql/language/parser.rb +14 -6
  43. data/lib/graphql/query/context.rb +3 -8
  44. data/lib/graphql/query/partial.rb +179 -0
  45. data/lib/graphql/query.rb +59 -55
  46. data/lib/graphql/schema/addition.rb +3 -1
  47. data/lib/graphql/schema/always_visible.rb +1 -0
  48. data/lib/graphql/schema/argument.rb +9 -3
  49. data/lib/graphql/schema/build_from_definition.rb +96 -47
  50. data/lib/graphql/schema/directive/flagged.rb +2 -0
  51. data/lib/graphql/schema/directive.rb +33 -1
  52. data/lib/graphql/schema/field.rb +23 -1
  53. data/lib/graphql/schema/input_object.rb +38 -30
  54. data/lib/graphql/schema/list.rb +1 -1
  55. data/lib/graphql/schema/member/has_arguments.rb +2 -2
  56. data/lib/graphql/schema/member/has_dataloader.rb +4 -2
  57. data/lib/graphql/schema/member/has_deprecation_reason.rb +15 -0
  58. data/lib/graphql/schema/member/has_interfaces.rb +2 -2
  59. data/lib/graphql/schema/member/type_system_helpers.rb +16 -2
  60. data/lib/graphql/schema/ractor_shareable.rb +79 -0
  61. data/lib/graphql/schema/resolver.rb +1 -0
  62. data/lib/graphql/schema/scalar.rb +1 -6
  63. data/lib/graphql/schema/timeout.rb +19 -2
  64. data/lib/graphql/schema/validator/required_validator.rb +15 -6
  65. data/lib/graphql/schema/visibility/migration.rb +2 -2
  66. data/lib/graphql/schema/visibility/profile.rb +107 -21
  67. data/lib/graphql/schema/visibility.rb +41 -29
  68. data/lib/graphql/schema/warden.rb +13 -5
  69. data/lib/graphql/schema.rb +228 -32
  70. data/lib/graphql/static_validation/all_rules.rb +2 -2
  71. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +47 -13
  72. data/lib/graphql/static_validation/rules/fields_will_merge.rb +78 -16
  73. data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +10 -2
  74. data/lib/graphql/static_validation/rules/not_single_subscription_error.rb +25 -0
  75. data/lib/graphql/static_validation/rules/subscription_root_exists_and_single_subscription_selection.rb +26 -0
  76. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +6 -2
  77. data/lib/graphql/testing/helpers.rb +5 -2
  78. data/lib/graphql/tracing/active_support_notifications_trace.rb +7 -0
  79. data/lib/graphql/tracing/appoptics_tracing.rb +5 -0
  80. data/lib/graphql/tracing/appsignal_trace.rb +26 -61
  81. data/lib/graphql/tracing/data_dog_trace.rb +41 -164
  82. data/lib/graphql/tracing/monitor_trace.rb +283 -0
  83. data/lib/graphql/tracing/new_relic_trace.rb +34 -164
  84. data/lib/graphql/tracing/notifications_trace.rb +183 -37
  85. data/lib/graphql/tracing/null_trace.rb +1 -1
  86. data/lib/graphql/tracing/perfetto_trace.rb +16 -19
  87. data/lib/graphql/tracing/prometheus_trace.rb +47 -74
  88. data/lib/graphql/tracing/scout_trace.rb +25 -59
  89. data/lib/graphql/tracing/sentry_trace.rb +56 -99
  90. data/lib/graphql/tracing/statsd_trace.rb +24 -47
  91. data/lib/graphql/tracing/trace.rb +0 -17
  92. data/lib/graphql/tracing.rb +1 -0
  93. data/lib/graphql/type_kinds.rb +1 -0
  94. data/lib/graphql/version.rb +1 -1
  95. data/lib/graphql.rb +1 -1
  96. metadata +35 -26
  97. data/lib/graphql/dashboard/views/graphql/dashboard/traces/index.html.erb +0 -63
  98. data/lib/graphql/static_validation/rules/subscription_root_exists.rb +0 -17
@@ -0,0 +1 @@
1
+ @property --color-1{syntax:"<color>";initial-value:transparent;inherits:true}@property --color-2{syntax:"<color>";initial-value:transparent;inherits:true}@property --color-3{syntax:"<color>";initial-value:transparent;inherits:true}@property --color-4{syntax:"<color>";initial-value:transparent;inherits:true}@property --color-5{syntax:"<color>";initial-value:transparent;inherits:true}@property --color-6{syntax:"<color>";initial-value:transparent;inherits:true}@property --color-7{syntax:"<color>";initial-value:transparent;inherits:true}@property --color-8{syntax:"<color>";initial-value:transparent;inherits:true}@property --color-9{syntax:"<color>";initial-value:transparent;inherits:true}@property --color-10{syntax:"<color>";initial-value:transparent;inherits:true}@property --color{syntax:"<color>";inherits:true}@property --chart-bg-color{syntax:"<color>";inherits:true}@property --aspect-ratio{syntax:"<ratio>";initial-value:auto;inherits:true}@property --labels-size{syntax:"<length>";initial-value:0;inherits:true}@property --labels-align-block{syntax:"<string>";inherits:true}@property --labels-align-inline{syntax:"<string>";inherits:true}@property --primary-axis-width{syntax:"<length>";initial-value:1px;inherits:true}@property --secondary-axes-width{syntax:"<length>";initial-value:1px;inherits:true}@property --data-axes-width{syntax:"<length>";initial-value:1px;inherits:true}@property --legend-border-width{syntax:"<length>";initial-value:1px;inherits:true}@property --primary-axis-style{syntax:"<line-style>";initial-value:solid;inherits:true}@property --secondary-axes-style{syntax:"<line-style>";initial-value:solid;inherits:true}@property --data-axes-style{syntax:"<line-style>";initial-value:solid;inherits:true}@property --legend-border-style{syntax:"<line-style>";initial-value:solid;inherits:true}@property --primary-axis-color{syntax:"<color>";initial-value:transparent;inherits:true}@property --secondary-axes-color{syntax:"<color>";initial-value:transparent;inherits:true}@property --data-axes-color{syntax:"<color>";initial-value:transparent;inherits:true}@property --legend-border-color{syntax:"<color>";initial-value:transparent;inherits:true}@property --start{syntax:"<number>";inherits:true}@property --end{syntax:"<number>";inherits:true}@property --size{syntax:"<number>";inherits:true}@property --line-size{syntax:"<number>";inherits:true}.charts-css{--color-1:rgba(240,50,50,.75);--color-2:rgba(255,180,50,.75);--color-3:rgba(255,220,90,.75);--color-4:rgba(100,210,80,.75);--color-5:rgba(90,165,255,.75);--color-6:rgba(170,90,240,.75);--color-7:hsla(0,0%,71%,.75);--color-8:hsla(0,0%,43%,.75);--color-9:hsla(40,26%,55%,.75);--color-10:rgba(130,50,20,.75);--chart-bg-color:#f5f5f5;--primary-axis-color:#000;--primary-axis-style:solid;--primary-axis-width:1px;--secondary-axes-color:rgba(0,0,0,.15);--secondary-axes-style:solid;--secondary-axes-width:1px;--data-axes-color:rgba(0,0,0,.15);--data-axes-style:solid;--data-axes-width:1px;--legend-border-color:#c8c8c8;--legend-border-style:solid;--legend-border-width:1px;border:0;display:block;height:100%;margin:0 auto;padding:0;position:relative;-webkit-print-color-adjust:exact;print-color-adjust:exact;width:100%}.charts-css,.charts-css *,.charts-css ::after,.charts-css ::before,.charts-css::after,.charts-css::before{-webkit-box-sizing:border-box;box-sizing:border-box}table.charts-css{background-color:transparent;border-collapse:collapse;border-spacing:0;empty-cells:show;overflow:initial}table.charts-css caption,table.charts-css colgroup,table.charts-css tbody,table.charts-css td,table.charts-css th,table.charts-css thead,table.charts-css tr{background-color:transparent;border:0;display:block;margin:0;padding:0}.charts-css.area.show-labels th.hide-label,.charts-css.area.show-labels tr.hide-label th,.charts-css.area:not(.show-labels) tbody tr th,.charts-css.bar.show-labels th.hide-label,.charts-css.bar.show-labels tr.hide-label th,.charts-css.bar:not(.show-labels) tbody tr th,.charts-css.column.show-labels th.hide-label,.charts-css.column.show-labels tr.hide-label th,.charts-css.column:not(.show-labels) tbody tr th,.charts-css.hide-data .data,.charts-css.hide-data .data:not(:focus):not(:focus-within),.charts-css.line.show-labels th.hide-label,.charts-css.line.show-labels tr.hide-label th,.charts-css.line:not(.show-labels) tbody tr th,.charts-css.pie tbody tr th,.charts-css.polar tbody tr,.charts-css.radar tbody tr,.charts-css.radial tbody tr,.charts-css:not(.show-heading) caption,table.charts-css colgroup,table.charts-css tfoot,table.charts-css thead{clip:rect(0,0,0,0);border:0;-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;white-space:nowrap;width:1px}table.charts-css tbody{position:relative}ol.charts-css,ul.charts-css{list-style-type:none}ol.charts-css li,ul.charts-css li{border:0;margin:0;padding:0}.charts-css.show-heading caption{display:block;width:100%}.charts-css.area tbody tr td:nth-of-type(10n+1)::before,.charts-css.bar tbody tr:nth-of-type(10n+1) td,.charts-css.bar.multiple tbody tr td:nth-of-type(10n+1),.charts-css.column tbody tr:nth-of-type(10n+1) td,.charts-css.column.multiple tbody tr td:nth-of-type(10n+1),.charts-css.line tbody tr td:nth-of-type(10n+1)::before{background:var(--color,var(--color-1))}.charts-css.pie tbody tr:nth-of-type(10n+1) td,.charts-css.pie.multiple tbody tr td:nth-of-type(10n+1){--c:var(--color,var(--color-1,transparent))}.charts-css.area tbody tr td:nth-of-type(10n+2)::before,.charts-css.bar tbody tr:nth-of-type(10n+2) td,.charts-css.bar.multiple tbody tr td:nth-of-type(10n+2),.charts-css.column tbody tr:nth-of-type(10n+2) td,.charts-css.column.multiple tbody tr td:nth-of-type(10n+2),.charts-css.line tbody tr td:nth-of-type(10n+2)::before{background:var(--color,var(--color-2))}.charts-css.pie tbody tr:nth-of-type(10n+2) td,.charts-css.pie.multiple tbody tr td:nth-of-type(10n+2){--c:var(--color,var(--color-2,transparent))}.charts-css.area tbody tr td:nth-of-type(10n+3)::before,.charts-css.bar tbody tr:nth-of-type(10n+3) td,.charts-css.bar.multiple tbody tr td:nth-of-type(10n+3),.charts-css.column tbody tr:nth-of-type(10n+3) td,.charts-css.column.multiple tbody tr td:nth-of-type(10n+3),.charts-css.line tbody tr td:nth-of-type(10n+3)::before{background:var(--color,var(--color-3))}.charts-css.pie tbody tr:nth-of-type(10n+3) td,.charts-css.pie.multiple tbody tr td:nth-of-type(10n+3){--c:var(--color,var(--color-3,transparent))}.charts-css.area tbody tr td:nth-of-type(10n+4)::before,.charts-css.bar tbody tr:nth-of-type(10n+4) td,.charts-css.bar.multiple tbody tr td:nth-of-type(10n+4),.charts-css.column tbody tr:nth-of-type(10n+4) td,.charts-css.column.multiple tbody tr td:nth-of-type(10n+4),.charts-css.line tbody tr td:nth-of-type(10n+4)::before{background:var(--color,var(--color-4))}.charts-css.pie tbody tr:nth-of-type(10n+4) td,.charts-css.pie.multiple tbody tr td:nth-of-type(10n+4){--c:var(--color,var(--color-4,transparent))}.charts-css.area tbody tr td:nth-of-type(10n+5)::before,.charts-css.bar tbody tr:nth-of-type(10n+5) td,.charts-css.bar.multiple tbody tr td:nth-of-type(10n+5),.charts-css.column tbody tr:nth-of-type(10n+5) td,.charts-css.column.multiple tbody tr td:nth-of-type(10n+5),.charts-css.line tbody tr td:nth-of-type(10n+5)::before{background:var(--color,var(--color-5))}.charts-css.pie tbody tr:nth-of-type(10n+5) td,.charts-css.pie.multiple tbody tr td:nth-of-type(10n+5){--c:var(--color,var(--color-5,transparent))}.charts-css.area tbody tr td:nth-of-type(10n+6)::before,.charts-css.bar tbody tr:nth-of-type(10n+6) td,.charts-css.bar.multiple tbody tr td:nth-of-type(10n+6),.charts-css.column tbody tr:nth-of-type(10n+6) td,.charts-css.column.multiple tbody tr td:nth-of-type(10n+6),.charts-css.line tbody tr td:nth-of-type(10n+6)::before{background:var(--color,var(--color-6))}.charts-css.pie tbody tr:nth-of-type(10n+6) td,.charts-css.pie.multiple tbody tr td:nth-of-type(10n+6){--c:var(--color,var(--color-6,transparent))}.charts-css.area tbody tr td:nth-of-type(10n+7)::before,.charts-css.bar tbody tr:nth-of-type(10n+7) td,.charts-css.bar.multiple tbody tr td:nth-of-type(10n+7),.charts-css.column tbody tr:nth-of-type(10n+7) td,.charts-css.column.multiple tbody tr td:nth-of-type(10n+7),.charts-css.line tbody tr td:nth-of-type(10n+7)::before{background:var(--color,var(--color-7))}.charts-css.pie tbody tr:nth-of-type(10n+7) td,.charts-css.pie.multiple tbody tr td:nth-of-type(10n+7){--c:var(--color,var(--color-7,transparent))}.charts-css.area tbody tr td:nth-of-type(10n+8)::before,.charts-css.bar tbody tr:nth-of-type(10n+8) td,.charts-css.bar.multiple tbody tr td:nth-of-type(10n+8),.charts-css.column tbody tr:nth-of-type(10n+8) td,.charts-css.column.multiple tbody tr td:nth-of-type(10n+8),.charts-css.line tbody tr td:nth-of-type(10n+8)::before{background:var(--color,var(--color-8))}.charts-css.pie tbody tr:nth-of-type(10n+8) td,.charts-css.pie.multiple tbody tr td:nth-of-type(10n+8){--c:var(--color,var(--color-8,transparent))}.charts-css.area tbody tr td:nth-of-type(10n+9)::before,.charts-css.bar tbody tr:nth-of-type(10n+9) td,.charts-css.bar.multiple tbody tr td:nth-of-type(10n+9),.charts-css.column tbody tr:nth-of-type(10n+9) td,.charts-css.column.multiple tbody tr td:nth-of-type(10n+9),.charts-css.line tbody tr td:nth-of-type(10n+9)::before{background:var(--color,var(--color-9))}.charts-css.pie tbody tr:nth-of-type(10n+9) td,.charts-css.pie.multiple tbody tr td:nth-of-type(10n+9){--c:var(--color,var(--color-9,transparent))}.charts-css.area tbody tr td:nth-of-type(10n+10)::before,.charts-css.bar tbody tr:nth-of-type(10n+10) td,.charts-css.bar.multiple tbody tr td:nth-of-type(10n+10),.charts-css.column tbody tr:nth-of-type(10n+10) td,.charts-css.column.multiple tbody tr td:nth-of-type(10n+10),.charts-css.line tbody tr td:nth-of-type(10n+10)::before{background:var(--color,var(--color-10))}.charts-css.pie tbody tr:nth-of-type(10n+10) td,.charts-css.pie.multiple tbody tr td:nth-of-type(10n+10){--c:var(--color,var(--color-10,transparent))}.charts-css .data{display:-webkit-box;display:-ms-flexbox;display:flex}.charts-css.show-data-on-hover .data{opacity:0;-webkit-transition-duration:.3s;transition-duration:.3s}.charts-css.pie.show-data-on-hover tbody:hover .data,.charts-css.polar.show-data-on-hover tbody:hover .data,.charts-css.radar.show-data-on-hover tbody:hover .data,.charts-css.radial.show-data-on-hover tbody:hover .data,.charts-css.show-data-on-hover tr:hover .data{opacity:1;-webkit-transition-duration:.3s;transition-duration:.3s}.charts-css.bar.data-center tbody tr td,.charts-css.column.data-center tbody tr td{--data-position:center}.charts-css.bar.data-end.reverse tbody tr td,.charts-css.bar.data-outside.reverse tbody tr td,.charts-css.bar.data-start:not(.reverse) tbody tr td,.charts-css.column.data-end:not(.reverse) tbody tr td,.charts-css.column.data-outside:not(.reverse) tbody tr td,.charts-css.column.data-start.reverse tbody tr td{--data-position:flex-start}.charts-css.bar.data-end:not(.reverse) tbody tr td,.charts-css.bar.data-outside:not(.reverse) tbody tr td,.charts-css.bar.data-start.reverse tbody tr td,.charts-css.column.data-end.reverse tbody tr td,.charts-css.column.data-outside.reverse tbody tr td,.charts-css.column.data-start:not(.reverse) tbody tr td{--data-position:flex-end}.charts-css.bar.data-outside:not(.reverse) tbody tr td .data{-webkit-transform:translateX(100%);transform:translateX(100%)}.charts-css.bar.data-outside.reverse tbody tr td .data{-webkit-transform:translateX(-100%);transform:translateX(-100%)}.charts-css.column.data-outside:not(.reverse) tbody tr td .data,.charts-css.column:not(.reverse) tbody tr td .data.outside{-webkit-transform:translateY(-100%);transform:translateY(-100%)}.charts-css.column.data-outside.reverse tbody tr td .data,.charts-css.column.reverse tbody tr td .data.outside{-webkit-transform:translateY(100%);transform:translateY(100%)}.charts-css.area.reverse tbody tr td .data.inside,.charts-css.area.reverse tbody tr td.inside .data,.charts-css.area:not(.reverse) tbody tr td .data.inside,.charts-css.area:not(.reverse) tbody tr td.inside .data,.charts-css.bar.reverse tbody tr td .data.inside,.charts-css.bar.reverse tbody tr td.inside .data,.charts-css.bar:not(.reverse) tbody tr td .data.inside,.charts-css.bar:not(.reverse) tbody tr td.inside .data,.charts-css.column.reverse tbody tr td .data.inside,.charts-css.column.reverse tbody tr td.inside .data,.charts-css.column:not(.reverse) tbody tr td .data.inside,.charts-css.column:not(.reverse) tbody tr td.inside .data,.charts-css.line.reverse tbody tr td .data.inside,.charts-css.line.reverse tbody tr td.inside .data,.charts-css.line:not(.reverse) tbody tr td .data.inside,.charts-css.line:not(.reverse) tbody tr td.inside .data{-webkit-transform:unset;transform:unset}.charts-css.bar{--labels-size:80px}.charts-css.area:not(.show-labels),.charts-css.bar:not(.show-labels),.charts-css.column:not(.show-labels),.charts-css.line:not(.show-labels){--labels-size:0}.charts-css.bar.show-labels tbody tr th{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-box-align:var(--labels-align-block,center);-ms-flex-align:var(--labels-align-block,center);align-items:var(--labels-align-block,center);display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;gap:5px}.charts-css.bar.show-labels.reverse.reverse-labels tbody tr th,.charts-css.bar.show-labels:not(.reverse):not(.reverse-labels) tbody tr th{-webkit-box-pack:var(--labels-align-inline,flex-start);-ms-flex-pack:var(--labels-align-inline,flex-start);justify-content:var(--labels-align-inline,flex-start)}.charts-css.bar.show-labels.reverse:not(.reverse-labels) tbody tr th,.charts-css.bar.show-labels:not(.reverse).reverse-labels tbody tr th{-webkit-box-pack:var(--labels-align-inline,flex-end);-ms-flex-pack:var(--labels-align-inline,flex-end);justify-content:var(--labels-align-inline,flex-end)}.charts-css.area,.charts-css.column,.charts-css.line{--labels-size:1.5rem}.charts-css.area.show-labels tbody tr th,.charts-css.column.show-labels tbody tr th,.charts-css.line.show-labels tbody tr th{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-box-align:var(--labels-align-inline,center);-ms-flex-align:var(--labels-align-inline,center);align-items:var(--labels-align-inline,center);display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.charts-css.area.show-labels.reverse.reverse-labels tbody tr th,.charts-css.area.show-labels:not(.reverse):not(.reverse-labels) tbody tr th,.charts-css.column.show-labels.reverse.reverse-labels tbody tr th,.charts-css.column.show-labels:not(.reverse):not(.reverse-labels) tbody tr th,.charts-css.line.show-labels.reverse.reverse-labels tbody tr th,.charts-css.line.show-labels:not(.reverse):not(.reverse-labels) tbody tr th{-webkit-box-pack:var(--labels-align-block,flex-end);-ms-flex-pack:var(--labels-align-block,flex-end);justify-content:var(--labels-align-block,flex-end)}.charts-css.area.show-labels.reverse:not(.reverse-labels) tbody tr th,.charts-css.area.show-labels:not(.reverse).reverse-labels tbody tr th,.charts-css.column.show-labels.reverse:not(.reverse-labels) tbody tr th,.charts-css.column.show-labels:not(.reverse).reverse-labels tbody tr th,.charts-css.line.show-labels.reverse:not(.reverse-labels) tbody tr th,.charts-css.line.show-labels:not(.reverse).reverse-labels tbody tr th{-webkit-box-pack:var(--labels-align-block,flex-start);-ms-flex-pack:var(--labels-align-block,flex-start);justify-content:var(--labels-align-block,flex-start)}.charts-css.area.labels-align-inline-start tbody tr th,.charts-css.bar.labels-align-inline-start tbody tr th,.charts-css.column.labels-align-inline-start tbody tr th,.charts-css.line.labels-align-inline-start tbody tr th{--labels-align-inline:flex-start}.charts-css.area.labels-align-inline-end tbody tr th,.charts-css.bar.labels-align-inline-end tbody tr th,.charts-css.column.labels-align-inline-end tbody tr th,.charts-css.line.labels-align-inline-end tbody tr th{--labels-align-inline:flex-end}.charts-css.area.labels-align-inline-center tbody tr th,.charts-css.bar.labels-align-inline-center tbody tr th,.charts-css.column.labels-align-inline-center tbody tr th,.charts-css.line.labels-align-inline-center tbody tr th{--labels-align-inline:center}.charts-css.area.labels-align-block-start tbody tr th,.charts-css.bar.labels-align-block-start tbody tr th,.charts-css.column.labels-align-block-start tbody tr th,.charts-css.line.labels-align-block-start tbody tr th{--labels-align-block:flex-start}.charts-css.area.labels-align-block-end tbody tr th,.charts-css.bar.labels-align-block-end tbody tr th,.charts-css.column.labels-align-block-end tbody tr th,.charts-css.line.labels-align-block-end tbody tr th{--labels-align-block:flex-end}.charts-css.area.labels-align-block-center tbody tr th,.charts-css.bar.labels-align-block-center tbody tr th,.charts-css.column.labels-align-block-center tbody tr th,.charts-css.line.labels-align-block-center tbody tr th{--labels-align-block:center}.charts-css.area.show-primary-axis:not(.reverse) tbody tr,.charts-css.column.show-primary-axis:not(.reverse) tbody tr,.charts-css.line.show-primary-axis:not(.reverse) tbody tr{-webkit-border-after:var(--primary-axis-width) var(--primary-axis-style) var(--primary-axis-color);border-block-end:var(--primary-axis-width) var(--primary-axis-style) var(--primary-axis-color)}.charts-css.area.show-primary-axis.reverse tbody tr,.charts-css.column.show-primary-axis.reverse tbody tr,.charts-css.line.show-primary-axis.reverse tbody tr{-webkit-border-before:var(--primary-axis-width) var(--primary-axis-style) var(--primary-axis-color);border-block-start:var(--primary-axis-width) var(--primary-axis-style) var(--primary-axis-color)}.charts-css.area.show-1-secondary-axes:not(.reverse) tbody tr,.charts-css.column.show-1-secondary-axes:not(.reverse) tbody tr,.charts-css.line.show-1-secondary-axes:not(.reverse) tbody tr{background-image:-webkit-gradient(linear,left top,left bottom,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:100% calc(100% / 1)}.charts-css.area.show-1-secondary-axes.reverse tbody tr,.charts-css.column.show-1-secondary-axes.reverse tbody tr,.charts-css.line.show-1-secondary-axes.reverse tbody tr{background-image:-webkit-gradient(linear,left bottom,left top,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(0deg,var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:100% calc(100% / 1)}.charts-css.area.show-2-secondary-axes:not(.reverse) tbody tr,.charts-css.column.show-2-secondary-axes:not(.reverse) tbody tr,.charts-css.line.show-2-secondary-axes:not(.reverse) tbody tr{background-image:-webkit-gradient(linear,left top,left bottom,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:100% calc(100% / 2)}.charts-css.area.show-2-secondary-axes.reverse tbody tr,.charts-css.column.show-2-secondary-axes.reverse tbody tr,.charts-css.line.show-2-secondary-axes.reverse tbody tr{background-image:-webkit-gradient(linear,left bottom,left top,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(0deg,var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:100% calc(100% / 2)}.charts-css.area.show-3-secondary-axes:not(.reverse) tbody tr,.charts-css.column.show-3-secondary-axes:not(.reverse) tbody tr,.charts-css.line.show-3-secondary-axes:not(.reverse) tbody tr{background-image:-webkit-gradient(linear,left top,left bottom,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:100% calc(100% / 3)}.charts-css.area.show-3-secondary-axes.reverse tbody tr,.charts-css.column.show-3-secondary-axes.reverse tbody tr,.charts-css.line.show-3-secondary-axes.reverse tbody tr{background-image:-webkit-gradient(linear,left bottom,left top,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(0deg,var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:100% calc(100% / 3)}.charts-css.area.show-4-secondary-axes:not(.reverse) tbody tr,.charts-css.column.show-4-secondary-axes:not(.reverse) tbody tr,.charts-css.line.show-4-secondary-axes:not(.reverse) tbody tr{background-image:-webkit-gradient(linear,left top,left bottom,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:100% calc(100% / 4)}.charts-css.area.show-4-secondary-axes.reverse tbody tr,.charts-css.column.show-4-secondary-axes.reverse tbody tr,.charts-css.line.show-4-secondary-axes.reverse tbody tr{background-image:-webkit-gradient(linear,left bottom,left top,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(0deg,var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:100% calc(100% / 4)}.charts-css.area.show-5-secondary-axes:not(.reverse) tbody tr,.charts-css.column.show-5-secondary-axes:not(.reverse) tbody tr,.charts-css.line.show-5-secondary-axes:not(.reverse) tbody tr{background-image:-webkit-gradient(linear,left top,left bottom,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:100% calc(100% / 5)}.charts-css.area.show-5-secondary-axes.reverse tbody tr,.charts-css.column.show-5-secondary-axes.reverse tbody tr,.charts-css.line.show-5-secondary-axes.reverse tbody tr{background-image:-webkit-gradient(linear,left bottom,left top,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(0deg,var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:100% calc(100% / 5)}.charts-css.area.show-6-secondary-axes:not(.reverse) tbody tr,.charts-css.column.show-6-secondary-axes:not(.reverse) tbody tr,.charts-css.line.show-6-secondary-axes:not(.reverse) tbody tr{background-image:-webkit-gradient(linear,left top,left bottom,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:100% calc(100% / 6)}.charts-css.area.show-6-secondary-axes.reverse tbody tr,.charts-css.column.show-6-secondary-axes.reverse tbody tr,.charts-css.line.show-6-secondary-axes.reverse tbody tr{background-image:-webkit-gradient(linear,left bottom,left top,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(0deg,var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:100% calc(100% / 6)}.charts-css.area.show-7-secondary-axes:not(.reverse) tbody tr,.charts-css.column.show-7-secondary-axes:not(.reverse) tbody tr,.charts-css.line.show-7-secondary-axes:not(.reverse) tbody tr{background-image:-webkit-gradient(linear,left top,left bottom,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:100% calc(100% / 7)}.charts-css.area.show-7-secondary-axes.reverse tbody tr,.charts-css.column.show-7-secondary-axes.reverse tbody tr,.charts-css.line.show-7-secondary-axes.reverse tbody tr{background-image:-webkit-gradient(linear,left bottom,left top,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(0deg,var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:100% calc(100% / 7)}.charts-css.area.show-8-secondary-axes:not(.reverse) tbody tr,.charts-css.column.show-8-secondary-axes:not(.reverse) tbody tr,.charts-css.line.show-8-secondary-axes:not(.reverse) tbody tr{background-image:-webkit-gradient(linear,left top,left bottom,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:100% calc(100% / 8)}.charts-css.area.show-8-secondary-axes.reverse tbody tr,.charts-css.column.show-8-secondary-axes.reverse tbody tr,.charts-css.line.show-8-secondary-axes.reverse tbody tr{background-image:-webkit-gradient(linear,left bottom,left top,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(0deg,var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:100% calc(100% / 8)}.charts-css.area.show-9-secondary-axes:not(.reverse) tbody tr,.charts-css.column.show-9-secondary-axes:not(.reverse) tbody tr,.charts-css.line.show-9-secondary-axes:not(.reverse) tbody tr{background-image:-webkit-gradient(linear,left top,left bottom,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:100% calc(100% / 9)}.charts-css.area.show-9-secondary-axes.reverse tbody tr,.charts-css.column.show-9-secondary-axes.reverse tbody tr,.charts-css.line.show-9-secondary-axes.reverse tbody tr{background-image:-webkit-gradient(linear,left bottom,left top,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(0deg,var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:100% calc(100% / 9)}.charts-css.area.show-10-secondary-axes:not(.reverse) tbody tr,.charts-css.column.show-10-secondary-axes:not(.reverse) tbody tr,.charts-css.line.show-10-secondary-axes:not(.reverse) tbody tr{background-image:-webkit-gradient(linear,left top,left bottom,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:100% calc(100% / 10)}.charts-css.area.show-10-secondary-axes.reverse tbody tr,.charts-css.column.show-10-secondary-axes.reverse tbody tr,.charts-css.line.show-10-secondary-axes.reverse tbody tr{background-image:-webkit-gradient(linear,left bottom,left top,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(0deg,var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:100% calc(100% / 10)}.charts-css.area.show-data-axes tbody tr,.charts-css.area.show-dataset-axes tbody tr td,.charts-css.column.show-data-axes tbody tr,.charts-css.column.show-dataset-axes tbody tr td,.charts-css.line.show-data-axes tbody tr,.charts-css.line.show-dataset-axes tbody tr td{-webkit-border-end:var(--data-axes-width) var(--data-axes-style) var(--data-axes-color);border-inline-end:var(--data-axes-width) var(--data-axes-style) var(--data-axes-color)}.charts-css.area.show-data-axes.reverse-data tbody tr:last-of-type,.charts-css.area.show-data-axes:not(.reverse-data) tbody tr:first-of-type,.charts-css.area.show-dataset-axes.reverse-data tbody tr:last-of-type td,.charts-css.area.show-dataset-axes:not(.reverse-data) tbody tr:first-of-type td,.charts-css.column.show-data-axes.reverse-data tbody tr:last-of-type,.charts-css.column.show-data-axes:not(.reverse-data) tbody tr:first-of-type,.charts-css.column.show-dataset-axes.reverse-data tbody tr:last-of-type td,.charts-css.column.show-dataset-axes:not(.reverse-data) tbody tr:first-of-type td,.charts-css.line.show-data-axes.reverse-data tbody tr:last-of-type,.charts-css.line.show-data-axes:not(.reverse-data) tbody tr:first-of-type,.charts-css.line.show-dataset-axes.reverse-data tbody tr:last-of-type td,.charts-css.line.show-dataset-axes:not(.reverse-data) tbody tr:first-of-type td{-webkit-border-start:var(--data-axes-width) var(--data-axes-style) var(--data-axes-color);border-inline-start:var(--data-axes-width) var(--data-axes-style) var(--data-axes-color)}.charts-css.bar.show-primary-axis:not(.reverse) tbody tr{-webkit-border-start:var(--primary-axis-width) var(--primary-axis-style) var(--primary-axis-color);border-inline-start:var(--primary-axis-width) var(--primary-axis-style) var(--primary-axis-color)}.charts-css.bar.show-primary-axis.reverse tbody tr{-webkit-border-end:var(--primary-axis-width) var(--primary-axis-style) var(--primary-axis-color);border-inline-end:var(--primary-axis-width) var(--primary-axis-style) var(--primary-axis-color)}.charts-css.bar.show-1-secondary-axes:not(.reverse) tbody tr{background-image:-webkit-gradient(linear,right top,left top,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(-90deg,var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:calc(100% / 1) 100%}.charts-css.bar.show-1-secondary-axes.reverse tbody tr{background-image:-webkit-gradient(linear,left top,right top,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(90deg,var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:calc(100% / 1) 100%}.charts-css.bar.show-2-secondary-axes:not(.reverse) tbody tr{background-image:-webkit-gradient(linear,right top,left top,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(-90deg,var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:calc(100% / 2) 100%}.charts-css.bar.show-2-secondary-axes.reverse tbody tr{background-image:-webkit-gradient(linear,left top,right top,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(90deg,var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:calc(100% / 2) 100%}.charts-css.bar.show-3-secondary-axes:not(.reverse) tbody tr{background-image:-webkit-gradient(linear,right top,left top,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(-90deg,var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:calc(100% / 3) 100%}.charts-css.bar.show-3-secondary-axes.reverse tbody tr{background-image:-webkit-gradient(linear,left top,right top,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(90deg,var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:calc(100% / 3) 100%}.charts-css.bar.show-4-secondary-axes:not(.reverse) tbody tr{background-image:-webkit-gradient(linear,right top,left top,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(-90deg,var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:calc(100% / 4) 100%}.charts-css.bar.show-4-secondary-axes.reverse tbody tr{background-image:-webkit-gradient(linear,left top,right top,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(90deg,var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:calc(100% / 4) 100%}.charts-css.bar.show-5-secondary-axes:not(.reverse) tbody tr{background-image:-webkit-gradient(linear,right top,left top,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(-90deg,var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:calc(100% / 5) 100%}.charts-css.bar.show-5-secondary-axes.reverse tbody tr{background-image:-webkit-gradient(linear,left top,right top,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(90deg,var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:calc(100% / 5) 100%}.charts-css.bar.show-6-secondary-axes:not(.reverse) tbody tr{background-image:-webkit-gradient(linear,right top,left top,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(-90deg,var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:calc(100% / 6) 100%}.charts-css.bar.show-6-secondary-axes.reverse tbody tr{background-image:-webkit-gradient(linear,left top,right top,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(90deg,var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:calc(100% / 6) 100%}.charts-css.bar.show-7-secondary-axes:not(.reverse) tbody tr{background-image:-webkit-gradient(linear,right top,left top,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(-90deg,var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:calc(100% / 7) 100%}.charts-css.bar.show-7-secondary-axes.reverse tbody tr{background-image:-webkit-gradient(linear,left top,right top,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(90deg,var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:calc(100% / 7) 100%}.charts-css.bar.show-8-secondary-axes:not(.reverse) tbody tr{background-image:-webkit-gradient(linear,right top,left top,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(-90deg,var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:calc(100% / 8) 100%}.charts-css.bar.show-8-secondary-axes.reverse tbody tr{background-image:-webkit-gradient(linear,left top,right top,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(90deg,var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:calc(100% / 8) 100%}.charts-css.bar.show-9-secondary-axes:not(.reverse) tbody tr{background-image:-webkit-gradient(linear,right top,left top,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(-90deg,var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:calc(100% / 9) 100%}.charts-css.bar.show-9-secondary-axes.reverse tbody tr{background-image:-webkit-gradient(linear,left top,right top,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(90deg,var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:calc(100% / 9) 100%}.charts-css.bar.show-10-secondary-axes:not(.reverse) tbody tr{background-image:-webkit-gradient(linear,right top,left top,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(-90deg,var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:calc(100% / 10) 100%}.charts-css.bar.show-10-secondary-axes.reverse tbody tr{background-image:-webkit-gradient(linear,left top,right top,from(var(--secondary-axes-color)),to(transparent));background-image:linear-gradient(90deg,var(--secondary-axes-color) var(--secondary-axes-width),transparent var(--secondary-axes-width));background-size:calc(100% / 10) 100%}.charts-css.bar.show-data-axes tbody tr,.charts-css.bar.show-dataset-axes tbody tr td{-webkit-border-after:var(--data-axes-width) var(--data-axes-style) var(--data-axes-color);border-block-end:var(--data-axes-width) var(--data-axes-style) var(--data-axes-color)}.charts-css.bar.show-data-axes.reverse-data tbody tr:last-of-type,.charts-css.bar.show-data-axes:not(.reverse-data) tbody tr:first-of-type,.charts-css.bar.show-dataset-axes.reverse-data tbody tr:last-of-type td,.charts-css.bar.show-dataset-axes:not(.reverse-data) tbody tr:first-of-type td{-webkit-border-before:var(--data-axes-width) var(--data-axes-style) var(--data-axes-color);border-block-start:var(--data-axes-width) var(--data-axes-style) var(--data-axes-color)}.charts-css.pie.show-primary-axis tbody,.charts-css.polar.show-primary-axis tbody,.charts-css.radar.show-primary-axis tbody,.charts-css.radial.show-primary-axis tbody{border:var(--primary-axis-width) var(--primary-axis-style) var(--primary-axis-color)}.charts-css.pie.show-1-secondary-axes tbody::after,.charts-css.polar.show-1-secondary-axes tbody::after,.charts-css.radar.show-1-secondary-axes tbody::after,.charts-css.radial.show-1-secondary-axes tbody::after{background:repeating-radial-gradient(closest-side,transparent 0,transparent calc(100% / 2 - var(--secondary-axes-width)),var(--secondary-axes-color) calc(100% / 2 - var(--secondary-axes-width)),var(--secondary-axes-color) calc(100% / 2),transparent calc(100% / 2 + var(--secondary-axes-width)),transparent calc(100% / 2 + var(--secondary-axes-width)));border-radius:50%;bottom:0;content:"";height:100%;left:0;position:absolute;right:0;top:0;width:100%;z-index:2}.charts-css.pie.show-2-secondary-axes tbody::after,.charts-css.polar.show-2-secondary-axes tbody::after,.charts-css.radar.show-2-secondary-axes tbody::after,.charts-css.radial.show-2-secondary-axes tbody::after{background:repeating-radial-gradient(closest-side,transparent 0,transparent calc(100% / 3 - var(--secondary-axes-width)),var(--secondary-axes-color) calc(100% / 3 - var(--secondary-axes-width)),var(--secondary-axes-color) calc(100% / 3),transparent calc(100% / 3 + var(--secondary-axes-width)),transparent calc(100% / 3 + var(--secondary-axes-width)));border-radius:50%;bottom:0;content:"";height:100%;left:0;position:absolute;right:0;top:0;width:100%;z-index:2}.charts-css.pie.show-3-secondary-axes tbody::after,.charts-css.polar.show-3-secondary-axes tbody::after,.charts-css.radar.show-3-secondary-axes tbody::after,.charts-css.radial.show-3-secondary-axes tbody::after{background:repeating-radial-gradient(closest-side,transparent 0,transparent calc(100% / 4 - var(--secondary-axes-width)),var(--secondary-axes-color) calc(100% / 4 - var(--secondary-axes-width)),var(--secondary-axes-color) calc(100% / 4),transparent calc(100% / 4 + var(--secondary-axes-width)),transparent calc(100% / 4 + var(--secondary-axes-width)));border-radius:50%;bottom:0;content:"";height:100%;left:0;position:absolute;right:0;top:0;width:100%;z-index:2}.charts-css.pie.show-4-secondary-axes tbody::after,.charts-css.polar.show-4-secondary-axes tbody::after,.charts-css.radar.show-4-secondary-axes tbody::after,.charts-css.radial.show-4-secondary-axes tbody::after{background:repeating-radial-gradient(closest-side,transparent 0,transparent calc(100% / 5 - var(--secondary-axes-width)),var(--secondary-axes-color) calc(100% / 5 - var(--secondary-axes-width)),var(--secondary-axes-color) calc(100% / 5),transparent calc(100% / 5 + var(--secondary-axes-width)),transparent calc(100% / 5 + var(--secondary-axes-width)));border-radius:50%;bottom:0;content:"";height:100%;left:0;position:absolute;right:0;top:0;width:100%;z-index:2}.charts-css.pie.show-5-secondary-axes tbody::after,.charts-css.polar.show-5-secondary-axes tbody::after,.charts-css.radar.show-5-secondary-axes tbody::after,.charts-css.radial.show-5-secondary-axes tbody::after{background:repeating-radial-gradient(closest-side,transparent 0,transparent calc(100% / 6 - var(--secondary-axes-width)),var(--secondary-axes-color) calc(100% / 6 - var(--secondary-axes-width)),var(--secondary-axes-color) calc(100% / 6),transparent calc(100% / 6 + var(--secondary-axes-width)),transparent calc(100% / 6 + var(--secondary-axes-width)));border-radius:50%;bottom:0;content:"";height:100%;left:0;position:absolute;right:0;top:0;width:100%;z-index:2}.charts-css.pie.show-6-secondary-axes tbody::after,.charts-css.polar.show-6-secondary-axes tbody::after,.charts-css.radar.show-6-secondary-axes tbody::after,.charts-css.radial.show-6-secondary-axes tbody::after{background:repeating-radial-gradient(closest-side,transparent 0,transparent calc(100% / 7 - var(--secondary-axes-width)),var(--secondary-axes-color) calc(100% / 7 - var(--secondary-axes-width)),var(--secondary-axes-color) calc(100% / 7),transparent calc(100% / 7 + var(--secondary-axes-width)),transparent calc(100% / 7 + var(--secondary-axes-width)));border-radius:50%;bottom:0;content:"";height:100%;left:0;position:absolute;right:0;top:0;width:100%;z-index:2}.charts-css.pie.show-7-secondary-axes tbody::after,.charts-css.polar.show-7-secondary-axes tbody::after,.charts-css.radar.show-7-secondary-axes tbody::after,.charts-css.radial.show-7-secondary-axes tbody::after{background:repeating-radial-gradient(closest-side,transparent 0,transparent calc(100% / 8 - var(--secondary-axes-width)),var(--secondary-axes-color) calc(100% / 8 - var(--secondary-axes-width)),var(--secondary-axes-color) calc(100% / 8),transparent calc(100% / 8 + var(--secondary-axes-width)),transparent calc(100% / 8 + var(--secondary-axes-width)));border-radius:50%;bottom:0;content:"";height:100%;left:0;position:absolute;right:0;top:0;width:100%;z-index:2}.charts-css.pie.show-8-secondary-axes tbody::after,.charts-css.polar.show-8-secondary-axes tbody::after,.charts-css.radar.show-8-secondary-axes tbody::after,.charts-css.radial.show-8-secondary-axes tbody::after{background:repeating-radial-gradient(closest-side,transparent 0,transparent calc(100% / 9 - var(--secondary-axes-width)),var(--secondary-axes-color) calc(100% / 9 - var(--secondary-axes-width)),var(--secondary-axes-color) calc(100% / 9),transparent calc(100% / 9 + var(--secondary-axes-width)),transparent calc(100% / 9 + var(--secondary-axes-width)));border-radius:50%;bottom:0;content:"";height:100%;left:0;position:absolute;right:0;top:0;width:100%;z-index:2}.charts-css.pie.show-9-secondary-axes tbody::after,.charts-css.polar.show-9-secondary-axes tbody::after,.charts-css.radar.show-9-secondary-axes tbody::after,.charts-css.radial.show-9-secondary-axes tbody::after{background:repeating-radial-gradient(closest-side,transparent 0,transparent calc(100% / 10 - var(--secondary-axes-width)),var(--secondary-axes-color) calc(100% / 10 - var(--secondary-axes-width)),var(--secondary-axes-color) calc(100% / 10),transparent calc(100% / 10 + var(--secondary-axes-width)),transparent calc(100% / 10 + var(--secondary-axes-width)));border-radius:50%;bottom:0;content:"";height:100%;left:0;position:absolute;right:0;top:0;width:100%;z-index:2}.charts-css.pie.show-10-secondary-axes tbody::after,.charts-css.polar.show-10-secondary-axes tbody::after,.charts-css.radar.show-10-secondary-axes tbody::after,.charts-css.radial.show-10-secondary-axes tbody::after{background:repeating-radial-gradient(closest-side,transparent 0,transparent calc(100% / 11 - var(--secondary-axes-width)),var(--secondary-axes-color) calc(100% / 11 - var(--secondary-axes-width)),var(--secondary-axes-color) calc(100% / 11),transparent calc(100% / 11 + var(--secondary-axes-width)),transparent calc(100% / 11 + var(--secondary-axes-width)));border-radius:50%;bottom:0;content:"";height:100%;left:0;position:absolute;right:0;top:0;width:100%;z-index:2}.charts-css.legend{border:var(--legend-border-width) var(--legend-border-style) var(--legend-border-color);font-size:1rem;list-style:none;padding:1rem}.charts-css.legend li{-webkit-box-align:center;-ms-flex-align:center;align-items:center;display:-webkit-box;display:-ms-flexbox;display:flex;line-height:2}.charts-css.legend li::before{-webkit-margin-end:.5rem;border-style:solid;border-width:2px;content:"";display:inline-block;margin-inline-end:.5rem;vertical-align:middle}.charts-css.legend li:nth-child(10n+1)::before{background-color:var(--color-1,transparent);border-color:var(--border-color-1,var(--border-color,#000))}.charts-css.legend li:nth-child(10n+2)::before{background-color:var(--color-2,transparent);border-color:var(--border-color-2,var(--border-color,#000))}.charts-css.legend li:nth-child(10n+3)::before{background-color:var(--color-3,transparent);border-color:var(--border-color-3,var(--border-color,#000))}.charts-css.legend li:nth-child(10n+4)::before{background-color:var(--color-4,transparent);border-color:var(--border-color-4,var(--border-color,#000))}.charts-css.legend li:nth-child(10n+5)::before{background-color:var(--color-5,transparent);border-color:var(--border-color-5,var(--border-color,#000))}.charts-css.legend li:nth-child(10n+6)::before{background-color:var(--color-6,transparent);border-color:var(--border-color-6,var(--border-color,#000))}.charts-css.legend li:nth-child(10n+7)::before{background-color:var(--color-7,transparent);border-color:var(--border-color-7,var(--border-color,#000))}.charts-css.legend li:nth-child(10n+8)::before{background-color:var(--color-8,transparent);border-color:var(--border-color-8,var(--border-color,#000))}.charts-css.legend li:nth-child(10n+9)::before{background-color:var(--color-9,transparent);border-color:var(--border-color-9,var(--border-color,#000))}.charts-css.legend li:nth-child(10n+10)::before{background-color:var(--color-10,transparent);border-color:var(--border-color-10,var(--border-color,#000))}.charts-css:not(.legend-inline){-webkit-box-orient:vertical;-ms-flex-direction:column;flex-direction:column;-ms-flex-wrap:nowrap;flex-wrap:nowrap}.charts-css.legend-inline,.charts-css:not(.legend-inline){-webkit-box-direction:normal;display:-webkit-box;display:-ms-flexbox;display:flex}.charts-css.legend-inline{-webkit-box-orient:horizontal;-ms-flex-direction:row;flex-direction:row;-ms-flex-wrap:wrap;flex-wrap:wrap}.charts-css.legend-inline li{-webkit-margin-end:1rem;margin-inline-end:1rem}.charts-css.legend-circle li::before{border-radius:50%;height:1rem;width:1rem}.charts-css.legend-ellipse li::before{border-radius:50%;height:1rem;width:2rem}.charts-css.legend-rhombus li::before,.charts-css.legend-square li::before{border-radius:3px;height:1rem;width:1rem}.charts-css.legend-rhombus li::before{-webkit-transform:rotate(45deg) scale(.85);transform:rotate(45deg) scale(.85)}.charts-css.legend-rectangle li::before{border-radius:3px;height:1rem;width:2rem}.charts-css.legend-line li::before{border-radius:2px;-webkit-box-sizing:content-box;box-sizing:content-box;height:3px;width:2rem}.charts-css .tooltip{background-color:#555;border-radius:6px;bottom:50%;color:#fff;font-size:.9rem;left:50%;opacity:0;padding:5px 10px;position:absolute;text-align:center;-webkit-transform:translateX(-50%);transform:translateX(-50%);-webkit-transition:opacity .3s;transition:opacity .3s;visibility:hidden;width:-webkit-max-content;width:-moz-max-content;width:max-content;z-index:1}.charts-css .tooltip::after{border:5px solid transparent;border-top-color:#555;content:"";left:50%;margin-left:-5px;position:absolute;top:100%}.charts-css td:hover .tooltip{opacity:1;visibility:visible}.charts-css.bar tbody{-webkit-box-pack:justify;-ms-flex-pack:justify;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;aspect-ratio:var(--aspect-ratio,auto);display:-webkit-box;display:-ms-flexbox;display:flex;justify-content:space-between;width:100%}.charts-css.area tbody tr,.charts-css.bar tbody tr,.charts-css.column tbody tr,.charts-css.line tbody tr{-webkit-box-pack:start;-ms-flex-pack:start;-webkit-box-flex:1;-ms-flex-positive:1;-ms-flex-negative:1;-ms-flex-preferred-size:0;display:-webkit-box;display:-ms-flexbox;display:flex;flex-basis:0;flex-grow:1;flex-shrink:1;justify-content:flex-start;overflow-wrap:anywhere;position:relative}.charts-css.bar tbody tr th{bottom:0;left:0;position:absolute;right:0;top:0;width:var(--labels-size)}.charts-css.bar tbody tr td{-webkit-box-align:center;-ms-flex-align:center;-webkit-padding-before:10px;-webkit-padding-after:10px;align-items:center;display:-webkit-box;display:-ms-flexbox;display:flex;height:100%;min-height:1rem;padding-block-end:10px;padding-block-start:10px;position:relative;width:calc(100% * var(--end, var(--size, 1)))}.charts-css.bar:not(.reverse) tbody tr td{-webkit-box-pack:var(--data-position,flex-end);-ms-flex-pack:var(--data-position,flex-end);justify-content:var(--data-position,flex-end)}.charts-css.bar:not(.reverse) tbody tr td .data.outside{-webkit-transform:translateX(100%);transform:translateX(100%);white-space:nowrap}.charts-css.bar.reverse tbody tr td{-webkit-box-pack:var(--data-position,flex-start);-ms-flex-pack:var(--data-position,flex-start);justify-content:var(--data-position,flex-start)}.charts-css.bar.reverse tbody tr td .data.outside{-webkit-transform:translateX(-100%);transform:translateX(-100%);white-space:nowrap}.charts-css.area.reverse tbody tr,.charts-css.area:not(.reverse) tbody tr td .data,.charts-css.bar:not(.reverse) tbody tr,.charts-css.column.reverse tbody tr,.charts-css.line.reverse tbody tr,.charts-css.line:not(.reverse) tbody tr td .data{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.charts-css.area.reverse tbody tr td .data,.charts-css.area:not(.reverse) tbody tr,.charts-css.bar.reverse tbody tr,.charts-css.column:not(.reverse) tbody tr,.charts-css.line.reverse tbody tr td .data,.charts-css.line:not(.reverse) tbody tr{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}.charts-css.bar.reverse-labels.reverse tbody tr,.charts-css.bar:not(.reverse-labels):not(.reverse) tbody tr{-webkit-margin-start:var(--labels-size);margin-inline-start:var(--labels-size)}.charts-css.bar:not(.reverse-labels):not(.reverse) tbody tr th{-webkit-margin-end:auto;-webkit-margin-start:calc(-1 * var(--labels-size) - var(--primary-axis-width));margin-inline-end:auto;margin-inline-start:calc(-1 * var(--labels-size) - var(--primary-axis-width))}.charts-css.bar.reverse-labels:not(.reverse) tbody tr,.charts-css.bar:not(.reverse-labels).reverse tbody tr{-webkit-margin-end:var(--labels-size);margin-inline-end:var(--labels-size)}.charts-css.bar:not(.reverse-labels).reverse tbody tr th{-webkit-margin-start:auto;-webkit-margin-end:calc(-1 * var(--labels-size) - var(--primary-axis-width));margin-inline-end:calc(-1 * var(--labels-size) - var(--primary-axis-width));margin-inline-start:auto}.charts-css.bar.reverse-labels:not(.reverse) tbody tr th{-webkit-margin-start:auto;-webkit-margin-end:calc(-1 * var(--labels-size));margin-inline-end:calc(-1 * var(--labels-size));margin-inline-start:auto}.charts-css.bar.reverse-labels.reverse tbody tr th{-webkit-margin-end:auto;-webkit-margin-start:calc(-1 * var(--labels-size));margin-inline-end:auto;margin-inline-start:calc(-1 * var(--labels-size))}.charts-css.bar:not(.stacked) tbody tr td,.charts-css.column:not(.stacked) tbody tr td{-webkit-box-flex:1;-ms-flex-positive:1;-ms-flex-negative:1;-ms-flex-preferred-size:0;flex-basis:0;flex-grow:1;flex-shrink:1}.charts-css.bar.stacked tbody tr td,.charts-css.column.stacked tbody tr td{-webkit-box-flex:unset;-ms-flex-positive:unset;-ms-flex-negative:unset;-ms-flex-preferred-size:unset;flex-basis:unset;flex-grow:unset;flex-shrink:unset}.charts-css.area:not(.reverse) tbody tr th,.charts-css.bar.stacked.reverse-datasets tbody tr,.charts-css.column.stacked.reverse-datasets tbody tr,.charts-css.column:not(.reverse) tbody tr th,.charts-css.line:not(.reverse) tbody tr th{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.charts-css.bar:not(.reverse-data) tbody,.charts-css.bar:not(.reverse-datasets):not(.stacked) tbody tr,.charts-css.column.reverse-datasets.stacked:not(.reverse) tbody tr,.charts-css.column:not(.reverse-datasets).stacked.reverse tbody tr{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.charts-css.bar.reverse-data tbody,.charts-css.bar.reverse-datasets:not(.stacked) tbody tr,.charts-css.column.reverse-datasets.stacked.reverse tbody tr,.charts-css.column:not(.reverse-datasets).stacked:not(.reverse) tbody tr{-webkit-box-orient:vertical;-webkit-box-direction:reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}.charts-css.area:not(.reverse-data) tbody,.charts-css.area:not(.reverse-datasets) tbody tr,.charts-css.bar.reverse-datasets.stacked.reverse tbody tr,.charts-css.bar:not(.reverse-datasets).stacked:not(.reverse) tbody tr,.charts-css.column.reverse-labels.reverse-data tbody,.charts-css.column:not(.reverse-datasets):not(.stacked) tbody tr,.charts-css.column:not(.reverse-labels):not(.reverse-data) tbody,.charts-css.line:not(.reverse-data) tbody,.charts-css.line:not(.reverse-datasets) tbody tr{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.charts-css.area.reverse-data tbody,.charts-css.area.reverse-datasets tbody tr,.charts-css.bar.reverse-datasets.stacked:not(.reverse) tbody tr,.charts-css.bar:not(.reverse-datasets).stacked.reverse tbody tr,.charts-css.column.reverse-datasets:not(.stacked) tbody tr,.charts-css.column.reverse-labels:not(.reverse-data) tbody,.charts-css.column:not(.reverse-labels).reverse-data tbody,.charts-css.line.reverse-data tbody,.charts-css.line.reverse-datasets tbody tr{-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.charts-css.bar.data-spacing-1 tbody tr{-webkit-padding-before:1px;-webkit-padding-after:1px;padding-block-end:1px;padding-block-start:1px}.charts-css.bar.data-spacing-2 tbody tr{-webkit-padding-before:2px;-webkit-padding-after:2px;padding-block-end:2px;padding-block-start:2px}.charts-css.bar.data-spacing-3 tbody tr{-webkit-padding-before:3px;-webkit-padding-after:3px;padding-block-end:3px;padding-block-start:3px}.charts-css.bar.data-spacing-4 tbody tr{-webkit-padding-before:4px;-webkit-padding-after:4px;padding-block-end:4px;padding-block-start:4px}.charts-css.bar.data-spacing-5 tbody tr{-webkit-padding-before:5px;-webkit-padding-after:5px;padding-block-end:5px;padding-block-start:5px}.charts-css.bar.data-spacing-6 tbody tr{-webkit-padding-before:6px;-webkit-padding-after:6px;padding-block-end:6px;padding-block-start:6px}.charts-css.bar.data-spacing-7 tbody tr{-webkit-padding-before:7px;-webkit-padding-after:7px;padding-block-end:7px;padding-block-start:7px}.charts-css.bar.data-spacing-8 tbody tr{-webkit-padding-before:8px;-webkit-padding-after:8px;padding-block-end:8px;padding-block-start:8px}.charts-css.bar.data-spacing-9 tbody tr{-webkit-padding-before:9px;-webkit-padding-after:9px;padding-block-end:9px;padding-block-start:9px}.charts-css.bar.data-spacing-10 tbody tr{-webkit-padding-before:10px;-webkit-padding-after:10px;padding-block-end:10px;padding-block-start:10px}.charts-css.bar.data-spacing-11 tbody tr{-webkit-padding-before:11px;-webkit-padding-after:11px;padding-block-end:11px;padding-block-start:11px}.charts-css.bar.data-spacing-12 tbody tr{-webkit-padding-before:12px;-webkit-padding-after:12px;padding-block-end:12px;padding-block-start:12px}.charts-css.bar.data-spacing-13 tbody tr{-webkit-padding-before:13px;-webkit-padding-after:13px;padding-block-end:13px;padding-block-start:13px}.charts-css.bar.data-spacing-14 tbody tr{-webkit-padding-before:14px;-webkit-padding-after:14px;padding-block-end:14px;padding-block-start:14px}.charts-css.bar.data-spacing-15 tbody tr{-webkit-padding-before:15px;-webkit-padding-after:15px;padding-block-end:15px;padding-block-start:15px}.charts-css.bar.data-spacing-16 tbody tr{-webkit-padding-before:16px;-webkit-padding-after:16px;padding-block-end:16px;padding-block-start:16px}.charts-css.bar.data-spacing-17 tbody tr{-webkit-padding-before:17px;-webkit-padding-after:17px;padding-block-end:17px;padding-block-start:17px}.charts-css.bar.data-spacing-18 tbody tr{-webkit-padding-before:18px;-webkit-padding-after:18px;padding-block-end:18px;padding-block-start:18px}.charts-css.bar.data-spacing-19 tbody tr{-webkit-padding-before:19px;-webkit-padding-after:19px;padding-block-end:19px;padding-block-start:19px}.charts-css.bar.data-spacing-20 tbody tr{-webkit-padding-before:20px;-webkit-padding-after:20px;padding-block-end:20px;padding-block-start:20px}.charts-css.bar.datasets-spacing-1 tbody tr td{-webkit-margin-before:1px;-webkit-margin-after:1px;margin-block-end:1px;margin-block-start:1px}.charts-css.bar.datasets-spacing-2 tbody tr td{-webkit-margin-before:2px;-webkit-margin-after:2px;margin-block-end:2px;margin-block-start:2px}.charts-css.bar.datasets-spacing-3 tbody tr td{-webkit-margin-before:3px;-webkit-margin-after:3px;margin-block-end:3px;margin-block-start:3px}.charts-css.bar.datasets-spacing-4 tbody tr td{-webkit-margin-before:4px;-webkit-margin-after:4px;margin-block-end:4px;margin-block-start:4px}.charts-css.bar.datasets-spacing-5 tbody tr td{-webkit-margin-before:5px;-webkit-margin-after:5px;margin-block-end:5px;margin-block-start:5px}.charts-css.bar.datasets-spacing-6 tbody tr td{-webkit-margin-before:6px;-webkit-margin-after:6px;margin-block-end:6px;margin-block-start:6px}.charts-css.bar.datasets-spacing-7 tbody tr td{-webkit-margin-before:7px;-webkit-margin-after:7px;margin-block-end:7px;margin-block-start:7px}.charts-css.bar.datasets-spacing-8 tbody tr td{-webkit-margin-before:8px;-webkit-margin-after:8px;margin-block-end:8px;margin-block-start:8px}.charts-css.bar.datasets-spacing-9 tbody tr td{-webkit-margin-before:9px;-webkit-margin-after:9px;margin-block-end:9px;margin-block-start:9px}.charts-css.bar.datasets-spacing-10 tbody tr td{-webkit-margin-before:10px;-webkit-margin-after:10px;margin-block-end:10px;margin-block-start:10px}.charts-css.bar.datasets-spacing-11 tbody tr td{-webkit-margin-before:11px;-webkit-margin-after:11px;margin-block-end:11px;margin-block-start:11px}.charts-css.bar.datasets-spacing-12 tbody tr td{-webkit-margin-before:12px;-webkit-margin-after:12px;margin-block-end:12px;margin-block-start:12px}.charts-css.bar.datasets-spacing-13 tbody tr td{-webkit-margin-before:13px;-webkit-margin-after:13px;margin-block-end:13px;margin-block-start:13px}.charts-css.bar.datasets-spacing-14 tbody tr td{-webkit-margin-before:14px;-webkit-margin-after:14px;margin-block-end:14px;margin-block-start:14px}.charts-css.bar.datasets-spacing-15 tbody tr td{-webkit-margin-before:15px;-webkit-margin-after:15px;margin-block-end:15px;margin-block-start:15px}.charts-css.bar.datasets-spacing-16 tbody tr td{-webkit-margin-before:16px;-webkit-margin-after:16px;margin-block-end:16px;margin-block-start:16px}.charts-css.bar.datasets-spacing-17 tbody tr td{-webkit-margin-before:17px;-webkit-margin-after:17px;margin-block-end:17px;margin-block-start:17px}.charts-css.bar.datasets-spacing-18 tbody tr td{-webkit-margin-before:18px;-webkit-margin-after:18px;margin-block-end:18px;margin-block-start:18px}.charts-css.bar.datasets-spacing-19 tbody tr td{-webkit-margin-before:19px;-webkit-margin-after:19px;margin-block-end:19px;margin-block-start:19px}.charts-css.bar.datasets-spacing-20 tbody tr td{-webkit-margin-before:20px;-webkit-margin-after:20px;margin-block-end:20px;margin-block-start:20px}.charts-css.area tbody,.charts-css.column tbody,.charts-css.line tbody{-webkit-box-pack:justify;-ms-flex-pack:justify;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;aspect-ratio:var(--aspect-ratio,21/9);display:-webkit-box;display:-ms-flexbox;display:flex;justify-content:space-between;width:100%}.charts-css.area tbody tr th,.charts-css.column tbody tr th,.charts-css.line tbody tr th{bottom:0;height:var(--labels-size);left:0;position:absolute;right:0;top:0}.charts-css.column tbody tr td{-webkit-box-pack:center;-ms-flex-pack:center;display:-webkit-box;display:-ms-flexbox;display:flex;height:calc(100% * var(--end, var(--size, 1)));justify-content:center;position:relative;width:100%}.charts-css.column:not(.reverse) tbody tr td{-webkit-box-align:var(--data-position,flex-start);-ms-flex-align:var(--data-position,flex-start);align-items:var(--data-position,flex-start)}.charts-css.column.reverse tbody tr td{-webkit-box-align:var(--data-position,flex-end);-ms-flex-align:var(--data-position,flex-end);align-items:var(--data-position,flex-end)}.charts-css.area.reverse tbody tr td,.charts-css.area:not(.reverse) tbody tr td,.charts-css.column.reverse tbody tr td,.charts-css.column:not(.reverse) tbody tr td,.charts-css.line.reverse tbody tr td,.charts-css.line:not(.reverse) tbody tr td{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.charts-css.area.reverse tbody tr th,.charts-css.column.reverse tbody tr th,.charts-css.line.reverse tbody tr th{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.charts-css.area.reverse-labels.reverse tbody tr,.charts-css.area:not(.reverse-labels):not(.reverse) tbody tr,.charts-css.column.reverse-labels.reverse tbody tr,.charts-css.column:not(.reverse-labels):not(.reverse) tbody tr,.charts-css.line.reverse-labels.reverse tbody tr,.charts-css.line:not(.reverse-labels):not(.reverse) tbody tr{-webkit-margin-after:var(--labels-size);margin-block-end:var(--labels-size)}.charts-css.area:not(.reverse-labels):not(.reverse) tbody tr th,.charts-css.column:not(.reverse-labels):not(.reverse) tbody tr th,.charts-css.line:not(.reverse-labels):not(.reverse) tbody tr th{-webkit-margin-before:auto;-webkit-margin-after:calc(-1 * var(--labels-size) - var(--primary-axis-width));margin-block-end:calc(-1 * var(--labels-size) - var(--primary-axis-width));margin-block-start:auto}.charts-css.area.reverse-labels:not(.reverse) tbody tr,.charts-css.area:not(.reverse-labels).reverse tbody tr,.charts-css.column.reverse-labels:not(.reverse) tbody tr,.charts-css.column:not(.reverse-labels).reverse tbody tr,.charts-css.line.reverse-labels:not(.reverse) tbody tr,.charts-css.line:not(.reverse-labels).reverse tbody tr{-webkit-margin-before:var(--labels-size);margin-block-start:var(--labels-size)}.charts-css.area:not(.reverse-labels).reverse tbody tr th,.charts-css.column:not(.reverse-labels).reverse tbody tr th,.charts-css.line:not(.reverse-labels).reverse tbody tr th{-webkit-margin-after:auto;-webkit-margin-before:calc(-1 * var(--labels-size) - var(--primary-axis-width));margin-block-end:auto;margin-block-start:calc(-1 * var(--labels-size) - var(--primary-axis-width))}.charts-css.area.reverse-labels:not(.reverse) tbody tr th,.charts-css.column.reverse-labels:not(.reverse) tbody tr th,.charts-css.line.reverse-labels:not(.reverse) tbody tr th{-webkit-margin-after:auto;-webkit-margin-before:calc(-1 * var(--labels-size));margin-block-end:auto;margin-block-start:calc(-1 * var(--labels-size))}.charts-css.area.reverse-labels.reverse tbody tr th,.charts-css.column.reverse-labels.reverse tbody tr th,.charts-css.line.reverse-labels.reverse tbody tr th{-webkit-margin-before:auto;-webkit-margin-after:calc(-1 * var(--labels-size));margin-block-end:calc(-1 * var(--labels-size));margin-block-start:auto}.charts-css.column.data-spacing-1 tbody tr{-webkit-padding-start:1px;-webkit-padding-end:1px;padding-inline-end:1px;padding-inline-start:1px}.charts-css.column.data-spacing-2 tbody tr{-webkit-padding-start:2px;-webkit-padding-end:2px;padding-inline-end:2px;padding-inline-start:2px}.charts-css.column.data-spacing-3 tbody tr{-webkit-padding-start:3px;-webkit-padding-end:3px;padding-inline-end:3px;padding-inline-start:3px}.charts-css.column.data-spacing-4 tbody tr{-webkit-padding-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-inline-start:4px}.charts-css.column.data-spacing-5 tbody tr{-webkit-padding-start:5px;-webkit-padding-end:5px;padding-inline-end:5px;padding-inline-start:5px}.charts-css.column.data-spacing-6 tbody tr{-webkit-padding-start:6px;-webkit-padding-end:6px;padding-inline-end:6px;padding-inline-start:6px}.charts-css.column.data-spacing-7 tbody tr{-webkit-padding-start:7px;-webkit-padding-end:7px;padding-inline-end:7px;padding-inline-start:7px}.charts-css.column.data-spacing-8 tbody tr{-webkit-padding-start:8px;-webkit-padding-end:8px;padding-inline-end:8px;padding-inline-start:8px}.charts-css.column.data-spacing-9 tbody tr{-webkit-padding-start:9px;-webkit-padding-end:9px;padding-inline-end:9px;padding-inline-start:9px}.charts-css.column.data-spacing-10 tbody tr{-webkit-padding-start:10px;-webkit-padding-end:10px;padding-inline-end:10px;padding-inline-start:10px}.charts-css.column.data-spacing-11 tbody tr{-webkit-padding-start:11px;-webkit-padding-end:11px;padding-inline-end:11px;padding-inline-start:11px}.charts-css.column.data-spacing-12 tbody tr{-webkit-padding-start:12px;-webkit-padding-end:12px;padding-inline-end:12px;padding-inline-start:12px}.charts-css.column.data-spacing-13 tbody tr{-webkit-padding-start:13px;-webkit-padding-end:13px;padding-inline-end:13px;padding-inline-start:13px}.charts-css.column.data-spacing-14 tbody tr{-webkit-padding-start:14px;-webkit-padding-end:14px;padding-inline-end:14px;padding-inline-start:14px}.charts-css.column.data-spacing-15 tbody tr{-webkit-padding-start:15px;-webkit-padding-end:15px;padding-inline-end:15px;padding-inline-start:15px}.charts-css.column.data-spacing-16 tbody tr{-webkit-padding-start:16px;-webkit-padding-end:16px;padding-inline-end:16px;padding-inline-start:16px}.charts-css.column.data-spacing-17 tbody tr{-webkit-padding-start:17px;-webkit-padding-end:17px;padding-inline-end:17px;padding-inline-start:17px}.charts-css.column.data-spacing-18 tbody tr{-webkit-padding-start:18px;-webkit-padding-end:18px;padding-inline-end:18px;padding-inline-start:18px}.charts-css.column.data-spacing-19 tbody tr{-webkit-padding-start:19px;-webkit-padding-end:19px;padding-inline-end:19px;padding-inline-start:19px}.charts-css.column.data-spacing-20 tbody tr{-webkit-padding-start:20px;-webkit-padding-end:20px;padding-inline-end:20px;padding-inline-start:20px}.charts-css.column.datasets-spacing-1 tbody tr td{-webkit-margin-start:1px;-webkit-margin-end:1px;margin-inline-end:1px;margin-inline-start:1px}.charts-css.column.datasets-spacing-2 tbody tr td{-webkit-margin-start:2px;-webkit-margin-end:2px;margin-inline-end:2px;margin-inline-start:2px}.charts-css.column.datasets-spacing-3 tbody tr td{-webkit-margin-start:3px;-webkit-margin-end:3px;margin-inline-end:3px;margin-inline-start:3px}.charts-css.column.datasets-spacing-4 tbody tr td{-webkit-margin-start:4px;-webkit-margin-end:4px;margin-inline-end:4px;margin-inline-start:4px}.charts-css.column.datasets-spacing-5 tbody tr td{-webkit-margin-start:5px;-webkit-margin-end:5px;margin-inline-end:5px;margin-inline-start:5px}.charts-css.column.datasets-spacing-6 tbody tr td{-webkit-margin-start:6px;-webkit-margin-end:6px;margin-inline-end:6px;margin-inline-start:6px}.charts-css.column.datasets-spacing-7 tbody tr td{-webkit-margin-start:7px;-webkit-margin-end:7px;margin-inline-end:7px;margin-inline-start:7px}.charts-css.column.datasets-spacing-8 tbody tr td{-webkit-margin-start:8px;-webkit-margin-end:8px;margin-inline-end:8px;margin-inline-start:8px}.charts-css.column.datasets-spacing-9 tbody tr td{-webkit-margin-start:9px;-webkit-margin-end:9px;margin-inline-end:9px;margin-inline-start:9px}.charts-css.column.datasets-spacing-10 tbody tr td{-webkit-margin-start:10px;-webkit-margin-end:10px;margin-inline-end:10px;margin-inline-start:10px}.charts-css.column.datasets-spacing-11 tbody tr td{-webkit-margin-start:11px;-webkit-margin-end:11px;margin-inline-end:11px;margin-inline-start:11px}.charts-css.column.datasets-spacing-12 tbody tr td{-webkit-margin-start:12px;-webkit-margin-end:12px;margin-inline-end:12px;margin-inline-start:12px}.charts-css.column.datasets-spacing-13 tbody tr td{-webkit-margin-start:13px;-webkit-margin-end:13px;margin-inline-end:13px;margin-inline-start:13px}.charts-css.column.datasets-spacing-14 tbody tr td{-webkit-margin-start:14px;-webkit-margin-end:14px;margin-inline-end:14px;margin-inline-start:14px}.charts-css.column.datasets-spacing-15 tbody tr td{-webkit-margin-start:15px;-webkit-margin-end:15px;margin-inline-end:15px;margin-inline-start:15px}.charts-css.column.datasets-spacing-16 tbody tr td{-webkit-margin-start:16px;-webkit-margin-end:16px;margin-inline-end:16px;margin-inline-start:16px}.charts-css.column.datasets-spacing-17 tbody tr td{-webkit-margin-start:17px;-webkit-margin-end:17px;margin-inline-end:17px;margin-inline-start:17px}.charts-css.column.datasets-spacing-18 tbody tr td{-webkit-margin-start:18px;-webkit-margin-end:18px;margin-inline-end:18px;margin-inline-start:18px}.charts-css.column.datasets-spacing-19 tbody tr td{-webkit-margin-start:19px;-webkit-margin-end:19px;margin-inline-end:19px;margin-inline-start:19px}.charts-css.column.datasets-spacing-20 tbody tr td{-webkit-margin-start:20px;-webkit-margin-end:20px;margin-inline-end:20px;margin-inline-start:20px}.charts-css.area tbody tr td,.charts-css.line tbody tr td{-webkit-box-orient:vertical;-webkit-box-direction:normal;bottom:0;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-flow:column;flex-flow:column;height:100%;left:0;position:absolute;right:0;top:0;width:100%;z-index:0}.charts-css.area tbody tr td::before,.charts-css.line tbody tr td::before{bottom:0;content:"";left:0;position:absolute;right:0;top:0;z-index:-1}.charts-css.area tbody tr td::after,.charts-css.line tbody tr td::after,.charts-css.pie tbody tr td::after{content:"";width:100%}.charts-css.area.reverse:not(.reverse-data) tbody tr td,.charts-css.area:not(.reverse):not(.reverse-data) tbody tr td,.charts-css.line.reverse:not(.reverse-data) tbody tr td,.charts-css.line:not(.reverse):not(.reverse-data) tbody tr td{-webkit-box-pack:end;-ms-flex-pack:end;-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end;justify-content:flex-end}.charts-css.area:not(.reverse):not(.reverse-data) tbody tr td::before{-webkit-clip-path:polygon(0 calc(100% * (1 - var(--start, var(--end, var(--size))))),100% calc(100% * (1 - var(--end, var(--size)))),100% 100%,0 100%);clip-path:polygon(0 calc(100% * (1 - var(--start, var(--end, var(--size))))),100% calc(100% * (1 - var(--end, var(--size)))),100% 100%,0 100%)}.charts-css.area.reverse:not(.reverse-data) tbody tr td .data,.charts-css.area:not(.reverse):not(.reverse-data) tbody tr td .data,.charts-css.line.reverse:not(.reverse-data) tbody tr td .data,.charts-css.line:not(.reverse):not(.reverse-data) tbody tr td .data{-webkit-transform:translateX(50%);transform:translateX(50%)}.charts-css.area:not(.reverse).reverse-data tbody tr td::after,.charts-css.area:not(.reverse):not(.reverse-data) tbody tr td::after,.charts-css.line:not(.reverse).reverse-data tbody tr td::after,.charts-css.line:not(.reverse):not(.reverse-data) tbody tr td::after{height:calc(100% * var(--end, var(--size)))}.charts-css.area.reverse.reverse-data tbody tr td,.charts-css.area:not(.reverse).reverse-data tbody tr td,.charts-css.line.reverse.reverse-data tbody tr td,.charts-css.line:not(.reverse).reverse-data tbody tr td{-webkit-box-pack:end;-ms-flex-pack:end;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start;justify-content:flex-end}.charts-css.area:not(.reverse).reverse-data tbody tr td::before{-webkit-clip-path:polygon(0 calc(100% * (1 - var(--end, var(--size)))),100% calc(100% * (1 - var(--start, var(--end, var(--size))))),100% 100%,0 100%);clip-path:polygon(0 calc(100% * (1 - var(--end, var(--size)))),100% calc(100% * (1 - var(--start, var(--end, var(--size))))),100% 100%,0 100%)}.charts-css.area.reverse.reverse-data tbody tr td .data,.charts-css.area:not(.reverse).reverse-data tbody tr td .data,.charts-css.line.reverse.reverse-data tbody tr td .data,.charts-css.line:not(.reverse).reverse-data tbody tr td .data{-webkit-transform:translateX(-50%);transform:translateX(-50%)}.charts-css.area.reverse:not(.reverse-data) tbody tr td::before{-webkit-clip-path:polygon(0 0,100% 0,100% calc(100% * var(--end, var(--size))),0 calc(100% * var(--start, var(--end, var(--size)))));clip-path:polygon(0 0,100% 0,100% calc(100% * var(--end, var(--size))),0 calc(100% * var(--start, var(--end, var(--size)))))}.charts-css.area.reverse.reverse-data tbody tr td::after,.charts-css.area.reverse:not(.reverse-data) tbody tr td::after,.charts-css.line.reverse.reverse-data tbody tr td::after,.charts-css.line.reverse:not(.reverse-data) tbody tr td::after{height:calc(100% * (1 - var(--end, var(--size))))}.charts-css.area.reverse.reverse-data tbody tr td::before{-webkit-clip-path:polygon(0 0,100% 0,100% calc(100% * var(--start, var(--end, var(--size)))),0 calc(100% * var(--end, var(--size))));clip-path:polygon(0 0,100% 0,100% calc(100% * var(--start, var(--end, var(--size)))),0 calc(100% * var(--end, var(--size))))}.charts-css.line{--line-size:3px}.charts-css.line:not(.reverse):not(.reverse-data) tbody tr td::before{-webkit-clip-path:polygon(0 calc(100% * (1 - var(--start, var(--end, var(--size))))),100% calc(100% * (1 - var(--end, var(--size)))),100% calc(100% * (1 - var(--end, var(--size))) - var(--line-size)),0 calc(100% * (1 - var(--start, var(--end, var(--size)))) - var(--line-size)));clip-path:polygon(0 calc(100% * (1 - var(--start, var(--end, var(--size))))),100% calc(100% * (1 - var(--end, var(--size)))),100% calc(100% * (1 - var(--end, var(--size))) - var(--line-size)),0 calc(100% * (1 - var(--start, var(--end, var(--size)))) - var(--line-size)))}.charts-css.line:not(.reverse).reverse-data tbody tr td::before{-webkit-clip-path:polygon(0 calc(100% * (1 - var(--end, var(--size)))),100% calc(100% * (1 - var(--start, var(--end, var(--size))))),100% calc(100% * (1 - var(--start, var(--end, var(--size)))) - var(--line-size)),0 calc(100% * (1 - var(--end, var(--size))) - var(--line-size)));clip-path:polygon(0 calc(100% * (1 - var(--end, var(--size)))),100% calc(100% * (1 - var(--start, var(--end, var(--size))))),100% calc(100% * (1 - var(--start, var(--end, var(--size)))) - var(--line-size)),0 calc(100% * (1 - var(--end, var(--size))) - var(--line-size)))}.charts-css.line.reverse:not(.reverse-data) tbody tr td::before{-webkit-clip-path:polygon(0 calc(100% * var(--start, var(--end, var(--size))) - var(--line-size)),100% calc(100% * var(--end, var(--size)) - var(--line-size)),100% calc(100% * var(--end, var(--size))),0 calc(100% * var(--start, var(--end, var(--size)))));clip-path:polygon(0 calc(100% * var(--start, var(--end, var(--size))) - var(--line-size)),100% calc(100% * var(--end, var(--size)) - var(--line-size)),100% calc(100% * var(--end, var(--size))),0 calc(100% * var(--start, var(--end, var(--size)))))}.charts-css.line.reverse.reverse-data tbody tr td::before{-webkit-clip-path:polygon(0 calc(100% * var(--end, var(--size)) - var(--line-size)),100% calc(100% * var(--start, var(--end, var(--size))) - var(--line-size)),100% calc(100% * var(--start, var(--end, var(--size)))),0 calc(100% * var(--end, var(--size))));clip-path:polygon(0 calc(100% * var(--end, var(--size)) - var(--line-size)),100% calc(100% * var(--start, var(--end, var(--size))) - var(--line-size)),100% calc(100% * var(--start, var(--end, var(--size)))),0 calc(100% * var(--end, var(--size))))}.charts-css.pie tbody,.charts-css.polar tbody,.charts-css.radar tbody,.charts-css.radial tbody{aspect-ratio:1;background-color:var(--chart-bg-color);border-radius:50%;display:block;width:100%}.charts-css.pie tbody tr td{-webkit-box-pack:center;-ms-flex-pack:center;background:conic-gradient(transparent 0 calc(1turn * var(--start)),var(--c,transparent) calc(1turn * var(--start, 0)) calc(1turn * var(--end)),transparent calc(1turn * var(--end)) 1turn);border-radius:50%;display:-webkit-box;display:-ms-flexbox;display:flex;justify-content:center}.charts-css.pie tbody tr td,.charts-css.pie tbody tr td::before{bottom:0;height:100%;left:0;position:absolute;right:0;top:0;width:100%}.charts-css.pie tbody tr td::before{content:""}.charts-css.pie tbody tr td .data{-webkit-box-pack:center;-ms-flex-pack:center;border-radius:50%;bottom:0;display:-webkit-box;display:-ms-flexbox;display:flex;height:100%;justify-content:center;left:0;position:absolute;right:0;top:0;-webkit-transform:rotate(calc(.5turn * var(--start, 0) + .5turn * var(--end, 0)));transform:rotate(calc(.5turn * var(--start, 0) + .5turn * var(--end, 0)));width:100%}
@@ -1,3 +1,30 @@
1
1
  #header-icon {
2
2
  max-height: 2em;
3
3
  }
4
+
5
+ .graphql-highlight {
6
+ font-family:'Courier New', Courier, monospace;
7
+ width: 100%;
8
+ white-space: pre-wrap;
9
+ }
10
+
11
+ #limiter-histogram .column {
12
+ max-height: 300px;
13
+ }
14
+
15
+ #limiter-histogram .column td {
16
+ --color-1: var(--bs-gray);
17
+ --color-2: var(--bs-red);
18
+ opacity: 0.6;
19
+ }
20
+
21
+ #limiter-histogram .column td:hover {
22
+ opacity: 1;
23
+ }
24
+
25
+ #limiter-histogram .column tbody tr th[scope=row] {
26
+ width: 150px;
27
+ transform: rotate(-75deg) translateY(55px) translateX(-50px);
28
+ left: auto;
29
+ --labels-align-inline: end;
30
+ }
@@ -52,18 +52,77 @@ async function openOnPerfetto(operationName, tracePath) {
52
52
  }, 100)
53
53
  }
54
54
 
55
- async function deleteTrace(tracePath, event) {
55
+ function getCsrfToken() {
56
+ return document.querySelector("meta[name='csrf-token']").content
57
+ }
58
+
59
+ function deleteTrace(tracePath) {
56
60
  if (confirm("Are you sure you want to permanently delete this trace?")) {
57
- var response = await fetch(tracePath, { method: "DELETE", headers: {
58
- "X-CSRF-Token": document.querySelector("meta[name='csrf-token']").content
59
- } })
60
- if (response.ok) {
61
- var row = event.target.closest("tr")
62
- row.remove()
63
- } else {
64
- console.error("Delete request failed for", tracePath, response)
61
+ fetch(tracePath, { method: "DELETE", headers: {
62
+ "X-CSRF-Token": getCsrfToken()
63
+ } }).then(function(_response) {
64
+ window.location.reload()
65
+ })
66
+ }
67
+ }
68
+
69
+ function deleteAllTraces(path) {
70
+ if (confirm("Are you sure you want to permanently delete ALL traces?")) {
71
+ fetch(path, { method: "DELETE", headers: {
72
+ "X-CSRF-Token": getCsrfToken()
73
+ } }).then(function(_response) {
74
+ window.location.reload()
75
+ })
76
+ }
77
+ }
78
+
79
+ function deleteAllSubscriptions(path) {
80
+ if (confirm("This will:\n\n- Remove all subscriptions from the database\n- Stop updates to all current subscribers\n\nAre you sure?")) {
81
+ fetch(path, { method: "POST", headers: {
82
+ "X-CSRF-Token": getCsrfToken()
83
+ } }).then(function(_response) {
84
+ window.location.reload()
85
+ })
86
+ }
87
+ }
88
+
89
+ function sendArchive(clientName) {
90
+ var values = []
91
+ document.querySelectorAll(".archive-check:checked").forEach(function(el) {
92
+ values.push(el.value)
93
+ })
94
+ if (values.length == 0) {
95
+ return
96
+ }
97
+ var mode = window.location.pathname.includes("/archived") ? "/unarchive" : "/archive"
98
+ if (mode == "/archive") {
99
+ if (!confirm("Are you sure you want to archive these operations? They won't be usable by clients while archived.")) {
100
+ return
101
+ }
102
+ } else {
103
+ if (!confirm("Are you sure you want to reactivate these operations? They'll be available to clients again.")) {
104
+ return
105
+ }
106
+ }
107
+ var url = window.location.pathname.replace("/archived", "")
108
+ url += mode
109
+ var data
110
+
111
+ if (clientName) {
112
+ data = {
113
+ operation_aliases: values
114
+ }
115
+ } else {
116
+ data = {
117
+ digests: values
65
118
  }
66
119
  }
120
+ fetch(url, { method: "POST", body: JSON.stringify(data), headers: {
121
+ "X-CSRF-Token": getCsrfToken(),
122
+ "Content-Type": "application/json",
123
+ }}).then(function(_response) {
124
+ window.location.reload()
125
+ })
67
126
  }
68
127
 
69
128
  document.addEventListener("click", function(event) {
@@ -72,7 +131,13 @@ document.addEventListener("click", function(event) {
72
131
  openOnPerfetto(dataset.perfettoOpen, dataset.perfettoPath)
73
132
  } else if (dataset.perfettoDelete) {
74
133
  deleteTrace(dataset.perfettoDelete, event)
134
+ } else if (dataset.perfettoDeleteAll) {
135
+ deleteAllTraces(dataset.perfettoDeleteAll)
136
+ } else if (dataset.subscriptionsDeleteAll) {
137
+ deleteAllSubscriptions(dataset.subscriptionsDeleteAll)
75
138
  } else if (event.target.id == "themeToggle") {
76
139
  toggleTheme()
140
+ } else if (dataset.archiveClient || dataset.archiveAll) {
141
+ sendArchive(dataset.archiveClient)
77
142
  }
78
143
  })
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+ module Graphql
3
+ class Dashboard < Rails::Engine
4
+ module Subscriptions
5
+ class BaseController < Graphql::Dashboard::ApplicationController
6
+ include Installable
7
+
8
+ def feature_installed?
9
+ schema_class.subscriptions.is_a?(GraphQL::Pro::Subscriptions)
10
+ end
11
+
12
+ INSTALLABLE_COMPONENT_HEADER_HTML = "GraphQL-Pro Subscriptions aren't installed on this schema yet.".html_safe
13
+ INSTALLABLE_COMPONENT_MESSAGE_HTML = <<-HTML.html_safe
14
+ Deliver live updates over
15
+ <a href="https://graphql-ruby.org/subscriptions/pusher_implementation.html">Pusher</a> or
16
+ <a href="https://graphql-ruby.org/subscriptions/ably_implementation.html"> Ably</a>
17
+ with GraphQL-Pro's subscription integrations.
18
+ HTML
19
+ end
20
+
21
+ class TopicsController < BaseController
22
+ def show
23
+ topic_name = params[:name]
24
+ all_subscription_ids = []
25
+ schema_class.subscriptions.each_subscription_id(topic_name) do |sid|
26
+ all_subscription_ids << sid
27
+ end
28
+
29
+ page = params[:page]&.to_i || 1
30
+ limit = params[:per_page]&.to_i || 20
31
+ offset = limit * (page - 1)
32
+ subscription_ids = all_subscription_ids[offset, limit]
33
+ subs = schema_class.subscriptions.read_subscriptions(subscription_ids)
34
+ show_broadcast_subscribers_count = schema_class.subscriptions.show_broadcast_subscribers_count?
35
+ subs.each do |sub|
36
+ sub[:is_broadcast] = is_broadcast = schema_class.subscriptions.broadcast_subscription_id?(sub[:id])
37
+ if is_broadcast && show_broadcast_subscribers_count
38
+ sub[:subscribers_count] = sub_count =schema_class.subscriptions.count_broadcast_subscribed(sub[:id])
39
+ sub[:still_subscribed] = sub_count > 0
40
+ else
41
+ sub[:still_subscribed] = schema_class.subscriptions.still_subscribed?(sub[:id])
42
+ sub[:subscribers_count] = nil
43
+ end
44
+ end
45
+
46
+ @topic_last_triggered_at = schema_class.subscriptions.topic_last_triggered_at(topic_name)
47
+ @subscriptions = subs
48
+ @subscriptions_count = all_subscription_ids.size
49
+ @show_broadcast_subscribers_count = show_broadcast_subscribers_count
50
+ @has_next_page = all_subscription_ids.size > offset + limit ? page + 1 : false
51
+ end
52
+
53
+ def index
54
+ page = params[:page]&.to_i || 1
55
+ per_page = params[:per_page]&.to_i || 20
56
+ offset = per_page * (page - 1)
57
+ limit = per_page
58
+ topics, all_topics_count, has_next_page = schema_class.subscriptions.topics(offset: offset, limit: limit)
59
+
60
+ @topics = topics
61
+ @all_topics_count = all_topics_count
62
+ @has_next_page = has_next_page
63
+ @page = page
64
+ end
65
+ end
66
+
67
+ class SubscriptionsController < BaseController
68
+ def show
69
+ subscription_id = params[:id]
70
+ subscriptions = schema_class.subscriptions
71
+ query_data = subscriptions.read_subscription(subscription_id)
72
+ is_broadcast = subscriptions.broadcast_subscription_id?(subscription_id)
73
+
74
+ if is_broadcast && subscriptions.show_broadcast_subscribers_count?
75
+ subscribers_count = subscriptions.count_broadcast_subscribed(subscription_id)
76
+ is_still_subscribed = subscribers_count > 0
77
+ else
78
+ subscribers_count = nil
79
+ is_still_subscribed = subscriptions.still_subscribed?(subscription_id)
80
+ end
81
+
82
+ @query_data = query_data
83
+ @still_subscribed = is_still_subscribed
84
+ @is_broadcast = is_broadcast
85
+ @subscribers_count = subscribers_count
86
+ end
87
+
88
+ def clear_all
89
+ schema_class.subscriptions.clear
90
+ flash[:success] = "All subscription data cleared."
91
+ head :no_content
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,45 @@
1
+ <% content_for(:title, "Profiles") %>
2
+ <div class="row justify-content-between mt-3">
3
+ <div class="col-auto">
4
+ <h3>Detailed Profiles</h3>
5
+ </div>
6
+ <div class="col-auto">
7
+ <%= button_tag "Delete All Traces", class: "btn btn-sm btn-outline-danger", data: { perfetto_delete_all: graphql_dashboard.delete_all_detailed_traces_traces_path } %>
8
+ </div>
9
+ </div>
10
+
11
+ <div class="row">
12
+ <div class="col">
13
+ <table class="table table-striped">
14
+ <thead>
15
+ <tr>
16
+ <th>Operation</th>
17
+ <th>Duration (ms) </th>
18
+ <th>Timestamp</th>
19
+ <th>Open in Perfetto UI</th>
20
+ </tr>
21
+ </thead>
22
+ <tbody>
23
+ <% if @traces.empty? %>
24
+ <tr>
25
+ <td colspan="4" class="text-center">
26
+ <em>No traces saved yet. Read about saving traces <%= link_to "in the docs", "https://graphql-ruby.org/queries/tracing#detailed-profiles" %>.</em>
27
+ </td>
28
+ </tr>
29
+ <% end %>
30
+ <% @traces.each do |trace| %>
31
+ <tr>
32
+ <td><%= trace.operation_name %></td>
33
+ <td><%= trace.duration_ms.round(2) %></td>
34
+ <td><%= Time.at(trace.begin_ms / 1000.0).strftime("%Y-%m-%d %H:%M:%S.%L") %></td>
35
+ <td><%= link_to "View ↗", "#", data: { perfetto_open: trace.operation_name, perfetto_path: graphql_dashboard.detailed_traces_trace_path(trace.id) } %></td>
36
+ <td><%= link_to "Delete", "#", data: { perfetto_delete: graphql_dashboard.detailed_traces_trace_path(trace.id) }, class: "text-danger" %></td>
37
+ </tr>
38
+ <% end %>
39
+ </tbody>
40
+ </table>
41
+ <% if @last && @traces.size >= @last %>
42
+ <%= link_to("Previous >", graphql_dashboard.detailed_traces_traces_path(last: @last, before: @traces.last.begin_ms), class: "btn btn-outline-primary") %>
43
+ <% end %>
44
+ </div>
45
+ </div>
@@ -0,0 +1,62 @@
1
+ <% content_for(:title, @title) %>
2
+ <% if @install_path %>
3
+ <div class="row mt-3">
4
+ <div class="col">
5
+ <h3><%= @title %></h3>
6
+ <p>It looks like this limiter isn't installed yet. <a href="<%= @install_path %>">Install it now</a>.</p>
7
+ </div>
8
+ </div>
9
+ <% else %>
10
+ <div class="row mt-3 justify-content-between">
11
+ <div class="col-auto">
12
+ <h3><%= @title %></h3>
13
+ </div>
14
+ <div class="col-auto">
15
+ <div class="btn-group">
16
+ <%= link_to("This Hour", graphql_dashboard.limiters_limiter_path(params[:name], chart: "hour"), class: "btn btn-sm btn-outline-primary #{@chart_mode == "hour" ? "active" : "inactive"}", params: { chart: "hour" }) %>
17
+ <%= link_to("Today", graphql_dashboard.limiters_limiter_path(params[:name], chart: "day"), class: "btn btn-sm btn-outline-primary #{@chart_mode == "day" ? "active" : "inactive"}", params: { chart: "day" }) %>
18
+ <%= link_to("This Month", graphql_dashboard.limiters_limiter_path(params[:name], chart: "month"), class: "btn btn-sm btn-outline-primary #{@chart_mode == "month" ? "active" : "inactive"}", params: { chart: "month" }) %>
19
+ </div>
20
+ </div>
21
+ <div class="col-auto">
22
+ <%= form_tag graphql_dashboard.limiters_limiter_path(params[:name], chart: @chart_mode), method: "patch" do %>
23
+ <%= submit_tag "#{@current_soft ? "Disable" : "Enable"} Soft Limiting", class: "btn btn-sm btn-outline-warning" %>
24
+ <% end %>
25
+ </div>
26
+ </div>
27
+
28
+ <div class="row">
29
+ <div class="col ms-4">
30
+ <div id="limiter-histogram">
31
+ <table class="charts-css column multiple stacked show-labels hide-data show-primary-axis">
32
+ <thead>
33
+ <th>Date</th>
34
+ <th scope="col">Limited Requests</th>
35
+ <th scope="col">Unlimited Requests</th>
36
+ </thead>
37
+ <tbody>
38
+ <% @histogram.columns.each_with_index do |col, col_idx| %>
39
+ <tr>
40
+ <th scope="row" class="text-end"><%= col.label %></th>
41
+ <% col.values.each_with_index do |value, val_idx| %>
42
+ <td id="data-<%= col_idx %>-<%= val_idx %>">
43
+ <span class="data"><%= value.formatted_value %></span>
44
+ <span class="tooltip"><%= value.label %>: <%= value.formatted_value %><br><%= col.label %></span>
45
+ </td>
46
+ <% end %>
47
+ </tr>
48
+ <% end %>
49
+ </tbody>
50
+ </table>
51
+ </div>
52
+ </div>
53
+ </div>
54
+ <%= content_tag "style", nonce: @csp_nonce do %>
55
+ <% @histogram.columns.each_with_index do |col, col_idx| %>
56
+ <% col_max = @histogram.max_column_value.to_f %>
57
+ <% col.values.each_with_index do |val, val_idx| %>
58
+ #data-<%= col_idx %>-<%= val_idx %> { --size: <%= val.value / col_max %>}
59
+ <% end %>
60
+ <% end %>
61
+ <% end %>
62
+ <% end %>
@@ -0,0 +1,18 @@
1
+ <% content_for(:title, "Operation Store") %>
2
+
3
+ <div class="row">
4
+ <div class="col-md col-lg-8 mx-auto pt-4">
5
+ <div class="card mt-4">
6
+ <div class="card-body">
7
+ <div class="card-title">
8
+ <h2>
9
+ <%= @component_header_html %>
10
+ </h2>
11
+ </div>
12
+ <p class="card-text">
13
+ <%= @component_message_html %>
14
+ </p>
15
+ </div>
16
+ </div>
17
+ </div>
18
+ </div>
@@ -0,0 +1,23 @@
1
+ <%= form_tag((@client.persisted? ? graphql_dashboard.operation_store_client_path(name: @client.name) : graphql_dashboard.operation_store_clients_path), method: (@client.persisted? ? "patch" : "post")) do %>
2
+ <div class="row">
3
+ <label class="col-2 col-form-label">Name</label>
4
+ <div class="col">
5
+ <%= text_field_tag "client[name]", @client.name, class: "form-control", disabled: @client.persisted? %>
6
+ <div class="form-text">a unique identifier for this owner of persisted operations</div>
7
+ </div>
8
+ </div>
9
+ <div class="row">
10
+ <label class="col-2 col-form-label">Secret</label>
11
+ <div class="col">
12
+ <%= textarea_tag "client[secret]", @client.secret, class: "form-control" %>
13
+ <div class="form-text">authentication credential for <code>sync</code> transactions</div>
14
+ </div>
15
+ </div>
16
+ <div class="row">
17
+ <div class="col-auto">
18
+ <%= submit_tag "Save", class: "btn btn-outline-primary" %>
19
+ </div>
20
+ <div class="col-auto">
21
+ <%= link_to "Back", graphql_dashboard.operation_store_clients_path, class: "btn btn-outline-secondary" %>
22
+ </div>
23
+ <% end %>
@@ -0,0 +1,21 @@
1
+ <% content_for(:title, "Edit #{@client.name}") %>
2
+ <div class="row">
3
+ <div class="col">
4
+ <h1>Edit <%= @client.name %></h1>
5
+ </div>
6
+ <div>
7
+ <%= render partial: "graphql/dashboard/operation_store/clients/form" %>
8
+
9
+ <hr class="mt-5"/>
10
+ <div class="row mt-5">
11
+ <div class="col">
12
+ <div class="alert alert-danger">
13
+ <h4>Delete <%= @client.name %></h4>
14
+ <p>If you delete this client, it will no longer be able to use stored operations.</p>
15
+ <p>There is no way to undo this action.</p>
16
+ <%= form_tag(graphql_dashboard.operation_store_client_path(name: @client.name), method: "delete") do %>
17
+ <%= submit_tag "Permanently Delete #{@client.name.inspect}", class: "btn btn-outline-danger" %>
18
+ <% end %>
19
+ </div>
20
+ </div>
21
+ </div>